在我为简化应用程序/库构建而编写的主 make 文件中,我使用的解决方案是运行链接步骤两次。使用 -u 链接器选项在第二个链接上指定未定义的符号。
在我的make文件中,我有一个这样的目标:
undefined.txt:
@$(generate-undefined-syms)
它调用这个宏......第一次尝试链接......
define generate-undefined-syms
$(PRINTF) "$(this_makefile): Generating undefined symbols ... \n"
$(CC) -o rubbish $(LDFLAGS) $(objects) $(LDLIBS) 2>&1 | $(GREP) 'undefined reference' > tmp.txt; \
$(SED) 's/^.*`/-Wl,-u/g' < tmp.txt > undefined.txt; \
rm -f tmp.txt rubbish
endef
由于我的 sed/regexp 技能不好(而且我匆忙写了这些东西),我最终得到了 undefined.txt,其中包含:
-uSomeSym'
-uSomeOtherSym'
即带有尾随'
然后我使用这个 make 语法去除's,并删除重复项
undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))
'follow' 过滤器是因为如果多次引用一个未定义的符号,输出中会出现“more references to XXX follow”的消息,这会导致 undefined.txt 文件中出现虚假的“follow”,例如
-Wl, uXXXX' follow
最后我第二次链接(注意对undefined.txt的依赖)
$(application): $(library_dependencies) $(objects) undefined.txt
$(CC) -o $@ $(LDFLAGS) $(undefined_references) $(objects) $(LDLIBS)
顺便说一句,我完全推荐了以下书,因为我能够在几天内从头开始编写一个简单的构建系统。
使用 GNU Make 管理项目,第三版 作者:Robert Mecklenburg