链接时库依赖项如何工作?
我有一个库 libmya.so 和一个库 libmyb.so。 libmyb.so 中的函数依赖于 libmya.so 中的函数。我还有一个可执行文件 myexe,它依赖于 libmyb.so。当我创建这些库时,我应该在哪些规则中添加 -l 选项?
应该是 1):
libmya.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) -o $@ $^
libmyb.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmya
myexe: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmyb
或 2)
libmya.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) -o $@ $^
libmyb.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^
myexe: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmya -lmyb
或其他组合?
I have a library libmya.so and a library libmyb.so. The functions in libmyb.so depend on functions in libmya.so. Also I have an executable myexe which depends on libmyb.so. When I make these libraries, in which rules should I put the -l options?
Should it be 1):
libmya.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) -o $@ $^
libmyb.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmya
myexe: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmyb
or 2)
libmya.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) -o $@ $^
libmyb.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^
myexe: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmya -lmyb
or some other combo?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会选择选项 1(尽管选项 2 有效,但我不会推荐它,因为从那时起,任何链接 exe 的人都需要记住所需的所有传递库)。
但是,此建议仅适用于制作
so
文件,如上面所做的那样。so
文件(共享对象)是“智能”库,很像可执行文件,只是它们没有 main.so 文件。so
文件可以链接到其他库(例如可执行文件),当可执行文件链接到so
文件时,它会自动递归地包含so< 的依赖项/代码> 文件。
因此,您创建的
so
文件应与其所有依赖项链接。“哑”库,例如
a
文件(静态库)则是另一回事;那么您需要在可执行文件中进行所有链接(选项 2)。我建议您使用 ldd 工具来调查可执行文件和 so 文件的依赖关系,以了解其工作原理。
有关为什么选项 1 更好的实际示例,请尝试 ldd /usr/lib/libpng.so。请注意,libpng 与 libz 链接。如果不是,任何链接到 libpng 的人也需要链接到 libz。事实上,您甚至可以在不知道涉及 libz 的情况下链接到 libpng。
I would go with option 1 (though option 2 works, I wouldn't recommend it since then anybody who links the exe needs to remember all the transitive libraries required).
However, this advice is only for making an
so
file, as you do above.so
files (shared objects) are "intelligent" libraries, much like executables, except they don't have a main.so
files can link to other libraries (like executables), and when an executable links to anso
file, it will automatically recursively include the dependencies of theso
file.Therefore, an
so
file you create should be linked with all of its dependencies.A "dumb" library, such as an
a
file (static library) is a different story; then you need to do all the linking in the executable (option 2).I recommend you use the
ldd
tool to investigate the dependencies of both the executable and theso
file to see how this works.For a real-world example of why option 1 is better, try
ldd /usr/lib/libpng.so
. Note that libpng is linked with libz. If it wasn't, anybody who ever links against libpng would also need to link against libz. As it is, you can link against libpng without even knowing that libz is involved.当您构建库时,它们并不相互依赖。它是依赖于它们的可执行文件(exe 或 dll)。库只是函数和/或数据的集合。当 exe/dll 在链接时使用它们的内容时,它们必须在那里(来自哪里并不重要)。图书馆没有链接(在构建它们时),组成它们的目标文件由图书馆员存档。
一个库中的函数可以使用另一个库中的函数,但只有在 exe/dll 的链接时才会解析这些依赖关系(这意味着必须链接两个库)。
Libraries are not dependant of each other when you build them. It is de executable (exe or dll) that is dependant on them. Libraries are just collections of functions and/or data. They just have to be there when their contents is used by the exe/dll at link-time (from where is not important). Libraries are not linked (when building them) ,the object-files that comprise them archived by a librarian.
The functions in one library can use function in another library ,but only at link-time of an exe/dll will those depencies be resolved (that means that both libraries must be linked in).