首页 > 解决方案 > 未定义的引用,但链接的共享库包含它

问题描述

我正在使用系统 gcc 版本:

gcc --version
gcc (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0

我构建了一个目标文件,其中包含这样的定义vkCreateXlibSurfaceKHR

gcc -o thirdparty/volk/volk.os -c -std=gnu11 -w -g3 -pipe -Wall -Wshadow-local -Wno-misleading-indentation -Werror=return-type -w -fPIC -DDEBUG_ENABLED -DDEBUG_MEMORY_ALLOC -DDISABLE_FORCED_INLINE -DTOUCH_ENABLED -DALSA_ENABLED -DALSAMIDI_ENABLED -DPULSEAUDIO_ENABLED -D_REENTRANT -DDBUS_ENABLED -DJOYDEV_ENABLED -DUDEV_ENABLED -DX11_ENABLED -DUNIX_ENABLED -D_FILE_OFFSET_BITS=64 -DVULKAN_ENABLED -DTOOLS_ENABLED -DMINIZIP_ENABLED -DZSTD_STATIC_LINKING_ONLY -DUSE_VOLK -DVK_USE_PLATFORM_XLIB_KHR -Ithirdparty/volk -Ithirdparty/vulkan -Ithirdparty/vulkan/include -Ithirdparty/zstd -Ithirdparty/zlib -Iplatform/linuxbsd -I. -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include thirdparty/volk/volk.c
nm thirdparty/volk/volk.os | grep vkCreateXlibSurfaceKHR
0000000000000008 C vkCreateXlibSurfaceKHR

然后我构建了一个共享库,其中包含 C 和 C++ 代码以及对象(不确定为什么符号现在在 BSS 中?):

g++ -o drivers/libdrivers.linuxbsd.tools.64.so -rdynamic -pipe -static-libgcc -static-libstdc++ -shared drivers/unix/dir_access_unix.os drivers/unix/file_access_unix.os drivers/unix/ip_unix.os drivers/unix/net_socket_posix.os drivers/unix/os_unix.os drivers/unix/syslog_logger.os drivers/unix/thread_posix.os drivers/windows/dir_access_windows.os drivers/windows/file_access_windows.os drivers/alsa/asound-so_wrap.os drivers/alsa/audio_driver_alsa.os drivers/coreaudio/audio_driver_coreaudio.os drivers/pulseaudio/pulse-so_wrap.os drivers/pulseaudio/audio_driver_pulseaudio.os drivers/alsamidi/midi_driver_alsamidi.os drivers/coremidi/midi_driver_coremidi.os drivers/winmidi/midi_driver_winmidi.os thirdparty/volk/volk.os thirdparty/vulkan/vk_mem_alloc.os drivers/vulkan/rendering_device_vulkan.os drivers/vulkan/vulkan_context.os thirdparty/libpng/png.os thirdparty/libpng/pngerror.os thirdparty/libpng/pngget.os thirdparty/libpng/pngmem.os thirdparty/libpng/pngpread.os thirdparty/libpng/pngread.os thirdparty/libpng/pngrio.os thirdparty/libpng/pngrtran.os thirdparty/libpng/pngrutil.os thirdparty/libpng/pngset.os thirdparty/libpng/pngtrans.os thirdparty/libpng/pngwio.os thirdparty/libpng/pngwrite.os thirdparty/libpng/pngwtran.os thirdparty/libpng/pngwutil.os drivers/png/image_loader_png.os drivers/png/png_driver_common.os drivers/png/resource_saver_png.os thirdparty/spirv-reflect/spirv_reflect.os drivers/register_driver_types.os editor/libeditor.linuxbsd.tools.64.so scene/libscene.linuxbsd.tools.64.so servers/libservers.linuxbsd.tools.64.so core/libcore.linuxbsd.tools.64.so -lXcursor -lXinerama -lXext -lXrandr -lXrender -lX11 -lXi -ldbus-1 -lGL -lpthread -ldl
nm drivers/libdrivers.linuxbsd.tools.64.so | grep vkCreateXlibSurfaceKHR                                  
000000000049f388 b vkCreateXlibSurfaceKHR

我构建了另一个包含对以下内容的引用的对象vkCreateXlibSurfaceKHR

g++ -o platform/linuxbsd/vulkan_context_x11.linuxbsd.tools.64.o -c -std=gnu++17 -g3 -pipe -Wall -Wshadow-local -Wno-misleading-indentation -Werror=return-type -fPIC -DDEBUG_ENABLED -DDEBUG_MEMORY_ALLOC -DDISABLE_FORCED_INLINE -DTOUCH_ENABLED -DALSA_ENABLED -DALSAMIDI_ENABLED -DPULSEAUDIO_ENABLED -D_REENTRANT -DDBUS_ENABLED -DJOYDEV_ENABLED -DUDEV_ENABLED -DX11_ENABLED -DUNIX_ENABLED -D_FILE_OFFSET_BITS=64 -DVULKAN_ENABLED -DTOOLS_ENABLED -DMINIZIP_ENABLED -DZSTD_STATIC_LINKING_ONLY -DUSE_VOLK -DVK_USE_PLATFORM_XLIB_KHR -Ithirdparty/freetype/include -Ithirdparty/libpng -Ithirdparty/volk -Ithirdparty/vulkan -Ithirdparty/vulkan/include -Ithirdparty/zstd -Ithirdparty/zlib -Iplatform/linuxbsd -I. -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include platform/linuxbsd/vulkan_context_x11.cpp

最后,我将它们全部链接到一个程序二进制文件中,但我得到了一个未定义的引用:

g++ -o bin/godot.linuxbsd.tools.64 -rdynamic -pipe -static-libgcc -static-libstdc++ \
    platform/linuxbsd/godot_linuxbsd.linuxbsd.tools.64.o \
    platform/linuxbsd/crash_handler_linuxbsd.linuxbsd.tools.64.o \
    platform/linuxbsd/os_linuxbsd.linuxbsd.tools.64.o \
    platform/linuxbsd/joypad_linux.linuxbsd.tools.64.o \
    platform/linuxbsd/freedesktop_screensaver.linuxbsd.tools.64.o \
    platform/linuxbsd/context_gl_x11.linuxbsd.tools.64.o \
    platform/linuxbsd/detect_prime_x11.linuxbsd.tools.64.o \
    platform/linuxbsd/display_server_x11.linuxbsd.tools.64.o \
    platform/linuxbsd/key_mapping_x11.linuxbsd.tools.64.o \
    platform/linuxbsd/vulkan_context_x11.linuxbsd.tools.64.o \
    platform/linuxbsd/libudev-so_wrap.linuxbsd.tools.64.o \
    main/libmain.linuxbsd.tools.64.a \
    modules/libmodules.linuxbsd.tools.64.so \
    modules/libmodule_xatlas_unwrap.linuxbsd.tools.64.so \
    modules/libmodule_webxr.linuxbsd.tools.64.so \
    modules/libmodule_websocket.linuxbsd.tools.64.so \
    modules/libmodule_webrtc.linuxbsd.tools.64.so \
    modules/libmodule_webp.linuxbsd.tools.64.so \
    modules/libmodule_webm.linuxbsd.tools.64.a \
    modules/libmodule_vorbis.linuxbsd.tools.64.so \
    modules/libmodule_visual_script.linuxbsd.tools.64.so \
    modules/libmodule_vhacd.linuxbsd.tools.64.so \
    modules/libmodule_upnp.linuxbsd.tools.64.so \
    modules/libmodule_tinyexr.linuxbsd.tools.64.so \
    modules/libmodule_theora.linuxbsd.tools.64.so \
    modules/libmodule_tga.linuxbsd.tools.64.so \
    modules/libmodule_text_server_adv.linuxbsd.tools.64.a \
    modules/libmodule_svg.linuxbsd.tools.64.so \
    modules/libmodule_stb_vorbis.linuxbsd.tools.64.so \
    modules/libmodule_squish.linuxbsd.tools.64.so \
    modules/libmodule_regex.linuxbsd.tools.64.a \
    modules/libmodule_raycast.linuxbsd.tools.64.so \
    modules/libmodule_pvr.linuxbsd.tools.64.so \
    modules/libmodule_opus.linuxbsd.tools.64.so \
    modules/libmodule_opensimplex.linuxbsd.tools.64.so \
    modules/libmodule_ogg.linuxbsd.tools.64.so \
    modules/libmodule_navigation.linuxbsd.tools.64.so \
    modules/libmodule_msdfgen.linuxbsd.tools.64.so \
    modules/libmodule_mobile_vr.linuxbsd.tools.64.so \
    modules/libmodule_minimp3.linuxbsd.tools.64.so \
    modules/libmodule_meshoptimizer.linuxbsd.tools.64.so \
    modules/libmodule_mbedtls.linuxbsd.tools.64.so \
    modules/libmodule_lightmapper_rd.linuxbsd.tools.64.so \
    modules/libmodule_jsonrpc.linuxbsd.tools.64.so \
    modules/libmodule_jpg.linuxbsd.tools.64.so \
    modules/libmodule_hdr.linuxbsd.tools.64.so \
    modules/libmodule_gridmap.linuxbsd.tools.64.so \
    modules/libmodule_gltf.linuxbsd.tools.64.so \
    modules/libmodule_glslang.linuxbsd.tools.64.so \
    modules/libmodule_gdscript.linuxbsd.tools.64.so \
    modules/libmodule_gdnative.linuxbsd.tools.64.so \
    modules/libmodule_freetype.linuxbsd.tools.64.so \
    modules/libmodule_fbx.linuxbsd.tools.64.so \
    modules/libmodule_etcpak.linuxbsd.tools.64.so \
    modules/libmodule_enet.linuxbsd.tools.64.so \
    modules/libmodule_denoise.linuxbsd.tools.64.so \
    modules/libmodule_dds.linuxbsd.tools.64.so \
    modules/libmodule_cvtt.linuxbsd.tools.64.so \
    modules/libmodule_csg.linuxbsd.tools.64.so \
    modules/libmodule_bmp.linuxbsd.tools.64.so \
    modules/libmodule_basis_universal.linuxbsd.tools.64.so \
    platform/libplatform.linuxbsd.tools.64.so \
    drivers/libdrivers.linuxbsd.tools.64.so \
    editor/libeditor.linuxbsd.tools.64.so \
    scene/libscene.linuxbsd.tools.64.so \
    servers/libservers.linuxbsd.tools.64.so \
    core/libcore.linuxbsd.tools.64.so \
    modules/freetype/libfreetype_builtin.linuxbsd.tools.64.so \
    modules/msdfgen/libmsdfgen_builtin.linuxbsd.tools.64.so \
    modules/text_server_adv/libharfbuzz_builtin.linuxbsd.tools.64.a \
    modules/text_server_adv/libgraphite_builtin.linuxbsd.tools.64.a \
    modules/text_server_adv/libicu_builtin.linuxbsd.tools.64.a \
    -lXcursor -lXinerama -lXext -lXrandr -lXrender -lX11 -lXi \
    -ldbus-1 -lGL -lpthread -ldl
platform/linuxbsd/vulkan_context_x11.linuxbsd.tools.64.o: In function `VulkanContextX11::window_create(int, DisplayServer::VSyncMode, unsigned long, _XDisplay*, int, int)':
/home/ubuntu/godot/platform/linuxbsd/vulkan_context_x11.cpp:51: undefined reference to `vkCreateXlibSurfaceKHR'
collect2: error: ld returned 1 exit status

有谁知道为什么当我链接程序时链接器没有看到该定义?

标签: c++linkershared-librariesgodot

解决方案


不幸的是,nm 省略了一些信息,并且在使用 readelf 时:

readelf --symbols thirdparty/volk/volk.os | grep vkCreateXlibSurfaceKHR
313: 0000000000000008     8 OBJECT  GLOBAL HIDDEN  COM vkCreateXlibSurfaceKHR

我发现这个特定的第三方强制将符号隐藏,因此我能够通过第三方库用来将可见性切换为 DEFAULT 的 DEFINE 来修复它。


推荐阅读