简体   繁体   English

Makefile创建两个库 - 一个取决于其他库

[英]Makefile Creates Two Libraries - One Depends On Other

I have a parent C++ Makefile that builds 2 libraries, from two source subdirectories. 我有一个父C ++ Makefile,它从两个源子目录构建2个库。

Library B depends on Library A. 图书馆B依赖图书馆A.

The cpp files is compiled via the standard implicit rule. cpp文件是通过标准隐式规则编译的。

The linker step is completed by having a function that takes the sources, replaces the .cpp with a .o and then creates a dependency: 通过使用一个获取源的函数,用.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

This works fine until I want to introduce a dependency between the 2 libraries. 这工作正常,直到我想在两个库之间引入依赖关系。 I'm doing this by hardcoding: 我是通过硬编码来做到这一点的:

libB.so: libA.so

The problem here is that the $$^ will now not cleanly contain a list of object files, but will also include the libA.so - which has no place being in the linker line in the same place as the object files? 这里的问题是$$^现在不会干净地包含目标文件列表,但是也会包含libA.so - 它与目标文件在同一个地方的链接器行中没有位置?

So my question is how do I introduce the idea of a dependency between two libraries, without polluting the linker line with the value of the dependent library? 所以我的问题是如何引入两个库之间的依赖关系的想法,而不用依赖库的值污染链接器行?

This statement is not correct, you do want the library to be referenced on the linker line in the same form as it is represented as a target - see my answer 这个语句不正确,你确实希望在链接器行上引用库的形式与它表示为目标的形式相同 - 请参阅我的回答

I can of course just have -lA in the linker line for libB.so, just like you would for a 3rd party dependency - but this does not guarantee it will be built before it is referenced? 我当然可以在libB.so的链接器行中使用-lA,就像你对第三方依赖一样 - 但是这并不保证它会在引用之前构建它?

One thing I have noticed is that if I change $(RELEASE)/$$@ to just $$@ then it works: 我注意到的一件事是,如果我将$(RELEASE)/$$@改为$$@那么它可以工作:

g++ -fPIC -shared path/to/some_source.o libA.so -o libB.so 

This is a problem as I need the output of both libraries in the $RELEASE directory, and I'm not convinced the libA.so in the above linker line is ever correct? 这是一个问题,因为我需要$ RELEASE目录中两个库的输出,我不相信上面链接器行中的libA.so是否正确?

It's becoming a bit of a mess - any advice? 它变得有点乱 - 任何建议?

Thanks 谢谢

So my question is how do I introduce the idea of a dependency between two libraries, without polluting the linker line with the value of the dependent library? 所以我的问题是如何引入两个库之间的依赖关系的想法,而不用依赖库的值污染链接器行?

You can specify an "order-only prerequisite" which means that the rule for creating libA.so must complete before creating libB.so: 您可以指定“仅订单的先决条件” ,这意味着在创建libB.so之前必须完成创建libA.so的规则:

libB.so : | libA.so

The difference from a normal prerequisite is that if libA.so is newer than libB.so then libB.so won't be re-built. 与正常先决条件的区别在于,如果libA.so比libB.so更新,则不会重新构建libB.so。 When looking at the prerequisites for libB.so Make only cares if libA.so exists, not how old it is. 在查看libB.so的先决条件时,如果libA.so存在,则只关心它,而不是它的年龄。

If that's not useful for you (because you want libB.so to be rebuilt when libA.so changes) then you can just filter it out of the prerequisites by using $(filter-out libA.so,$^) 如果这对你没用(因为你希望在libA.so更改时重建libB.so),那么你可以通过使用$(filter-out libA.so,$^)它从先决条件中$(filter-out libA.so,$^)

You do already get the object files using the source-to-object function. 您已经使用source-to-object函数获取了目标文件。 Can you not just use that instead of $$^ , or am I missing something here? 你能不能只使用它而不是$$^ ,或者我在这里遗漏了什么?

The problem was my understanding of the linker command, and the moving of the output target as stated by @o11c in the comments under the original question. 问题是我对链接器命令的理解,以及@ o11c在原始问题下的注释中所述的输出目标的移动。

Having libA.so on the linker line is fine. 在链接器行上有libA.so就可以了。

I've added a subsequent cp command to copy the the $@ to $(RELEASE) so that targets are kept where make expects. 我添加了一个后续的cp命令来将$ @复制到$(RELEASE),以便将目标保存在make期望的位置。

$1: $(call source-to-object,$2)
    $(CXX) $(CXXFLAGS) -shared $$^ -o $$@ $(LDFLAGS) $(LDLIBS)
    $(CP) $$@ $(RELEASE)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM