我正在努力了解如何使用构建和使用源代码,然后在我的项目中链接到它。具体来说,我正在尝试使用SDL2库来实现这一点。我在mac上,想在命令行中执行此操作(我没有使用xcode(。
-
我已经下载了源代码(您可以在这里找到:https://www.libsdl.org/download-2.0.php),并将该文件夹放入与我的主.c文件相同的目录中。
-
我cd到这个目录中,然后运行以下命令
./configure
和make
。 -
接下来,我可以运行命令
make install
,该命令将库放入我的usr/bin目录中。然后,我可以像clang main.c -o main -lSDL2
一样在命令行中链接到此库,但我正在努力了解如何不执行此步骤并链接到我的应用程序目录中的代码。
我一直在尝试运行这样的命令:
clang main.c -o main -L./SDL2/build/.libs -I./SDL2/include -lSDL2
clang main.c -o main -L./SDL2/build/.libs -lSDL2
我的想法是,-L标志告诉构建的代码应该链接到哪里,因为在中/SDL2/build/.libs文件夹我看到了名为libSDL2.a、libSDL2-2.0.0.dylib和libSDL2.dylib的文件。这些命令实际上成功地构建了一个main
输出文件,但当我尝试运行该文件时,我会收到以下错误:
dyld: Library not loaded: /usr/local/lib/libSDL2-2.0.0.dylib
Referenced from: /Users/jerfp/Documents/personal/c-stuff/sdl-test-source/./main
Reason: image not found
[1] 37284 abort ./main
我不确定我做错了什么,也不确定当我用-L标志指定了一个不同的路径时,它为什么在/usr/local/lib/中查找库。
还要注意的是,在我的主.c文件中,我包含了如下的sdl头:
#include "SDL2/include/SDL.h"
因为这是SDL.h文件的文件夹路径。我也不确定这是否正确,但这正是我目前正在做的。
如果有人帮忙,我们将不胜感激。我是C的新手,只是想了解链接/构建/包括库是如何工作的,而不需要用自制软件或make install之类的东西来安装它们。
这是我正在使用的编译器:
Apple clang version 12.0.5 (clang-1205.0.22.9)
Target: x86_64-apple-darwin20.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
为了使用动态库,您必须在构建时和运行时指定搜索路径。-L
标志在构建时告诉链接器在哪里可以找到库,但在可执行文件中,符号表会将动态库中的符号列为未定义符号,这意味着没有与这些符号相关联的内存地址。在运行时,动态链接器必须找到相同的库才能加载可执行文件。向动态链接器提供此路径的最简单方法是在运行时使用LD_LIBRARY_PATH
环境变量(在Mac上可能是DYLD_LIBRARY_PATH
(:
LD_LIBRARY_PATH=./SDL2/build/.libs ./main
您也可以将库路径嵌入到可执行文件中,尽管这假设每次运行可执行文件时,库都位于可预测的位置。为此,您可以使用-rpath
链接器标志,它将在可执行文件的.dynamic
部分创建一个DT_RUNPATH
条目(如果您不知道所有这些意味着什么,请不要担心(。对于相对路径,可以使用特殊值$ORIGIN
来引用包含可执行文件的目录。在您的情况下,命令看起来是这样的(注意-Wl
的使用,它告诉clang
应该将此标志传递给底层链接器(:
clang -Wl,-rpath,'$ORIGIN/SDL2/build/.libs' main.o -o main -L./SDL2/build/.libs -lSDL2
然后,您应该能够在没有特殊环境变量的情况下运行可执行文件:
./main