I need to test the support of a specific linker flag (--no-undefined
) before eventually making it part of a Makefile
recipe.
This linker flag is not guaranteed to be supported on all platforms (as a matter of fact, it breaks macosx
link stage), so it's important to only enable it when it's actually supported.
I lean towards a runtime test, which seems preferable to a static list of compilers / systems which would be more difficult to maintain.
Preferably, the test would be run from the Makefile
, which would then conditionally set the flag.
The most reliable test would be a linking test, i.e. try to actually link something. This kind of test would depend on whether you are linking through the compiler or directly with the linker. My approach would be to create a generic template for testing arbitrary flag so it could be reused for different flags in different places, e.g.:
$ 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 $@ $<
The template tries to run the compiler or linker and if it succeeds (i.e. exits with 0) it will print out the flag, otherwise the output will be empty. May be more cumbersome if the compiler and/or linker do not behave good (return 0 on failed attempts).
Actual output on 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