链接时库依赖如何工作?

时间:2011-02-07 02:53:14

标签: c++ makefile

我有一个库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

或其他一些组合?

2 个答案:

答案 0 :(得分:1)

我会选择选项1(虽然选项2有效但我不推荐它,因为任何链接exe的人都需要记住所需的所有传递库。)

但是,此建议仅适用于制作so文件,如上所述。 so个文件(共享对象)是“智能”库,很像可执行文件,除了它们没有main。 so个文件可以链接到其他库(如可执行文件),当可执行文件链接到so文件时,它会自动递归地包含so文件的依赖项。

因此,您创建的so文件应与其所有依赖项链接。

“哑”库,例如a文件(静态库)是另一回事;然后你需要在可执行文件中进行所有链接(选项2)。

我建议您使用ldd工具调查可执行文件和so文件的相关性,以了解其工作原理。

有关选项1为何更好的真实示例,请尝试ldd /usr/lib/libpng.so。请注意,libpng与libz链接。如果不是,那么任何与libpng链接的人都需要链接libz。事实上,你可以在不知道涉及libz的情况下链接libpng。

答案 1 :(得分:0)

在构建库时,库不是彼此依赖的。它是可执行的(exe或dll)依赖于它们。库只是函数和/或数据的集合。当他们的内容被链接时的exe / dll使用时,他们只需要在那里(从哪里不重要)。库没有链接(构建它们时),组成它们的对象文件由图书馆员归档。

一个库中的函数可以使用另一个库中的函数,但只有在exe / dll的链接时才会解析这些依赖项(这意味着必须链接两个库)。