我有一个父C ++ Makefile,它从两个源子目录构建2个库。
库B取决于库A。
cpp文件是通过标准隐式规则编译的。
链接器步骤的完成是通过使用一个函数来获取源代码,用.o替换.cpp,然后创建一个依赖项:
# $(call source-to-object, source-file-list)
source-to-object = $(subst .c,.o,$(filter %.c,$1)) \
$(subst .cpp,.o,$(filter %.cpp,$1))
# $(call make-library, library-name, source-file-list, customldopt)
define make-library
libraries += $1
sources += $2
$1: $(call source-to-object,$2)
$(CXX) $(CXXFLAGS) -shared $$^ -o $(RELEASE)/$$@ -L$(RELEASE) $(LDFLAGS) $(LDLIBS) $(addprefix -l,$3)
endef
这很好,直到我想在两个库之间引入依赖关系。我正在通过硬编码做到这一点:
libB.so: libA.so
这里的问题是 $$^
现在将不干净地包含目标文件列表,但还将包含libA.so-在链接器行中的相同位置没有位置作为目标文件?
所以我的问题是我如何引入两个库之间的依赖关系的思想,而又不用依赖库的值污染链接器行?
此陈述不正确,您要做,希望链接器行以与表示目标相同的形式引用该库-请参阅我的答案
我当然可以在libB.so的链接器行中包含-lA,就像您对第3方依赖项一样-但这不能保证它会在被引用之前生成?
我注意到的一件事是,如果我将$(RELEASE)/$$@
更改为$$@
,那么它将起作用:
g++ -fPIC -shared path/to/some_source.o libA.so -o libB.so
这是一个问题,因为我需要$ RELEASE目录中的两个库的输出,而且我不确信上面链接器行中的libA.so
是正确的吗?
它变得一团糟-有什么建议吗?
谢谢
答案 0 :(得分:2)
所以我的问题是我如何引入两个库之间的依赖关系的思想,而又不用依赖库的值污染链接器行?
您可以指定"order-only prerequisite",这意味着创建libA.so的规则必须在创建libB.so之前完成:
libB.so : | libA.so
与正常先决条件的区别在于,如果libA.so比libB.so更新,则不会重建libB.so。在查看libB.so的先决条件时,只需关心libA.so是否存在,而不关心它的年龄。
如果这对您没有用(因为您希望在libA.so更改时重新构建libB.so),则可以使用$(filter-out libA.so,$^)
答案 1 :(得分:1)
您确实已经使用source-to-object
函数获取了目标文件。您不仅可以用它代替$$^
吗?还是我在这里遗漏了一些东西?
答案 2 :(得分:0)
问题在于我对链接器命令的理解以及输出目标的移动,如@ o11c在原始问题下的注释中所述。
在链接器行上具有libA.so很好。
我添加了后续的cp命令,将$ @复制到$(RELEASE),以便将目标保留在make期望的位置。
$1: $(call source-to-object,$2)
$(CXX) $(CXXFLAGS) -shared $$^ -o $$@ $(LDFLAGS) $(LDLIBS)
$(CP) $$@ $(RELEASE)