【发布时间】:2018-08-07 20:21:36
【问题描述】:
一段时间以来,我一直在使用特定于目标的变量来传递特定于对象的标志。例如,如果我需要将可执行文件与某个库链接,我可能会这样做:
bin/foo: LDFLAGS += -lbar
bin/% 规则将选择-lbar。这对系统库很有用,但是当我链接的库也是项目的一部分时,就会出现问题。在这种情况下,我会有一个类似的依赖项
bin/foo: lib/libbar.so
在构建lib/libbar.so 时,我应用于bin/foo 的特定于目标的规则也通过了!这不起作用,因为libbar.so 无法链接到自身。正如manual 所说,
目标特定变量还有一个特殊功能:当您定义目标特定变量时,该变量值也对该目标的所有先决条件及其所有先决条件等有效(除非这些先决条件覆盖具有自己的目标特定变量值的变量)。
我该怎么做才能只为bin/foo 添加该标志而不是它的先决条件?上面的引用暗示了类似
lib/libbar.so: LDFLAGS :=
但这并不理想,因为我的真实项目在全球范围内设置了其他 LDFLAGS 我想保留。
这是一个复制器:
生成文件
bin/%: @mkdir -p $(@D) gcc $(LDFLAGS) $(filter %.o,$^) -o $@ lib/%: @mkdir -p $(@D) gcc $(LDFLAGS) -shared $(filter %.o,$^) -o $@ obj/%.o: src/%.c @mkdir -p $(@D) gcc $(CFLAGS) -c $< -o $@ bin/foo: obj/foo.o lib/libbar.so bin/foo: LDFLAGS := -Wl,-rpath='$$ORIGIN/../lib' -Llib -lbar lib/libbar.so: obj/bar.o clean: rm -rf bin lib obj .PHONY: cleansrc/foo.c
int bar(void); int main() { return bar(); }src/bar.c
int bar() { return 42; }
这个坏了:
$ make bin/foo
gcc -c src/foo.c -o obj/foo.o
gcc -c src/bar.c -o obj/bar.o
gcc -Wl,-rpath='$ORIGIN/../lib' -Llib -lbar -shared obj/bar.o -o lib/libbar.so
/bin/ld: lib/libbar.so: file not recognized: file truncated
collect2: error: ld returned 1 exit status
make: *** [Makefile:7: lib/libbar.so] Error 1
但如果我先构建库,它就可以工作:
$ make lib/libbar.so
gcc -c src/bar.c -o obj/bar.o
gcc -shared obj/bar.o -o lib/libbar.so
$ make bin/foo
gcc -c src/foo.c -o obj/foo.o
gcc -Wl,-rpath='$ORIGIN/../lib' -Llib -lbar obj/foo.o -o bin/foo
$ ./bin/foo; echo $?
42
【问题讨论】: