基于Premake5构建SDL2项目时出现未定义引用错误求助
问题:Premake5构建SDL2静态库项目出现未定义引用错误
环境与场景
基于Arch系Garuda Linux,使用Premake5作为构建系统,手动编译SDL2-2.30.1源码为静态库,构建依赖该库的C++项目时,出现SDL_Init、SDL_CreateWindow等所有SDL函数的链接未定义引用错误。
原配置与代码
premake5.lua 原配置
workspace "Premake Test" location "Generated" language "C++" architecture "x86_64" configurations { "Debug", "Release" } filter "configurations:Debug" symbols "On" filter "configurations:Release" optimize "On" filter { } targetdir("Build/Bin/%{prj.name}/%{cfg.longname}") objdir("Build/Obj/%{prj.name}/%{cfg.longname}") project "SDL" kind "StaticLib" includedirs "libs/SDL2-2.30.1/include" files "libs/SDL2-2.30.1/src/*" function useSDL() includedirs "libs/SDL2-2.30.1/include" links "SDL" end project "TestLib" kind "StaticLib" files "libs/testlib/**" function useExampleLib() includedirs "libs/testlib" links "TestLib" end project "App" kind "WindowedApp" files "src/**" useSDL() useExampleLib()
主程序代码(main.cpp)
#include <SDL.h> #include <iostream> #include "test.h" //Screen dimension constants const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; int main( int argc, char* args[] ) { print("Wenn das klappt, dann WTF!!!"); SDL_Window *window = nullptr; SDL_Surface *screenSurface = nullptr; if (SDL_Init(SDL_INIT_VIDEO) < 0) { std::cout << "SDL could not be initialized! Error: " << SDL_GetError() << std::endl; return 0; } window = SDL_CreateWindow( "SDL_Premake_Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); if (window == nullptr) { std::cout << "SDL window could not be created! Error: " << SDL_GetError() << std::endl; return 0; } screenSurface = SDL_GetWindowSurface(window); SDL_FillRect( screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF)); SDL_UpdateWindowSurface(window); SDL_Event e; bool quit = false; while (!quit) while (SDL_PollEvent(&e)) if (e.type == SDL_QUIT) quit = true; SDL_DestroyWindow( window ); SDL_Quit(); return 0; }
项目目录结构
PREMAKE_TEST/ libs/ SDL2-2.30.1/ include/ (包含所有.h文件) src/ (包含所有.c文件) testlib/ test.cpp test.h src/ main.cpp premake5.lua
错误信息
$ make ==== Building SDL (debug) ==== ==== Building TestLib (debug) ==== ==== Building App (debug) ==== Linking App /usr/bin/ld: ../Build/Obj/App/Debug/main.o: in function `main': /home/.../dev/premake_test/Generated/../src/main.cpp:18:(.text+0x7e): undefined reference to `SDL_Init' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:20:(.text+0xa6): undefined reference to `SDL_GetError' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:24:(.text+0xf7): undefined reference to `SDL_CreateWindow' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:27:(.text+0x123): undefined reference to `SDL_GetError' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:31:(.text+0x156): undefined reference to `SDL_GetWindowSurface' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:32:(.text+0x179): undefined reference to `SDL_MapRGB' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:32:(.text+0x18c): undefined reference to `SDL_FillRect' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:33:(.text+0x198): undefined reference to `SDL_UpdateWindowSurface' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:38:(.text+0x1b8): undefined reference to `SDL_PollEvent' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:42:(.text+0x1d8): undefined reference to `SDL_DestroyWindow' /usr/bin/ld: /home/.../dev/premake_test/Generated/../src/main.cpp:43:(.text+0x1dd): undefined reference to `SDL_Quit' collect2: Fehler: ld gab 1 als Ende-Status zurück make[1]: *** [App.make:81: ../Build/Bin/App/Debug/App] Fehler 1 make: *** [Makefile:43: App] Fehler 2
问题分析
- SDL源文件未完整编译:原配置中
files "libs/SDL2-2.30.1/src/*"仅匹配src目录下的直接文件,未递归编译所有子目录中的源文件,导致静态库缺少大部分SDL实现代码。 - 语言设置错误:SDL是C语言实现的库,原项目未指定
language "C",用C++编译器编译会导致符号不兼容。 - 缺少静态库预定义宏:未定义
SDL_STATIC,导致头文件导出的是动态库符号,而非静态库符号。 - 缺失系统依赖库:SDL静态库需要链接系统底层库(如X11、音频库等),仅链接SDL静态库无法满足依赖。
解决方案
修改premake5.lua,修复上述问题:
修改后的完整premake5.lua
workspace "Premake Test" location "Generated" language "C++" architecture "x86_64" configurations { "Debug", "Release" } filter "configurations:Debug" symbols "On" filter "configurations:Release" optimize "On" filter { } targetdir("Build/Bin/%{prj.name}/%{cfg.longname}") objdir("Build/Obj/%{prj.name}/%{cfg.longname}") project "SDL" kind "StaticLib" language "C" -- SDL是C语言库,指定编译语言 includedirs "libs/SDL2-2.30.1/include" -- 递归匹配所有src子目录的源文件,排除测试和不需要的文件 files { "libs/SDL2-2.30.1/src/**.c", "!libs/SDL2-2.30.1/src/test/**", "!libs/SDL2-2.30.1/src/dynapi/**", "!libs/SDL2-2.30.1/src/main/**" } defines { "SDL_STATIC" } -- 定义静态库宏,确保导出正确符号 function useSDL() includedirs "libs/SDL2-2.30.1/include" defines { "SDL_STATIC" } -- 应用程序也需要定义该宏 links { "SDL", -- 添加SDL静态库依赖的系统库(Linux平台) "X11", "Xext", "Xcursor", "Xinerama", "Xi", "Xrandr", "Xss", "Xxf86vm", "asound", "pulse-simple", "pulse", "m", "pthread", "dl", "rt" } end project "TestLib" kind "StaticLib" files "libs/testlib/**" function useExampleLib() includedirs "libs/testlib" links "TestLib" end project "App" kind "WindowedApp" files "src/**" useSDL() useExampleLib()
验证步骤
- 清理之前的生成文件:删除
Generated和Build目录 - 重新生成Makefile:
premake5 gmake - 编译项目:进入
Generated目录执行make - 运行程序:
../Build/Bin/App/Debug/App
内容的提问来源于stack exchange,提问作者user23640673
相关产品推荐
相关产品推荐

