如何使用/链接源代码作为库 (C/C++)
我试图了解如何使用构建和使用源代码,然后在我的项目中链接到它。具体来说,我正在尝试使用 SDL2 库来做到这一点。我在 Mac 上,想在命令行中执行此操作(我没有使用 xcode)。
我已经下载了源代码(您可以在这里找到:https://www .libsdl.org/download-2.0.php),并将该文件夹放入与我的 main.c 文件相同的目录中。
我进入该目录并运行以下命令
./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/ 中查找库。
另请注意,在我的 main.c 文件中,我包含了 sdl 标头,如下所示:
#include "SDL2/include/SDL.h"
因为这是 SDL.h 文件的文件夹路径。我也不确定这是否正确,但这就是我目前正在做的事情。
任何帮助都会非常感激。我是 C 新手,只是想了解链接/构建/包含库的工作原理,而不用像 homebrew 或 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
I'm trying to understand how to use build and use source code and then link to it in my project. Specifically I'm trying to do this with the SDL2 library. I am on a mac and want to do this in the command line (I am not using xcode).
I've downloaded the source code (which you can find here: https://www.libsdl.org/download-2.0.php), and put the folder into the same directory as my main.c file.
I cd'd into this directory and run the following commands
./configure
and thenmake
.Next, I can run the command
make install
which puts the library into my usr/bin directory. Then, I can link to this library in the command line like thisclang main.c -o main -lSDL2
but I'm trying to understand how to not do this step and link to the code in my application directory.
I've been trying to run commands like this:
clang main.c -o main -L./SDL2/build/.libs -I./SDL2/include -lSDL2
clang main.c -o main -L./SDL2/build/.libs -lSDL2
My thought process was that the -L flag tells where the built code should be to link to, because in the ./SDL2/build/.libs folder I see the files called libSDL2.a, libSDL2-2.0.0.dylib, and libSDL2.dylib.
These commands actually do succesfully build and I get a main
output file, but when I try to run that file I get the following error:
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
I'm not sure what I'm doing wrong, or why it's looking for the library in /usr/local/lib/ when I have specified a different path with the -L flag.
Also to note, in my main.c file, I'm including the sdl header like this:
#include "SDL2/include/SDL.h"
since that is the folder path to the SDL.h file. I'm also not certain that this is correct, but is what I'm doing at the moment.
Any help here would be very apprecatied. I'm new to C and just trying to understand how linking/building/including libraries works without installing them with something like homebrew or make install.
Here is the compiler I'm using:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了使用动态库,您必须在构建时和运行时指定搜索路径。
-L
标志告诉链接器在构建时在哪里找到库,但在可执行文件中,符号表会将动态库中的符号列为未定义,这意味着没有与这些符号关联的内存地址符号。在运行时,动态链接器必须找到相同的库才能加载可执行文件。向动态链接器提供此路径的最简单方法是在运行时使用LD_LIBRARY_PATH
环境变量(在 Mac 上可能是DYLD_LIBRARY_PATH
):您还可以嵌入库路径到可执行文件中,尽管这假设每次运行可执行文件时您的库都将位于可预测的位置。为此,您可以使用
-rpath
链接器标志,它将在可执行文件的.dynamic
部分中创建一个DT_RUNPATH
条目(不要如果您不知道所有这些意味着什么,请不要担心)。对于相对路径,您可以使用特殊值$ORIGIN
来引用包含可执行文件的目录。在您的情况下,该命令看起来像这样(请注意-Wl
的使用,它告诉clang
该标志应该传递给底层链接器):然后您应该能够在没有特殊环境变量的情况下运行可执行文件:
In order to use a dynamic library, you have to specify a search path both at build-time and at run-time. The
-L
flag tells your linker at build-time where to find the library, but within the executable, the symbol table will list symbols from dynamic libraries as undefined, meaning there is no memory address associated with those symbols. At run-time, the dynamic linker has to find those same libraries in order to load the executable. The simplest way to provide this path to the dynamic linker is using theLD_LIBRARY_PATH
environment variable at runtime (on Mac it might beDYLD_LIBRARY_PATH
instead):You can also embed the library path into the executable, though this assumes that your libraries will be at a predictable location every time you run the executable. To do this, you use the
-rpath
linker flag, which will create aDT_RUNPATH
entry in the.dynamic
section of the executable (don't worry if you don't know what all of that means). For relative paths, you can use the special value,$ORIGIN
, to refer to the directory containing the executable. In your case, the command would look something like this (note the use of-Wl
, which tellsclang
that this flag should be passed to the underlying linker):Then you should be able to run the executable with no special environment variables: