Linux下共享库静态链接GLFW出现未定义引用报错排查
问题背景
我正在构建一个包含两大核心组件的C++项目:
- Game:游戏可执行程序
- Engine:游戏引擎,以共享库形式存在,承载绝大多数图形调用逻辑,需要集成GLFW库;Game程序通过链接Engine实现功能调用。
项目文件结构示意图:
项目使用premake5作为构建工具,premake文件夹仅用于存储构建相关文件,无需额外关注。
现有配置
根目录premake5.lua配置
workspace "Game" architecture "x64" configurations { "Debug", "Release", "Dist" } outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" -- 相对于根目录(解决方案)的包含目录 include "Engine/GLFW" project "Engine" location "Engine" kind "SharedLib" language "C++" targetdir ("bin/" .. outputdir .. "/") objdir ("bin-int/" .. outputdir .. "/") pchheader "Egpch.h" pchsource "Egpch.cpp" files { "%{prj.name}/src/**.h", "%{prj.name}/src/**.cpp" } includedirs { "%{prj.name}/", "%{prj.name}/src", "%{prj.name}/spdlog/include", "Engine/GLFW/include" } links { "GLFW" } filter "system:linux" cppdialect "C++17" staticruntime "On" links { "GL" } filter "system:windows" cppdialect "C++17" staticruntime "On" systemversion "latest" links { "OpenGL32" } defines { "EG_PLATFORM_WINDOWS", "EG_BUILD_DLL"; } filter "configurations:Debug" defines "EG_DEBUG" symbols "On" filter "configurations:Release" defines "EG_RELEASE" optimize "On" filter "configurations:Dist" defines "EG_DIST" optimize "On" project "Game" location "Game" kind "ConsoleApp" language "C++" targetdir ("bin/" .. outputdir .. "/") objdir ("bin-int/" .. outputdir .. "/") files { "%{prj.name}/**.h", "%{prj.name}/**.cpp" } includedirs { "Engine/spdlog/include", "Engine/", "Engine/src", } links { "Engine" } filter "system:linux" cppdialect "C++17" staticruntime "On" filter "system:windows" cppdialect "C++17" staticruntime "On" systemversion "latest" defines { "EG_PLATFORM_WINDOWS", } filter "configurations:Debug" defines "EG_DEBUG" symbols "On" filter "configurations:Release" defines "EG_RELEASE" optimize "On" filter "configurations:Dist" defines "EG_DIST" optimize "On"
GLFW目录下premake配置
project "GLFW" kind "StaticLib" language "C" targetdir ("bin/" .. outputdir .. "/%{prj.name}") objdir ("bin-int/" .. outputdir .. "/%{prj.name}") files { "include/GLFW/glfw3.h", "include/GLFW/glfw3native.h", "src/glfw_config.h", "src/context.c", "src/init.c", "src/input.c", "src/monitor.c", "src/vulkan.c", "src/window.c" } filter "system:windows" systemversion "latest" staticruntime "On" files { "src/win32_init.c", "src/win32_joystick.c", "src/win32_monitor.c", "src/win32_time.c", "src/win32_thread.c", "src/win32_window.c", "src/wgl_context.c", "src/egl_context.c", "src/osmesa_context.c" } defines { "_GLFW_WIN32", "_CRT_SECURE_NO_WARNINGS" } filter "system:linux" pic "On" systemversion "latest" staticruntime "On" files { "src/x11_init.c", "src/x11_monitor.c", "src/x11_window.c", "src/xkb_unicode.c", "src/posix_time.c", "src/posix_thread.c", "src/glx_context.c", "src/egl_context.c", "src/osmesa_context.c", "src/linux_joystick.c" } defines { "_GLFW_X11" } filter "configurations:Debug" runtime "Debug" symbols "On" filter "configurations:Release" runtime "Release" optimize "on"
报错信息
Game项目链接阶段出现未定义引用报错,构建日志如下:
==== Building GLFW (debug) ==== ==== Building Engine (debug) ==== Linking Engine ==== Building Game (debug) ==== Linking Game /usr/bin/ld: ../bin/Debug-linux-x86_64/libEngine.so: undefined reference to `_glfwPlatformLoadModule' /usr/bin/ld: ../bin/Debug-linux-x86_64/libEngine.so: undefined reference to `pthread_key_create' /usr/bin/ld: ../bin/Debug-linux-x86_64/libEngine.so: undefined reference to `pthread_getspecific' /usr/bin/ld: ../bin/Debug-linux-x86_64/libEngine.so: undefined reference to `_glfwSelectPlatform' /usr/bin/ld: ../bin/Debug-linux-x86_64/libEngine.so: undefined reference to `pthread_key_delete' /usr/bin/ld: ../bin/Debug-linux-x86_64/libEngine.so: undefined reference to `_glfwPlatformFreeModule' /usr/bin/ld: ../bin/Debug-linux-x86_64/libEngine.so: undefined reference to `_glfwPlatformGetModuleSymbol' /usr/bin/ld: ../bin/Debug-linux-x86_64/libEngine.so: undefined reference to `pthread_setspecific' collect2: error: ld returned 1 exit status make[1]: *** [Makefile:91: ../bin/Debug-linux-x86_64/Game] Error 1 make: *** [Makefile:51: Game] Error 2
已排查进展
- 已定位所有
_glfw前缀接口未定义的初步原因:GLFW目录下的premake配置存在疏漏,遗漏了部分必要的源文件。 - 剩余未解决问题:pthread库相关的未定义引用仍未定位根因。
修复方案
两类报错对应修复方式如下:
- 补全GLFW静态库的编译源文件
报错中_glfwSelectPlatform对应src/platform.c,三个_glfwPlatform*Module接口对应src/posix_module.c,这两个文件没有加入GLFW的Linux平台编译列表,直接把这两个文件追加到GLFW配置Linux分支的files块即可解决这部分符号缺失。 - 补全Linux平台的链接依赖
Linux下静态库不会自动传递依赖关系,GLFW编译依赖的系统库不会被静态库本身记录,需要显式加入链接列表:- 在Engine项目Linux配置的
links块中追加pthread,解决线程相关函数未定义问题 - 同步追加
dl库,对应posix_module.c中用到的动态库加载接口 - 建议同步补全GLFW依赖的X11相关库,避免后续编译出现新的未定义报错
修改后的Engine Linux配置块示例:
filter "system:linux" cppdialect "C++17" staticruntime "On" links { "GL", "pthread", "dl", "X11", "Xrandr", "Xinerama", "Xcursor", "Xi" } - 在Engine项目Linux配置的
如果补全后仍有GLFW相关符号丢失,可以在链接Engine时添加-Wl,--whole-archive链接选项,强制把静态GLFW的所有符号打包进Engine共享库,避免静态库链接顺序导致的符号裁剪问题。
内容的提问来源于stack exchange,提问作者miyoku
相关产品推荐
相关产品推荐

