You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

问题分析

  1. SDL源文件未完整编译:原配置中files "libs/SDL2-2.30.1/src/*"仅匹配src目录下的直接文件,未递归编译所有子目录中的源文件,导致静态库缺少大部分SDL实现代码。
  2. 语言设置错误:SDL是C语言实现的库,原项目未指定language "C",用C++编译器编译会导致符号不兼容。
  3. 缺少静态库预定义宏:未定义SDL_STATIC,导致头文件导出的是动态库符号,而非静态库符号。
  4. 缺失系统依赖库: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()

验证步骤

  1. 清理之前的生成文件:删除Generated和Build目录
  2. 重新生成Makefile:premake5 gmake
  3. 编译项目:进入Generated目录执行make
  4. 运行程序:../Build/Bin/App/Debug/App

内容的提问来源于stack exchange,提问作者user23640673

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 22:09:51