Самый надежный тест - это тест на связывание, то есть попытка что-то связать. Этот вид теста будет зависеть от того, используете ли вы компилятор или напрямую с компоновщиком. Мой подход заключается в создании общего шаблона c для проверки произвольного флага, чтобы его можно было повторно использовать для различных флагов в разных местах, например:
$ 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