秋·风

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
修复lazarus/fpc在windows不支持中文目录的问题(2025-09-22更新) - 秋·风 - 博客园》后已支持中文目录,但交叉编译时出错以下错误信息:

QQ_1758889013347

1、写linkxxxx.res时cross目录缺少双引号:
fpcsrc\compiler\systems\t_linux.pas这个 Function TLinkerLinux.WriteResponseFile(isdll:boolean) : Boolean;
QQ_1758893731951
将WriteResponseFile函数按以下红色代码修改:

Function TLinkerLinux.WriteResponseFile(isdll:boolean) : Boolean;
Var
  linkres      : TLinkRes;
  i            : longint;
  HPath        : TCmdStrListItem;
  s,s1,s2      : TCmdStr;
  found1,
  found2       : boolean;
  linksToSharedLibFiles, libraryadded: boolean;
begin
  result:=False;
{ set special options for some targets }
  if cs_profile in current_settings.moduleswitches then
   begin
     if not(libctype in [glibc2,glibc21]) then
       AddSharedLibrary('gmon');
     AddSharedLibrary('c');
   end;

  { Open link.res file }
  LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true);
  with linkres do
    begin
      { Write path to search libraries }
      HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
      while assigned(HPath) do
       begin
         Add('SEARCH_DIR("'+HPath.Str+'")');
         HPath:=TCmdStrListItem(HPath.Next);
       end;
      HPath:=TCmdStrListItem(LibrarySearchPath.First);
      while assigned(HPath) do
       begin
         Add('SEARCH_DIR("'+HPath.Str+'")');
         HPath:=TCmdStrListItem(HPath.Next);
       end;

      { force local symbol resolution (i.e., inside the shared }
      { library itself) for all non-exorted symbols, otherwise }
      { several RTL symbols of FPC-compiled shared libraries   }
      { will be bound to those of a single shared library or   }
      { to the main program                                    }
      if (isdll) then
        begin
          add('VERSION');
          add('{');
          add('  {');
          if not texportlibunix(exportlib).exportedsymnames.empty then
            begin
              add('    global:');
              repeat
                add('      '+texportlibunix(exportlib).exportedsymnames.getfirst+';');
              until texportlibunix(exportlib).exportedsymnames.empty;
            end;
          add('    local:');
          add('      *;');
          add('  };');
          add('}');
        end;

      StartSection('INPUT(');
      { add objectfiles, start with prt0 always }
      if not (target_info.system in systems_internal_sysinit) and (prtobj<>'') then
       AddFileName(maybequoted(FindObjectFile(prtobj,'',false)));
      { try to add crti and crtbegin if linking to C }
      if linklibc and (libctype<>uclibc) then
       begin
         { crti.o must come first }
         if librarysearchpath.FindFile('crti.o',false,s) then
           AddFileName('"'+s+'"')
         else
           Message1(exec_w_init_file_not_found,'crti.o');

         { then the crtbegin* }
         if (cs_create_pic in current_settings.moduleswitches)
{$ifdef RISCV}
         { on RISC-V we need to use always the *S.o variants
           if shared libraries are involved }
         or (not SharedLibFiles.Empty)
{$endif RISCV}
         then
           begin
             if librarysearchpath.FindFile('crtbeginS.o',false,s) then
               AddFileName('"'+s+'"')
             else
               Message1(exec_w_init_file_not_found,'crtbeginS.o');
           end
         else
           if (cs_link_staticflag in current_settings.globalswitches) then
             begin
               if librarysearchpath.FindFile('crtbeginT.o',false,s) then
                 AddFileName('"'+s+'"')
               else
                 Message1(exec_w_init_file_not_found,'crtbeginT.o');
             end
           else if librarysearchpath.FindFile('crtbegin.o',false,s) then
             AddFileName('"'+s+'"')
           else
             Message1(exec_w_init_file_not_found,'crtbegin.o');
       end;
      { main objectfiles }
      while not ObjectFiles.Empty do
       begin
         s:=ObjectFiles.GetFirst;
         if s<>'' then
          AddFileName(maybequoted(s));
       end;
      EndSection(')');

      { Write staticlibraries }
      if not StaticLibFiles.Empty then
       begin
         Add('GROUP(');
         While not StaticLibFiles.Empty do
          begin
            S:=StaticLibFiles.GetFirst;
            AddFileName(maybequoted(s))
          end;
         Add(')');
       end;

      // we must reorder here because the result could empty sharedlibfiles
      if reorder Then
        ExpandAndApplyOrder(SharedLibFiles);
      // after this point addition of shared libs not allowed.

      { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
        here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
      if isdll and not linklibc then
       begin
         Add('INPUT(');
         Add(sysrootpath+info.DynamicLinker);
         Add(')');
       end;
      linksToSharedLibFiles := not SharedLibFiles.Empty;

      if not SharedLibFiles.Empty then
       begin

         if (SharedLibFiles.Count<>1) or
            (TCmdStrListItem(SharedLibFiles.First).Str<>'c') or
            reorder then
           begin
             libraryadded:=false;
             Add('INPUT(');
             While not SharedLibFiles.Empty do
               begin
                 S:=SharedLibFiles.GetFirst;
                 if (s<>'c') or reorder then
                  begin
                    i:=Pos(target_info.sharedlibext,S);
                    if i>0 then
                     Delete(S,i,255);
                    Add('-l'+s);
                    libraryadded:=true;
                  end
                 else
                   linklibc:=true;
               end;
             { link explicitly against the dyn. linker in case we are using section threadvars and
               if we link against any other library. We need __tls_get_addr from the dyn. linker in this case.
               This does not hurt as in case we use a dyn. library we depend on the dyn. linker anyways.

               All this does not apply if we link anyways against libc }
             if libraryadded and not(linklibc) and not(isdll) and (tf_section_threadvars in target_info.flags) then
               Add('-l:'+ExtractFileName(defdynlinker));
             Add(')');
           end
         else
           linklibc:=true;
         if (cs_link_staticflag in current_settings.globalswitches) or
            (linklibc and not reorder) then
           begin
             Add('GROUP(');
             { when we have -static for the linker the we also need libgcc }
             if (cs_link_staticflag in current_settings.globalswitches) then
               begin
                 Add('-lgcc');
                 if librarysearchpath.FindFile('libgcc_eh.a',false,s1) then
                   Add('-lgcc_eh');
               end;
             { be sure that libc is the last lib }
             if linklibc and not reorder then
               Add('-lc');
             Add(')');
           end;
       end;

      { objects which must be at the end }
      if linklibc and (libctype<>uclibc) then
       begin
         if (cs_create_pic in current_settings.moduleswitches)
{$ifdef RISCV}
         { on RISC-V we need to use always the *S.o variants
           if shared libraries are involved }
         or linksToSharedLibFiles
{$endif RISCV}
         then
           begin
             found1:=librarysearchpath.FindFile('crtendS.o',false,s1);
             if not(found1) then
               Message1(exec_w_init_file_not_found,'crtendS.o');
           end
         else
           begin
             found1:=librarysearchpath.FindFile('crtend.o',false,s1);
             if not(found1) then
               Message1(exec_w_init_file_not_found,'crtend.o');
           end;

         found2:=librarysearchpath.FindFile('crtn.o',false,s2);
         if not(found2) then
           Message1(exec_w_init_file_not_found,'crtn.o');
         if found1 or found2 then
          begin
            Add('INPUT(');
            if found1 then
             AddFileName('"'+s1+'"');
            if found2 then
             AddFileName('"'+s2+'"');
            Add(')');
          end;
       end;

      { Entry point. Only needed for executables, as for shared lubraries we use
        the -init command line option instead

       The "ENTRY" linkerscript command does not have any effect when augmenting
       a linker script, so use the command line parameter instead }
      if (not isdll) then
        if (linksToSharedLibFiles and not linklibc) then
          info.ExeCmd[1]:=info.ExeCmd[1]+' -e _dynamic_start'
        else
          info.ExeCmd[1]:=info.ExeCmd[1]+' -e _start';

      add('SECTIONS');
      add('{');
      if not(cs_link_pre_binutils_2_19 in current_settings.globalswitches) then
        { we can't use ".data", as that would hide the .data from the
          original linker script in combination with the INSERT at the end }
        add('  .fpcdata           :')
      else
        add('  .data           :');
      add('  {');
      add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
      add('  }');
      if not(cs_debuginfo in current_settings.moduleswitches) and
         not(tf_use_psabieh in target_info.flags) then
        add('  /DISCARD/ : {*(.debug_frame)}');
      add('  .threadvar : { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
      add('}');
      { this "INSERT" means "merge into the original linker script, even if
        -T is used" }
      if not(cs_link_pre_binutils_2_19 in current_settings.globalswitches) then
        add('INSERT AFTER .data;');
      { Write and Close response }
      writetodisk;
      Free;
    end;

  WriteResponseFile:=True;
end;

2、跟踪fpc编译器发现执行以下命令时出现上面的错误:

D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe -b elf64-x86-64 -m elf_x86_64  --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -L. -o "D:\QFLazarus4.2绿色版\projects\project1" -T "D:\QFLazarus4.2绿色版\projects\link8256.res" -e _start

是链接器不支持中文引起的:

D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe -b elf64-x86-64 -m elf_x86_64  --dynamic-linker=/lib64/ld-linux-x86-64.so.2 -L. -o "D:\QFLazarus4.2绿色版\projects\project1" -T "D:\QFLazarus4.2绿色版\projects\link8256.res" -e _start
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lpthread: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -ldl: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lgdk-x11-2.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lgtk-x11-2.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lX11: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lgdk_pixbuf-2.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lgobject-2.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lglib-2.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lgthread-2.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lgmodule-2.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lpango-1.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lcairo: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -latk-1.0: No such file or directory
D:\QFLazarus4.2绿色版\cross\bin-x86_64-win64\x86_64-linux\x86_64-linux-gnu-ld.exe: cannot find -lc: No such file or directory

更新x86_64-linux-gnu-ld.exe,用支持中文的x86_64-linux-gnu-ld.exe替换原有的文件。
3、最后,重新编译相应的cross就可以。 

 

posted on 2025-09-26 21:43  秋·风  阅读(76)  评论(1)    收藏  举报