【发布时间】:2020-04-28 23:53:36
【问题描述】:
在最终将其作为Makefile 配方的一部分之前,我需要测试对特定链接器标志 (--no-undefined) 的支持。
保证所有平台都支持此链接器标志(事实上,它破坏了macosx 链接阶段),因此仅在实际支持时才启用它很重要。
我倾向于运行时测试,这似乎比更难维护的编译器/系统的静态列表更可取。
最好从Makefile 运行测试,然后有条件地设置标志。
【问题讨论】:
在最终将其作为Makefile 配方的一部分之前,我需要测试对特定链接器标志 (--no-undefined) 的支持。
保证所有平台都支持此链接器标志(事实上,它破坏了macosx 链接阶段),因此仅在实际支持时才启用它很重要。
我倾向于运行时测试,这似乎比更难维护的编译器/系统的静态列表更可取。
最好从Makefile 运行测试,然后有条件地设置标志。
【问题讨论】:
最可靠的测试是链接测试,即尝试实际链接某些东西。这种测试取决于您是通过编译器链接还是直接与链接器链接。我的方法是创建一个通用模板来测试任意标志,这样它就可以在不同的地方重复用于不同的标志,例如:
$ cat Makefile
CHECK_CC_FLAGS := -Wl,--no-undefined -Wl,--whatever
CHECK_LD_FLAGS := --no-undefined --whatever
define check_cc_flag
$(shell echo 'int main() { return 0; }' | $(CC) $(1) -xc - 2>/dev/null && echo $(1))
endef
define check_ld_flag
$(shell $(LD) $(1) -e 0 /dev/null 2>/dev/null && echo $(1))
endef
# If linking with $(CC)
test: LDFLAGS += $(foreach flag,$(CHECK_CC_FLAGS),$(call check_cc_flag,$(flag)))
# If linking with $(LD)
test_ld: LDFLAGS += $(foreach flag,$(CHECK_LD_FLAGS),$(call check_ld_flag,$(flag)))
test_ld: test.o
$(LD) $(LDFLAGS) -o $@ $<
模板尝试运行编译器或链接器,如果成功(即以 0 退出),它将打印出标志,否则输出将为空。如果编译器和/或链接器表现不佳(尝试失败返回 0)可能会更麻烦。
Ubuntu 20.04 LTS 上的实际输出:
$ make test
cc -c -o test.o test.c
cc -Wl,--no-undefined test.o -o test
$ make test_ld
ld --no-undefined -o test_ld test.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
【讨论】: