




















fpc 3.2.2交叉编译i386-linux链接出错,原以为是cross的lib问题,查询发现是:
FPC 3.2.2 的源码文件 fpcsrc/rtl/linux/i386/si_c21.inc ,它引用了 __libc_csu_init 和 __libc_csu_fini 这两个函数。然而,在较新的 glibc 版本(如 2.34 及更高)中,这些符号已经被移除或不再公开导出。
因此,当 FPC 3.2.2 在链接时试图引用这些不存在的符号时,链接器就会报错。
project1.lpr(28,1) Warning: "crtn.o" not found, this will probably cause a linking failure C:\QFLazarus_x86_64_win64\cross\bin-x86_64-win64\i386-linux\i386-linux-gnu-ld.exe: C:\Temp\project1: hidden symbol `__init_array_end' isn't defined C:\QFLazarus_x86_64_win64\cross\bin-x86_64-win64\i386-linux\i386-linux-gnu-ld.exe: final link failed: bad value project1.lpr(28,1) Error: Error while linking

解决方案:
1、升级 FPC 版本:这是最直接的解决方法。FPC 的开发者在 3.2.3 及更新的版本(包括 3.3.1)中已经修复了此问题
2、用新版si_c21.inc替换。
修复si_s21.inc后,重新编译i386-linux的交叉编译环境,然后编译应用就可以。
修复后编译已正常:

这是patch:
diff -urN 1\si_c21.inc 2\si_c21.inc --- 1\si_c21.inc Sat May 15 23:38:31 2021 +++ 2\si_c21.inc Tue Jun 16 19:07:37 2026 @@ -35,12 +35,13 @@ {$asmmode att} -procedure __libc_csu_init; cdecl; external; -procedure __libc_csu_fini; cdecl; external; +procedure ini_dummy; + begin + end; + procedure libc_start_main; external name '__libc_start_main'; procedure libc_exit(code: longint); cdecl; external name 'exit'; - {****************************************************************************** glibc 2.1 lib + profiling start/halt ******************************************************************************} @@ -81,20 +82,20 @@ {$endif FPC_PIC} { int __libc_start_main( - int *(main) (int, char * *, char * *), - int argc, - char * * ubp_av, - void (*init) (void), - void (*fini) (void), - void (*rtld_fini) (void), - void (* stack_end)); } + int *(main) (int, char **, char **), + int argc, + AnsiChar * * ubp_av, + void (*init) (void), + void (*fini) (void), + void (*rtld_fini) (void), + void (* stack_end)); } pushl %ebp { padding } pushl %esp { stack_end } pushl %edx { function to be registered with atexit(), passed by loader } - pushl $__libc_csu_fini - pushl $__libc_csu_init + pushl $ini_dummy + pushl $ini_dummy pushl %esi { Push second argument: argv. } pushl %ecx { Push first argument: argc. }
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。