为什么我会收到对正在链接的库中定义的符号的未定义引用?

Why do I get an undefined reference to a symbol that is defined in the library I am linking?

提问人:Alaric de Ruiter 提问时间:9/9/2023 最后编辑:Alaric de Ruiter 更新时间:9/9/2023 访问量:67

问:

当我在使用 Raylib 库的特定函数时得到一个未定义的引用时,我正在尝试编译一个不相关的项目。

我能够使用以下测试重现此行为。

#include <raylib.h>

int main(){
        InitWindow(500,500, "test");
        
        int w = GetRenderWidth(); // undefined reference symbol
                                                                                
        while(!WindowShouldClose()){                                            
                BeginDrawing();                                                 
                ClearBackground(BLACK);                                  
                EndDrawing();                                                   
        }                                                                       
        CloseWindow();                                                          
        return 0;                                                               
} 

此代码是使用以下命令编译的。

gcc test.c -o app -L/usr/local/lib -lraylib

结果输出为

/usr/bin/ld: /tmp/ccxqgamX.o: in function `main':
code.c:(.text+0x27): undefined reference to `GetRenderWidth'
collect2: error: ld returned 1 exit status

然而,一旦我注释了违规的行() 该应用程序编译良好,并且能够成功运行。// int w = GetRenderWidth();

我使用libraylib.a/usr/local/lib

nm /usr/local/lib/libraylib.a | grep GetRenderWidth

这导致了以下输出:

0000000000027b1e T GetRenderWidth

由此我推测,该符号实际上存在于我链接的库中,因此是我的问题。 为什么我的编译器(和 )报告对同一库中的其他符号的未定义引用,而不是?gccclangGetRenderWidth()

C linker undefined-reference nm raylib

评论

1赞 Some programmer dude 9/9/2023
您是否安装了多个 Raylib?也许在 ?在构建时,如果删除该选项,它是否仍然可以找到 Raylib 库?/usr/local/lib-L/usr/local/lib
0赞 Weather Vane 9/9/2023
该怎么办?它们是代码编辑器的产物吗?width: height: title:
0赞 Alaric de Ruiter 9/9/2023
@Someprogrammerdude,在删除 GetRenderWidth 函数调用时,它仍然显示相同的行为,包括编译和运行。
0赞 Alaric de Ruiter 9/9/2023
@WeatherVane是的,对不起,这是因为我在 neovim 中使用了 neoclide,所以当我复制文本时,它复制了 neovim 显示的所有内容,我现在已经删除了它。
2赞 John Bollinger 9/9/2023
"为什么我的编译器(gcc 和 clang)在 GetRenderWidth() 上报告未定义的引用,而不是在同一库中的其他符号上报告?-- 因为链接的 libraylib 版本没有提供函数的外部定义。由于您正在检查的库确实定义了一个库,因此您必须链接不同的库。可能在某处有一个共享库版本()优先于静态版本链接。GetRenderWidth()libraylib.so

答:

2赞 Alaric de Ruiter 9/9/2023 #1

事实证明,它还包含我的编译器链接的同一库的共享版本。这个版本不包含导致我困惑的符号。我能够通过用 替换 来强制我的编译器使用静态库。/usr/local/libGetRenderWidth-lraylib-l:libraylib.a