You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

arm64环境nm显示.so含已定义函数但ld链接找不到对应符号

报错原因

一共有4处配置错误,其中直接触发符号找不到的核心原因是链接顺序错误:

  • GNU ld默认按从左到右的顺序扫描输入文件,左侧文件的未定义符号只会到右侧的输入文件/库中查找。你当前的编译命令把-llib1放在了源文件a.c/a.cc的前面,从ld的执行日志可以看到实际传入的参数顺序是-llib1 /tmp/cc0K5Hhf.o(后者是源文件编译生成的临时目标文件)。ld扫描到-llib1时,还没有读取到后续目标文件里对foo_incremented的未定义引用,加上默认开启的--as-needed参数会直接丢弃没有被前置文件依赖的库,等后续扫描到目标文件的未定义符号时,不会回头重新扫描已经处理过的-llib1,就会报符号找不到。
  • 共享库生成参数错误:Linux下生成位置无关的共享库,编译阶段需要加-fPIC参数生成位置无关代码,链接阶段需要加-shared参数指定生成共享库。你当前写的cc -dynamic -o $@ $<里,-dynamic是生成动态链接可执行文件的参数,不是生成共享库的参数,生成出来的文件不是合法的共享库,即使解决链接顺序问题后续运行也会出错。
  • 头文件标准宏写错:C/C标准中用来判断当前是否为C编译环境的宏是__cplusplus,你写的__cplusplus__前后都带双下划线,是不存在的自定义宏,会导致编译C文件时extern "C"声明不生效,后续会触发C符号修饰不匹配的问题。
  • acc目标的编译参数写错:你写的-Wl,-v,-rpath=.会把-v参数传给链接器,同时rpath参数的传递格式也不规范,另外两个可执行文件的依赖项没有加上liblib1.so,库文件修改后不会自动触发可执行文件重编译。
修复步骤
  1. 修正共享库的编译规则,添加-fPIC和-shared参数:
liblib1.so: $(lib1_source)
	cc -fPIC -shared -o $@ $<
  1. 修正lib1.h中的宏拼写错误:
// lib1.h
#ifndef LIB1_H
#define LIB1_H

#ifdef __cplusplus
extern "C" {
#endif

extern int foo_incremented(int x);

#ifdef __cplusplus
}
#endif

#endif
  1. 修正两个可执行文件的编译规则,调整链接顺序(把库参数放到源文件后面),修正rpath参数,补全依赖项:
a: a.c liblib1.so lib1.h
	cc -Wl,-rpath=. -L. -I. -o $@ $< -llib1

acc: a.cc liblib1.so lib1.h
	c++ -Wl,-rpath=. -L. -I. -o $@ $< -llib1
  1. (可选规范修正)把Makefile开头的伪目标声明修正为标准写法:
.PHONY: clean

修正后先执行make clean && make liblib1.so,再执行make a或make acc即可正常编译链接。


内容的提问来源于stack exchange,提问作者Michaelzh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:36:37