Delphi 12.3+Ubuntu22.04编译时libdl.a语法及System.o未定义引用问题
解决Delphi 12.3+Ubuntu22.04构建时libdl.a空归档链接错误问题
问题背景
升级构建服务器环境至Delphi 12.3(含四月补丁)+Ubuntu 22.04后,通过dcclinux64.exe命令行构建Linux应用时遭遇链接错误:
- 系统自动引入的
libdl.a仅包含! <arch>标识,被ld-linux.exe判定为非有效对象/归档文件 - 虽调整
--libpath和-u参数的路径顺序解决了System.o未定义引用问题,但libdl.a的问题持续存在;删除/重命名该文件后,链接器又提示找不到-ldl
根源在于Ubuntu22.04搭载的glibc 2.35已将libdl、libpthread等库的功能整合至libc,仅保留空静态归档文件做向下兼容,但Delphi的Linux链接器ld-linux.exe无法处理此类空归档。
可行解决方案
方案1:替换空libdl.a为指向libc.a的符号链接
- 进入Ubuntu22.04 SDK的
lib/x86_64-linux-gnu目录(或对应架构的lib目录) - 备份原空归档:
mv libdl.a libdl.a.bak - 创建指向libc.a的符号链接:
此方法让链接器查找libdl.a时实际使用libc.a,而libc已包含原libdl的所有符号。ln -s libc.a libdl.a
方案2:生成包含空对象的有效libdl.a归档
如果符号链接方式不生效,可手动生成一个合法的空归档文件:
- 创建空C文件并编译为对象文件:
touch empty.c gcc -c empty.c -o empty.o - 将空对象打包为libdl.a:
ar rcs libdl.a empty.o - 替换SDK目录中原有的libdl.a文件。链接器会识别这是合法归档,且因无实际符号,会自动从libc中查找所需的dlopen/dlclose等函数。
方案3:修改dcclinux64配置强制忽略-ldl参数
在dcclinux64.cfg文件中添加以下链接器参数,强制让链接器优先使用libc并跳过无效的libdl依赖:
-Wl,--no-as-needed,-lc,-Wl,--as-needed
同时添加参数抵消自动传递的-ldl:
-Wl,--exclude-libs,libdl.a
此配置会让链接器在处理时优先依赖libc,并且排除对libdl.a的强制引用。
内容的提问来源于stack exchange,提问作者Matthias B
相关产品推荐
相关产品推荐

