GNUstep构建可执行文件链接libLibname.a出现undefined reference符号错误
问题产生原因
- 链接参数顺序错误:GNUstep Make 中
LDFLAGS变量的内容会被放在链接命令的靠前位置,早于你自己代码编译出的目标文件。而链接器处理静态库的规则是:只有处理到静态库时已经存在的未解析符号,才会从静态库中加载对应的目标文件。你把静态库路径放在LDFLAGS里时,链接器还没扫描到你代码里的ObjC类引用,就直接跳过了静态库,不会加载里面的内容。 - 链接器未识别ObjC符号规则:GNU 链接器默认不会主动加载静态库中仅包含ObjC类、分类的目标文件,这类符号的引用特征和C/C++符号不同,没有额外参数的情况下链接器会判定这类符号无引用,不会加载对应目标文件。
- 小概率原因:静态库编译时没有将
SomeClassNameOfLibLibname对应的实现文件编译打包进去,导致静态库本身就缺失对应符号。
解决方法
- 首先修正链接参数配置:不要将静态库路径放在
LDFLAGS变量中,改为放到LDADD变量中,同时推荐使用标准的库搜索路径+库名的写法,示例GNUmakefile配置:
# 添加静态库所在的搜索路径 ADDITIONAL_LIBRARY_DIRS += /usr/GNUstep/Local/Library/Libraries # 链接对应静态库,-lLibname 会自动匹配libLibname.a executableToolName_LDADD += -lLibname
如果需要指定全路径,也直接写在LDADD中即可:
executableToolName_LDADD += /usr/GNUstep/Local/Library/Libraries/libLibname.a
- 加链接参数强制加载ObjC符号:如果修改参数后仍然报错,在
LDFLAGS中添加-ObjC参数,让链接器主动扫描静态库中的所有ObjC符号:
executableToolName_LDFLAGS += -ObjC
如果是Linux环境用GNU ld,还可以用全加载参数包裹静态库:
executableToolName_LDFLAGS += -Wl,--whole-archive /usr/GNUstep/Local/Library/Libraries/libLibname.a -Wl,--no-whole-archive
- 验证静态库符号完整性:执行命令
nm /usr/GNUstep/Local/Library/Libraries/libLibname.a | grep SomeClassNameOfLibLibname,如果没有输出结果,说明静态库本身没有包含对应类,需要检查静态库的GNUmakefile是否将对应.m文件加入了编译列表。
内容的提问来源于stack exchange,提问作者shallowThought
相关产品推荐
相关产品推荐

