Error: Undefined Reference to _

Hey all! I have a basic question for an open source project I’m working on that uses vulkan. You can find the code HERE. In this project, I am using Swift and the Clang compiler and ran into a linking issue for extension specific functions in the compiler. The errors are shown below:

/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/AccelerationStructure.swift:7: error: undefined reference to 'vkCreateAccelerationStructureNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/AccelerationStructure.swift:10: error: undefined reference to 'vkGetAccelerationStructureHandleNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/AccelerationStructure.swift:13: error: undefined reference to 'vkDestroyAccelerationStructureNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:19: error: undefined reference to 'vkGetFenceFdKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:29: error: undefined reference to 'vkImportFenceFdKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:32: error: undefined reference to 'vkWaitSemaphoresKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:35: error: undefined reference to 'vkSignalSemaphoreKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:38: error: undefined reference to 'vkImportSemaphoreFdKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:44: error: undefined reference to 'vkGetCalibratedTimestampsEXT'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:58: error: undefined reference to 'vkGetPipelineExecutablePropertiesKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:63: error: undefined reference to 'vkGetPipelineExecutableStatisticsKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:67: error: undefined reference to 'vkGetPipelineExecutableInternalRepresentationsKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:74: error: undefined reference to 'vkGetMemoryFdKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:79: error: undefined reference to 'vkGetMemoryFdPropertiesKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:84: error: undefined reference to 'vkGetMemoryHostPointerPropertiesEXT'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:109: error: undefined reference to 'vkGetImageViewHandleNVX'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:112: error: undefined reference to 'vkGetAccelerationStructureMemoryRequirementsNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Device.swift:115: error: undefined reference to 'vkBindAccelerationStructureMemoryNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Fence.swift:13: error: undefined reference to 'vkRegisterDeviceEventEXT'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Fence.swift:16: error: undefined reference to 'vkRegisterDisplayEventEXT'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Image.swift:13: error: undefined reference to 'vkGetImageDrmFormatModifierPropertiesEXT'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/PhysicalDevice.swift:23: error: undefined reference to 'vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/PhysicalDevice.swift:26: error: undefined reference to 'vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/PhysicalDevice.swift:30: error: undefined reference to 'vkGetPhysicalDeviceCooperativeMatrixPropertiesNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/PhysicalDevice.swift:32: error: undefined reference to 'vkGetPhysicalDeviceCooperativeMatrixPropertiesNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Pipeline.swift:10: error: undefined reference to 'vkGetShaderInfoAMD'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Pipeline.swift:13: error: undefined reference to 'vkGetRayTracingShaderGroupHandlesNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Pipeline.swift:16: error: undefined reference to 'vkCompileDeferredNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/PipelineCache.swift:15: error: undefined reference to 'vkCreateRayTracingPipelinesNV'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/Semaphore.swift:11: error: undefined reference to 'vkGetSemaphoreCounterValueKHR'
witch/Desktop/NYON/Sources/NYON/Vulkan/ValidationCache.swift:7: error: undefined reference to 'vkCreateValidationCacheEXT'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/ValidationCache.swift:10: error: undefined reference to 'vkMergeValidationCachesEXT'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/ValidationCache.swift:13: error: undefined reference to 'vkGetValidationCacheDataEXT'
/home/underswitch/Desktop/NYON/Sources/NYON/Vulkan/ValidationCache.swift:16: error: undefined reference to 'vkDestroyValidationCacheEXT'
clang-7: error: linker command failed with exit code 1 (use -v to see invocation)
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)

Right now, I am only linking with the “vulkan” library from the compiler for the vulkan.h file. I am using other functions that are working and linking fine, it seems to be an issue with extension specific functions and I have literally no idea why. Any ideas? And one more note if you look at the code some specific extension functions / structures are working totally fine, it is just a very odd issue. Also to note I am using the newest vulkan 1.1.130 SDK on ubuntu. I have a Intel i7 8700 CPU and a GTX 1050Ti 4GB as my GPU.

Extension functions have to be loaded dynamically via vkGet*ProcAddr, or some utility library. Only core and platform-specific WSI extension can be linked statically.

1 Like

Thank you so much! This is the problem for sure but how would I go about getting the address for let’s just say the “AccelerationStructure” extension. Like what would the code look like or the steps look like. Again super sorry I am a massive vulkan NEWBE :joy:. Also you can talk in C/C++ terms cause i’ve gotten ok at converting C++ code to swift code. YOU ARE AMAZING! I do see the VkGetInstanceProcAddress & VkGetDeviceProcAddress just have no idea how I would go about getting a function pointer from them

You can use volk. It will load extensions known up to date.

Manually it is done e.g.:

PFN_vkGetPhysicalDeviceFeatures2KHR pvkGetPhysicalDeviceFeatures2KHR  = vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR");
// use pvkGetPhysicalDeviceFeatures2KHR

Alternatively\additionally the vulkan.h declaration can be defined:

//somewhere in *.cpp
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR(
    VkPhysicalDevice physicalDevice,
    VkPhysicalDeviceFeatures2* pFeatures)
{
    return pvkGetPhysicalDeviceFeatures2KHR( physicalDevice, pFeatures );
}

This of course works only if you have single VkInstance and VkDevice. The fptr returned by vkGet*ProcAddr is valid only for that particular VkInstance\VkDevice it was called with.

A lazy solution is to make your own dispatch using std::unordered_map, as I do here: https://github.com/krOoze/Hello_Triangle/blob/3cde6942e84cd5c19a38caced9e45f25df672d21/src/ExtensionLoader.h#L174-L178

Another solution is using the Vulkan-Hpp.

1 Like

This was it! Thank you so much for your help!!! YOU ARE AMAZING