View Issue Details

IDProjectCategoryView StatusLast Update
0031099FPCCompilerpublic2019-06-21 21:21
ReporterAlfredAssigned ToMaciej Izak 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Platformx86_64OSWindowsOS VersionWin10
Product Version3.1.1Product Buildtrunk 
Target VersionFixed in Version 
Summary0031099: Enabling crosscompiling from Windows towards Darwin
DescriptionAfter the Makefile changes (thanks for that) as a result of solving:
http://bugs.freepascal.org/view.php?id=30964
some more changes are needed to be able to cross from Windows to Darwin.

Included are patches for script.pas and t_bsd.pas that allow the use of osxcross to cross from Windows to Darwin.
See:
https://github.com/tpoechtrager/osxcross
https://github.com/LongDirtyAnimAlf/osxcross
http://wiki.lazarus.freepascal.org/fpcupdeluxe#Crosscompiling_from_Windows_towards_Darwin
However, the changes are not osxcross-centric. But the changes will allow for the use of osxcross.

Most important change in these patches: a link-list (linkfiles.res) is used when linking files on Windows.
Additional InformationSome more changes are needed when implementing the patches:
fpcmake.inc : linkfiles.res has to be added
delp.pp : linkfiles.res has to be added

fpccfg.inc
This is non-trivial.
-ap is default for Darwin, but cannot be used when crossing from Windows towards Darwin. Adding #IFNDEF FPC_CROSSCOMPILING will solve for crossing from Windows, but could cause failures when crossing from Linux.
At the moment, I do not know how to get the underlying system when cross-compiling.

Patches have been tested on various systems ... no regressions detected.
TagsNo tags attached.
Fixed in Revision36168
FPCOldBugId
FPCTarget
Attached Files
  • crossdarwin.patch (9,455 bytes)
    Index: compiler/systems/t_bsd.pas
    ===================================================================
    --- compiler/systems/t_bsd.pas	(revision 35099)
    +++ compiler/systems/t_bsd.pas	(working copy)
    @@ -147,8 +147,8 @@
            begin
              if not(target_info.system in systems_darwin) then
                begin
    -             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';
    -             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'
    +             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES $FILELIST ';
    +             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES $FILELIST'
                end
              else
                begin
    @@ -167,16 +167,16 @@
                    programs with problems that require Valgrind will have more
                    than 60KB of data (first 4KB of address space is always invalid)
                  }
    -               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
    +               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
                  if not(cs_gdb_valgrind in current_settings.globalswitches) then
                    ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
     {$else ndef cpu64bitaddr}
    -             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
    +             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
     {$endif ndef cpu64bitaddr}
                  if (apptype<>app_bundle) then
    -               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'
    +               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
                  else
    -               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'
    +               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
                end
            end
          else
    @@ -388,6 +388,7 @@
     Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
     Var
       linkres      : TLinkRes;
    +  FilesList    : TLinkRes;
       i            : longint;
       cprtobj,
       gprtobj,
    @@ -589,15 +590,41 @@
                  LinkRes.AddFileName(s);
        end;
       { main objectfiles }
    +
    +  { Generate linkfiles.res file if needed }
    +  { Always needed on Windows, due to the limitation of 8196 characters for command line }
    +  { linkfiles.res will be piped if possible }
    +  if LdSupportsNoResponseFile then
    +  begin
    +    FilesList:=TLinkRes.Create(outputexedir+'linkfiles.res',not LdSupportsNoResponseFile);
       while not ObjectFiles.Empty do
        begin
          s:=ObjectFiles.GetFirst;
          if s<>'' then
    -      if LdSupportsNoResponseFile then
    -        LinkRes.AddFileName(s)
    +      begin
    +        {$ifdef MSWINDOWS}
    +        // osxcross specific, but does no harm
    +        // osxcross can only handle '/'
    +        repeat
    +          i:=Pos('\',s);
    +          if i>0 then s[i]:='/';
    +        until i=0;
    +        {$ENDIF}
    +        FilesList.Add(s);
    +      end;
    +    end;
    +    FilesList.writetodisk;
    +    FilesList.Free;
    +  end
           else
    -        LinkRes.AddFileName(maybequoted(s));
    +  begin
    +    while not ObjectFiles.Empty do
    +    begin
    +      s:=ObjectFiles.GetFirst;
    +      if s<>'' then LinkRes.AddFileName(maybequoted(s));
        end;
    +  end;
    +
       if not LdSupportsNoResponseFile then
        LinkRes.Add(')');
     
    @@ -784,6 +811,9 @@
       Replace(cmdstr,'$EMUL',EmulStr);
       Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
       Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
    +  if LdSupportsNoResponseFile
    +     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
    +     else Replace(cmdstr,'$FILELIST','');
       Replace(cmdstr,'$STATIC',StaticStr);
       Replace(cmdstr,'$STRIP',StripStr);
       Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
    @@ -813,8 +843,10 @@
             linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
           linkscript.WriteToDisk;
           BinStr:=linkscript.fn;
    +      {$ifndef MSWINDOWS}
           if not path_absolute(BinStr) then
             BinStr:='./'+BinStr;
    +      {$endif}
           CmdStr:='';
         end;
     
    @@ -836,6 +868,9 @@
            end;
        end;
     
    +  { Remove linkfiles.res }
    +  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
    +
       MakeExecutable:=success;   { otherwise a recursive call to link method }
     end;
     
    @@ -902,6 +937,9 @@
       Replace(cmdstr,'$TARGET',targetstr);
       Replace(cmdstr,'$EMUL',EmulStr);
       Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
    +  if LdSupportsNoResponseFile
    +     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
    +     else Replace(cmdstr,'$FILELIST','');
       Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
       Replace(cmdstr,'$INIT',InitStr);
       Replace(cmdstr,'$FINI',FiniStr);
    @@ -947,8 +985,10 @@
             linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
           linkscript.WriteToDisk;
           BinStr:=linkscript.fn;
    +      {$ifndef MSWINDOWS}
           if not path_absolute(BinStr) then
             BinStr:='./'+BinStr;
    +      {$endif}
           CmdStr:='';
         end;
     
    @@ -979,6 +1019,9 @@
             DeleteFile(outputexedir+'linksyms.fpc');
         end;
     
    +  { Remove linkfiles.res }
    +  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
    +
       MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
     end;
     
    Index: compiler/script.pas
    ===================================================================
    --- compiler/script.pas	(revision 35099)
    +++ compiler/script.pas	(working copy)
    @@ -236,7 +236,11 @@
          Add('echo Assembling %THEFILE%');
        end;
       Add(maybequoted(command)+' '+Options);
    +  {$ifdef MSWINDOWS}
    +  Add('if %ERRORLEVEL% EQU 1 goto asmend');
    +  {$else}
       Add('if errorlevel 1 goto asmend');
    +  {$endif}
     end;
     
     
    @@ -248,7 +252,11 @@
          Add('echo Linking %THEFILE%');
        end;
       Add(maybequoted(command)+' '+Options);
    +  {$ifdef MSWINDOWS}
    +  Add('if %ERRORLEVEL% EQU 1 goto linkend');
    +  {$else}
       Add('if errorlevel 1 goto linkend');
    +  {$endif}
     end;
     
     
    @@ -260,7 +268,11 @@
     
     Procedure TAsmScriptDos.AddDeleteDirCommand (Const FileName : TCmdStr);
     begin
    + {$ifdef MSWINDOWS}
    + Add('RMDIR /S /Q ' + MaybeQuoted (ScriptFixFileName (FileName)));
    + {$else}
      Add('Rmdir ' + MaybeQuoted (ScriptFixFileName (FileName)));
    + {$endif}
     end;
     
     
    @@ -361,7 +373,11 @@
       if FileName<>'' then
        Add('echo Assembling '+ScriptFixFileName(FileName));
       Add(maybequoted(command)+' '+Options);
    +  {$ifdef MSWINDOWS}
    +  Add('if %ERRORLEVEL% NEQ 0 call:DoExitAsm '+ScriptFixFileName(FileName));
    +  {$else}
       Add('if [ $? != 0 ]; then DoExitAsm '+ScriptFixFileName(FileName)+'; fi');
    +  {$endif}
     end;
     
     
    @@ -369,12 +385,18 @@
     begin
       if FileName<>'' then
        Add('echo Linking '+ScriptFixFileName(FileName));
    +  {$ifndef MSWINDOWS}
       Add('OFS=$IFS');
       Add('IFS="');
       Add('"');
    +  {$endif}
       Add(maybequoted(command)+' '+Options);
    +  {$ifndef MSWINDOWS}
       Add('if [ $? != 0 ]; then DoExitLink '+ScriptFixFileName(FileName)+'; fi');
       Add('IFS=$OFS');
    +  {$else}
    +  Add('if %ERRORLEVEL% NEQ 0 call:DoExitLink '+ScriptFixFileName(FileName));
    +  {$endif}
     end;
     
     
    @@ -386,12 +408,26 @@
     
     Procedure TAsmScriptUnix.AddDeleteDirCommand (Const FileName : TCmdStr);
     begin
    + {$ifdef MSWINDOWS}
    +  Add('RMDIR /S /Q ' + MaybeQuoted (ScriptFixFileName(FileName)));
    + {$else}
      Add('rmdir ' + MaybeQuoted (ScriptFixFileName(FileName)));
    + {$endif}
    +
     end;
     
     
     Procedure TAsmScriptUnix.WriteToDisk;
     Begin
    +  {$ifdef MSWINDOWS}
    +  Add('EXIT /B %ERRORLEVEL%');
    +  Add(':DoExitLink');
    +  Add('echo An error occurred while linking %*');
    +  Add('EXIT /B 1');
    +  Add(':DoExitAsm');
    +  Add('echo An error occurred while assembling %*');
    +  Add('EXIT /B 1');
    +  {$else}
       AddStart('{ echo "An error occurred while linking $1"; exit 1; }');
       AddStart('DoExitLink ()');
       AddStart('{ echo "An error occurred while assembling $1"; exit 1; }');
    @@ -401,6 +437,7 @@
       {$else}
        AddStart('#!/bin/sh');
       {$endif}
    +  {$endif}
       inherited WriteToDisk;
     end;
     
    @@ -420,7 +457,9 @@
       if FileName<>'' then
         Add('Echo Assembling '+ScriptFixFileName(FileName));
       Add(maybequoted(command)+' '+Options);
    +  {$ifndef MSWINDOWS}
       Add('Exit If "{Status}" != 0');
    +  {$endif}
     end;
     
     
    @@ -429,6 +468,7 @@
       if FileName<>'' then
         Add('Echo Linking '+ScriptFixFileName(FileName));
       Add(maybequoted(command)+' '+Options);
    +  {$ifndef MSWINDOWS}
       Add('Exit If "{Status}" != 0');
     
       {Add resources}
    @@ -437,6 +477,7 @@
           Add('Rez -append "{RIncludes}"SIOW.r -o '+ ScriptFixFileName(FileName));
           Add('Exit If "{Status}" != 0');
         end;
    +  {$endif}
     end;
     
     
    
    crossdarwin.patch (9,455 bytes)
  • crossdarwinnew.patch (6,884 bytes)
    Index: compiler/systems/t_bsd.pas
    ===================================================================
    --- compiler/systems/t_bsd.pas	(revision 35106)
    +++ compiler/systems/t_bsd.pas	(working copy)
    @@ -147,8 +147,8 @@
            begin
              if not(target_info.system in systems_darwin) then
                begin
    -             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';
    -             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'
    +             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES $FILELIST ';
    +             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES $FILELIST'
                end
              else
                begin
    @@ -167,16 +167,16 @@
                    programs with problems that require Valgrind will have more
                    than 60KB of data (first 4KB of address space is always invalid)
                  }
    -               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
    +               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
                  if not(cs_gdb_valgrind in current_settings.globalswitches) then
                    ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
     {$else ndef cpu64bitaddr}
    -             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
    +             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
     {$endif ndef cpu64bitaddr}
                  if (apptype<>app_bundle) then
    -               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'
    +               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
                  else
    -               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'
    +               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
                end
            end
          else
    @@ -388,6 +388,7 @@
     Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
     Var
       linkres      : TLinkRes;
    +  FilesList    : TLinkRes;
       i            : longint;
       cprtobj,
       gprtobj,
    @@ -589,15 +590,41 @@
                  LinkRes.AddFileName(s);
        end;
       { main objectfiles }
    +
    +  { Generate linkfiles.res file if needed }
    +  { Always needed on Windows, due to the limitation of 8196 characters for command line }
    +  { linkfiles.res will be piped if possible }
    +  if LdSupportsNoResponseFile then
    +  begin
    +    FilesList:=TLinkRes.Create(outputexedir+'linkfiles.res',not LdSupportsNoResponseFile);
       while not ObjectFiles.Empty do
        begin
          s:=ObjectFiles.GetFirst;
          if s<>'' then
    -      if LdSupportsNoResponseFile then
    -        LinkRes.AddFileName(s)
    +      begin
    +        {$ifdef MSWINDOWS}
    +        // osxcross specific, but does no harm
    +        // osxcross can only handle '/'
    +        repeat
    +          i:=Pos('\',s);
    +          if i>0 then s[i]:='/';
    +        until i=0;
    +        {$ENDIF}
    +        FilesList.Add(s);
    +      end;
    +    end;
    +    FilesList.writetodisk;
    +    FilesList.Free;
    +  end
           else
    -        LinkRes.AddFileName(maybequoted(s));
    +  begin
    +    while not ObjectFiles.Empty do
    +    begin
    +      s:=ObjectFiles.GetFirst;
    +      if s<>'' then LinkRes.AddFileName(maybequoted(s));
        end;
    +  end;
    +
       if not LdSupportsNoResponseFile then
        LinkRes.Add(')');
     
    @@ -784,6 +811,9 @@
       Replace(cmdstr,'$EMUL',EmulStr);
       Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
       Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
    +  if LdSupportsNoResponseFile
    +     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
    +     else Replace(cmdstr,'$FILELIST','');
       Replace(cmdstr,'$STATIC',StaticStr);
       Replace(cmdstr,'$STRIP',StripStr);
       Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
    @@ -807,14 +837,20 @@
          not(cs_link_nolink in current_settings.globalswitches) then
         begin
           { we have to use a script to use the IFS hack }
    +      {$ifndef MSWINDOWS}
           linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
    +      {$else}
    +      linkscript:=TAsmScriptDos.create(outputexedir+'ppaslink');
    +      {$endif}
           linkscript.AddLinkCommand(BinStr,CmdStr,'');
           if (extdbgcmdstr<>'') then
             linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
           linkscript.WriteToDisk;
           BinStr:=linkscript.fn;
    +      {$ifndef MSWINDOWS}
           if not path_absolute(BinStr) then
             BinStr:='./'+BinStr;
    +      {$endif}
           CmdStr:='';
         end;
     
    @@ -836,6 +872,9 @@
            end;
        end;
     
    +  { Remove linkfiles.res }
    +  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
    +
       MakeExecutable:=success;   { otherwise a recursive call to link method }
     end;
     
    @@ -902,6 +941,9 @@
       Replace(cmdstr,'$TARGET',targetstr);
       Replace(cmdstr,'$EMUL',EmulStr);
       Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
    +  if LdSupportsNoResponseFile
    +     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
    +     else Replace(cmdstr,'$FILELIST','');
       Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
       Replace(cmdstr,'$INIT',InitStr);
       Replace(cmdstr,'$FINI',FiniStr);
    @@ -941,14 +983,20 @@
          not(cs_link_nolink in current_settings.globalswitches) then
         begin
           { we have to use a script to use the IFS hack }
    +      {$ifndef MSWINDOWS}
           linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
    +      {$else}
    +      linkscript:=TAsmScriptDos.create(outputexedir+'ppaslink');
    +      {$endif}
           linkscript.AddLinkCommand(BinStr,CmdStr,'');
           if (extdbgbinstr<>'') then
             linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
           linkscript.WriteToDisk;
           BinStr:=linkscript.fn;
    +      {$ifndef MSWINDOWS}
           if not path_absolute(BinStr) then
             BinStr:='./'+BinStr;
    +      {$endif}
           CmdStr:='';
         end;
     
    @@ -979,6 +1027,9 @@
             DeleteFile(outputexedir+'linksyms.fpc');
         end;
     
    +  { Remove linkfiles.res }
    +  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
    +
       MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
     end;
     
    
    crossdarwinnew.patch (6,884 bytes)
  • crossdarwinnewer.patch (6,960 bytes)
    Index: compiler/systems/t_bsd.pas
    ===================================================================
    --- compiler/systems/t_bsd.pas	(revision 35106)
    +++ compiler/systems/t_bsd.pas	(working copy)
    @@ -147,8 +147,8 @@
            begin
              if not(target_info.system in systems_darwin) then
                begin
    -             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';
    -             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'
    +             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES $FILELIST ';
    +             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES $FILELIST'
                end
              else
                begin
    @@ -167,16 +167,16 @@
                    programs with problems that require Valgrind will have more
                    than 60KB of data (first 4KB of address space is always invalid)
                  }
    -               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
    +               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
                  if not(cs_gdb_valgrind in current_settings.globalswitches) then
                    ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
     {$else ndef cpu64bitaddr}
    -             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
    +             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
     {$endif ndef cpu64bitaddr}
                  if (apptype<>app_bundle) then
    -               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'
    +               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
                  else
    -               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'
    +               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
                end
            end
          else
    @@ -388,6 +388,7 @@
     Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
     Var
       linkres      : TLinkRes;
    +  FilesList    : TLinkRes;
       i            : longint;
       cprtobj,
       gprtobj,
    @@ -589,15 +590,37 @@
                  LinkRes.AddFileName(s);
        end;
       { main objectfiles }
    +
    +  { Generate linkfiles.res file if needed }
    +  { Always needed on Windows, due to the limitation of 8196 characters for command line }
    +  { linkfiles.res will be piped if possible }
    +  if LdSupportsNoResponseFile then
    +   begin
    +     FilesList:=TLinkRes.Create(outputexedir+'linkfiles.res',not LdSupportsNoResponseFile);
       while not ObjectFiles.Empty do
        begin
          s:=ObjectFiles.GetFirst;
          if s<>'' then
    -      if LdSupportsNoResponseFile then
    -        LinkRes.AddFileName(s)
    +         begin
    +           repeat
    +            i:=Pos(source_info.dirsep,s);
    +            if i>0 then s[i]:=target_info.dirsep;
    +           until i=0;
    +           FilesList.Add(s);
    +         end;
    +      end;
    +     FilesList.writetodisk;
    +     FilesList.Free;
    +   end
           else
    -        LinkRes.AddFileName(maybequoted(s));
    +   begin
    +     while not ObjectFiles.Empty do
    +      begin
    +        s:=ObjectFiles.GetFirst;
    +        if s<>'' then LinkRes.AddFileName(maybequoted(s));
        end;
    +   end;
    +
       if not LdSupportsNoResponseFile then
        LinkRes.Add(')');
     
    @@ -784,6 +807,9 @@
       Replace(cmdstr,'$EMUL',EmulStr);
       Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
       Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
    +  if LdSupportsNoResponseFile
    +     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
    +     else Replace(cmdstr,'$FILELIST','');
       Replace(cmdstr,'$STATIC',StaticStr);
       Replace(cmdstr,'$STRIP',StripStr);
       Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
    @@ -807,14 +833,17 @@
          not(cs_link_nolink in current_settings.globalswitches) then
         begin
           { we have to use a script to use the IFS hack }
    -      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
    +      linkscript:=GenerateScript(outputexedir+'ppaslink');
           linkscript.AddLinkCommand(BinStr,CmdStr,'');
           if (extdbgcmdstr<>'') then
             linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
           linkscript.WriteToDisk;
           BinStr:=linkscript.fn;
           if not path_absolute(BinStr) then
    -        BinStr:='./'+BinStr;
    +        if cs_link_on_target in current_settings.globalswitches then
    +          BinStr:='.'+target_info.dirsep+BinStr
    +        else
    +          BinStr:='.'+source_info.dirsep+BinStr;
           CmdStr:='';
         end;
     
    @@ -836,6 +865,9 @@
            end;
        end;
     
    +  { Remove linkfiles.res }
    +  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
    +
       MakeExecutable:=success;   { otherwise a recursive call to link method }
     end;
     
    @@ -902,6 +934,9 @@
       Replace(cmdstr,'$TARGET',targetstr);
       Replace(cmdstr,'$EMUL',EmulStr);
       Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
    +  if LdSupportsNoResponseFile
    +     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
    +     else Replace(cmdstr,'$FILELIST','');
       Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
       Replace(cmdstr,'$INIT',InitStr);
       Replace(cmdstr,'$FINI',FiniStr);
    @@ -941,14 +976,17 @@
          not(cs_link_nolink in current_settings.globalswitches) then
         begin
           { we have to use a script to use the IFS hack }
    -      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
    +      linkscript:=GenerateScript(outputexedir+'ppaslink');
           linkscript.AddLinkCommand(BinStr,CmdStr,'');
           if (extdbgbinstr<>'') then
             linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
           linkscript.WriteToDisk;
           BinStr:=linkscript.fn;
           if not path_absolute(BinStr) then
    -        BinStr:='./'+BinStr;
    +        if cs_link_on_target in current_settings.globalswitches then
    +          BinStr:='.'+target_info.dirsep+BinStr
    +        else
    +          BinStr:='.'+source_info.dirsep+BinStr;
           CmdStr:='';
         end;
     
    @@ -979,6 +1017,9 @@
             DeleteFile(outputexedir+'linksyms.fpc');
         end;
     
    +  { Remove linkfiles.res }
    +  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
    +
       MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
     end;
     
    
    crossdarwinnewer.patch (6,960 bytes)
  • crossdarwinnewest.patch (7,203 bytes)
    Index: compiler/systems/t_bsd.pas
    ===================================================================
    --- compiler/systems/t_bsd.pas	(revision 36160)
    +++ compiler/systems/t_bsd.pas	(working copy)
    @@ -147,8 +147,8 @@
            begin
              if not(target_info.system in systems_darwin) then
                begin
    -             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';
    -             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'
    +             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES $FILELIST ';
    +             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES $FILELIST'
                end
              else
                begin
    @@ -167,16 +167,16 @@
                    programs with problems that require Valgrind will have more
                    than 60KB of data (first 4KB of address space is always invalid)
                  }
    -               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
    +               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
                  if not(cs_gdb_valgrind in current_settings.globalswitches) then
                    ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
     {$else ndef cpu64bitaddr}
    -             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
    +             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
     {$endif ndef cpu64bitaddr}
                  if (apptype<>app_bundle) then
    -               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'
    +               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
                  else
    -               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'
    +               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
                end
            end
          else
    @@ -388,6 +388,7 @@
     Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
     Var
       linkres      : TLinkRes;
    +  FilesList    : TLinkRes;
       i            : longint;
       cprtobj,
       gprtobj,
    @@ -588,16 +589,42 @@
              else if librarysearchpath.FindFile('crtbegin.o',false,s) then
                  LinkRes.AddFileName(s);
        end;
    +
       { main objectfiles }
    +
    +  { Generate linkfiles.res file if needed }
    +  { Only needed on Windows, due to the limitation of 8196 characters for command line }
    +  if (LdSupportsNoResponseFile) AND (source_info.system in systems_all_windows) then
    +   begin
    +     FilesList:=TLinkRes.Create(outputexedir+'linkfiles.res',false);
       while not ObjectFiles.Empty do
        begin
          s:=ObjectFiles.GetFirst;
          if s<>'' then
    +         begin
    +           repeat
    +             i:=Pos(source_info.dirsep,s);
    +             if i>0 then s[i]:=target_info.dirsep;
    +           until i=0;
    +           FilesList.Add(s);
    +         end;
    +      end;
    +     FilesList.writetodisk;
    +     FilesList.Free;
    +   end
    +  else
    +   begin
    +     while not ObjectFiles.Empty do
    +      begin
    +        s:=ObjectFiles.GetFirst;
    +        if s<>'' then
           if LdSupportsNoResponseFile then
             LinkRes.AddFileName(s)
           else
             LinkRes.AddFileName(maybequoted(s));
        end;
    +   end;
    +
       if not LdSupportsNoResponseFile then
        LinkRes.Add(')');
     
    @@ -784,6 +811,10 @@
       Replace(cmdstr,'$EMUL',EmulStr);
       Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
       Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
    +  if (LdSupportsNoResponseFile) AND (source_info.system in systems_all_windows) then
    +    Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
    +  else
    +    Replace(cmdstr,'$FILELIST','');
       Replace(cmdstr,'$STATIC',StaticStr);
       Replace(cmdstr,'$STRIP',StripStr);
       Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
    @@ -807,14 +838,17 @@
          not(cs_link_nolink in current_settings.globalswitches) then
         begin
           { we have to use a script to use the IFS hack }
    -      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
    +      linkscript:=GenerateScript(outputexedir+'ppaslink');
           linkscript.AddLinkCommand(BinStr,CmdStr,'');
           if (extdbgcmdstr<>'') then
             linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
           linkscript.WriteToDisk;
           BinStr:=linkscript.fn;
           if not path_absolute(BinStr) then
    -        BinStr:='./'+BinStr;
    +        if cs_link_on_target in current_settings.globalswitches then
    +          BinStr:='.'+target_info.dirsep+BinStr
    +        else
    +          BinStr:='.'+source_info.dirsep+BinStr;
           CmdStr:='';
         end;
     
    @@ -836,6 +870,10 @@
            end;
        end;
     
    +  { Remove linkfiles.res }
    +  if (success) and (LdSupportsNoResponseFile) and (source_info.system in systems_all_windows) then
    +    DeleteFile(outputexedir+'linkfiles.res');
    +
       MakeExecutable:=success;   { otherwise a recursive call to link method }
     end;
     
    @@ -902,6 +940,10 @@
       Replace(cmdstr,'$TARGET',targetstr);
       Replace(cmdstr,'$EMUL',EmulStr);
       Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
    +  if (LdSupportsNoResponseFile) AND (source_info.system in systems_all_windows) then
    +    Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
    +  else
    +    Replace(cmdstr,'$FILELIST','');
       Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
       Replace(cmdstr,'$INIT',InitStr);
       Replace(cmdstr,'$FINI',FiniStr);
    @@ -941,14 +983,17 @@
          not(cs_link_nolink in current_settings.globalswitches) then
         begin
           { we have to use a script to use the IFS hack }
    -      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
    +      linkscript:=GenerateScript(outputexedir+'ppaslink');
           linkscript.AddLinkCommand(BinStr,CmdStr,'');
           if (extdbgbinstr<>'') then
             linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
           linkscript.WriteToDisk;
           BinStr:=linkscript.fn;
           if not path_absolute(BinStr) then
    -        BinStr:='./'+BinStr;
    +        if cs_link_on_target in current_settings.globalswitches then
    +          BinStr:='.'+target_info.dirsep+BinStr
    +        else
    +          BinStr:='.'+source_info.dirsep+BinStr;
           CmdStr:='';
         end;
     
    @@ -979,6 +1024,10 @@
             DeleteFile(outputexedir+'linksyms.fpc');
         end;
     
    +  { Remove linkfiles.res }
    +  if (success) and (LdSupportsNoResponseFile) and (source_info.system in systems_all_windows) then
    +    DeleteFile(outputexedir+'linkfiles.res');
    +
       MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
     end;
     
    
    crossdarwinnewest.patch (7,203 bytes)

Relationships

has duplicate 0029114 closedJonas Maebe crosscompile: building crosscompilator for i386 darwin fails 
related to 0035743 resolvedJonas Maebe Windows compiler doesn't call CLANG to assemble compiled *.s files when target is i386-darwin 

Activities

Alfred

2016-12-11 09:41

reporter  

crossdarwin.patch (9,455 bytes)
Index: compiler/systems/t_bsd.pas
===================================================================
--- compiler/systems/t_bsd.pas	(revision 35099)
+++ compiler/systems/t_bsd.pas	(working copy)
@@ -147,8 +147,8 @@
        begin
          if not(target_info.system in systems_darwin) then
            begin
-             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';
-             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'
+             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES $FILELIST ';
+             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES $FILELIST'
            end
          else
            begin
@@ -167,16 +167,16 @@
                programs with problems that require Valgrind will have more
                than 60KB of data (first 4KB of address space is always invalid)
              }
-               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
+               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
              if not(cs_gdb_valgrind in current_settings.globalswitches) then
                ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
 {$else ndef cpu64bitaddr}
-             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
+             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
 {$endif ndef cpu64bitaddr}
              if (apptype<>app_bundle) then
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
              else
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
            end
        end
      else
@@ -388,6 +388,7 @@
 Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
 Var
   linkres      : TLinkRes;
+  FilesList    : TLinkRes;
   i            : longint;
   cprtobj,
   gprtobj,
@@ -589,15 +590,41 @@
              LinkRes.AddFileName(s);
    end;
   { main objectfiles }
+
+  { Generate linkfiles.res file if needed }
+  { Always needed on Windows, due to the limitation of 8196 characters for command line }
+  { linkfiles.res will be piped if possible }
+  if LdSupportsNoResponseFile then
+  begin
+    FilesList:=TLinkRes.Create(outputexedir+'linkfiles.res',not LdSupportsNoResponseFile);
   while not ObjectFiles.Empty do
    begin
      s:=ObjectFiles.GetFirst;
      if s<>'' then
-      if LdSupportsNoResponseFile then
-        LinkRes.AddFileName(s)
+      begin
+        {$ifdef MSWINDOWS}
+        // osxcross specific, but does no harm
+        // osxcross can only handle '/'
+        repeat
+          i:=Pos('\',s);
+          if i>0 then s[i]:='/';
+        until i=0;
+        {$ENDIF}
+        FilesList.Add(s);
+      end;
+    end;
+    FilesList.writetodisk;
+    FilesList.Free;
+  end
       else
-        LinkRes.AddFileName(maybequoted(s));
+  begin
+    while not ObjectFiles.Empty do
+    begin
+      s:=ObjectFiles.GetFirst;
+      if s<>'' then LinkRes.AddFileName(maybequoted(s));
    end;
+  end;
+
   if not LdSupportsNoResponseFile then
    LinkRes.Add(')');
 
@@ -784,6 +811,9 @@
   Replace(cmdstr,'$EMUL',EmulStr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+  if LdSupportsNoResponseFile
+     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
+     else Replace(cmdstr,'$FILELIST','');
   Replace(cmdstr,'$STATIC',StaticStr);
   Replace(cmdstr,'$STRIP',StripStr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
@@ -813,8 +843,10 @@
         linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
       linkscript.WriteToDisk;
       BinStr:=linkscript.fn;
+      {$ifndef MSWINDOWS}
       if not path_absolute(BinStr) then
         BinStr:='./'+BinStr;
+      {$endif}
       CmdStr:='';
     end;
 
@@ -836,6 +868,9 @@
        end;
    end;
 
+  { Remove linkfiles.res }
+  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
+
   MakeExecutable:=success;   { otherwise a recursive call to link method }
 end;
 
@@ -902,6 +937,9 @@
   Replace(cmdstr,'$TARGET',targetstr);
   Replace(cmdstr,'$EMUL',EmulStr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
+  if LdSupportsNoResponseFile
+     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
+     else Replace(cmdstr,'$FILELIST','');
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
   Replace(cmdstr,'$INIT',InitStr);
   Replace(cmdstr,'$FINI',FiniStr);
@@ -947,8 +985,10 @@
         linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
       linkscript.WriteToDisk;
       BinStr:=linkscript.fn;
+      {$ifndef MSWINDOWS}
       if not path_absolute(BinStr) then
         BinStr:='./'+BinStr;
+      {$endif}
       CmdStr:='';
     end;
 
@@ -979,6 +1019,9 @@
         DeleteFile(outputexedir+'linksyms.fpc');
     end;
 
+  { Remove linkfiles.res }
+  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
+
   MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
 end;
 
Index: compiler/script.pas
===================================================================
--- compiler/script.pas	(revision 35099)
+++ compiler/script.pas	(working copy)
@@ -236,7 +236,11 @@
      Add('echo Assembling %THEFILE%');
    end;
   Add(maybequoted(command)+' '+Options);
+  {$ifdef MSWINDOWS}
+  Add('if %ERRORLEVEL% EQU 1 goto asmend');
+  {$else}
   Add('if errorlevel 1 goto asmend');
+  {$endif}
 end;
 
 
@@ -248,7 +252,11 @@
      Add('echo Linking %THEFILE%');
    end;
   Add(maybequoted(command)+' '+Options);
+  {$ifdef MSWINDOWS}
+  Add('if %ERRORLEVEL% EQU 1 goto linkend');
+  {$else}
   Add('if errorlevel 1 goto linkend');
+  {$endif}
 end;
 
 
@@ -260,7 +268,11 @@
 
 Procedure TAsmScriptDos.AddDeleteDirCommand (Const FileName : TCmdStr);
 begin
+ {$ifdef MSWINDOWS}
+ Add('RMDIR /S /Q ' + MaybeQuoted (ScriptFixFileName (FileName)));
+ {$else}
  Add('Rmdir ' + MaybeQuoted (ScriptFixFileName (FileName)));
+ {$endif}
 end;
 
 
@@ -361,7 +373,11 @@
   if FileName<>'' then
    Add('echo Assembling '+ScriptFixFileName(FileName));
   Add(maybequoted(command)+' '+Options);
+  {$ifdef MSWINDOWS}
+  Add('if %ERRORLEVEL% NEQ 0 call:DoExitAsm '+ScriptFixFileName(FileName));
+  {$else}
   Add('if [ $? != 0 ]; then DoExitAsm '+ScriptFixFileName(FileName)+'; fi');
+  {$endif}
 end;
 
 
@@ -369,12 +385,18 @@
 begin
   if FileName<>'' then
    Add('echo Linking '+ScriptFixFileName(FileName));
+  {$ifndef MSWINDOWS}
   Add('OFS=$IFS');
   Add('IFS="');
   Add('"');
+  {$endif}
   Add(maybequoted(command)+' '+Options);
+  {$ifndef MSWINDOWS}
   Add('if [ $? != 0 ]; then DoExitLink '+ScriptFixFileName(FileName)+'; fi');
   Add('IFS=$OFS');
+  {$else}
+  Add('if %ERRORLEVEL% NEQ 0 call:DoExitLink '+ScriptFixFileName(FileName));
+  {$endif}
 end;
 
 
@@ -386,12 +408,26 @@
 
 Procedure TAsmScriptUnix.AddDeleteDirCommand (Const FileName : TCmdStr);
 begin
+ {$ifdef MSWINDOWS}
+  Add('RMDIR /S /Q ' + MaybeQuoted (ScriptFixFileName(FileName)));
+ {$else}
  Add('rmdir ' + MaybeQuoted (ScriptFixFileName(FileName)));
+ {$endif}
+
 end;
 
 
 Procedure TAsmScriptUnix.WriteToDisk;
 Begin
+  {$ifdef MSWINDOWS}
+  Add('EXIT /B %ERRORLEVEL%');
+  Add(':DoExitLink');
+  Add('echo An error occurred while linking %*');
+  Add('EXIT /B 1');
+  Add(':DoExitAsm');
+  Add('echo An error occurred while assembling %*');
+  Add('EXIT /B 1');
+  {$else}
   AddStart('{ echo "An error occurred while linking $1"; exit 1; }');
   AddStart('DoExitLink ()');
   AddStart('{ echo "An error occurred while assembling $1"; exit 1; }');
@@ -401,6 +437,7 @@
   {$else}
    AddStart('#!/bin/sh');
   {$endif}
+  {$endif}
   inherited WriteToDisk;
 end;
 
@@ -420,7 +457,9 @@
   if FileName<>'' then
     Add('Echo Assembling '+ScriptFixFileName(FileName));
   Add(maybequoted(command)+' '+Options);
+  {$ifndef MSWINDOWS}
   Add('Exit If "{Status}" != 0');
+  {$endif}
 end;
 
 
@@ -429,6 +468,7 @@
   if FileName<>'' then
     Add('Echo Linking '+ScriptFixFileName(FileName));
   Add(maybequoted(command)+' '+Options);
+  {$ifndef MSWINDOWS}
   Add('Exit If "{Status}" != 0');
 
   {Add resources}
@@ -437,6 +477,7 @@
       Add('Rez -append "{RIncludes}"SIOW.r -o '+ ScriptFixFileName(FileName));
       Add('Exit If "{Status}" != 0');
     end;
+  {$endif}
 end;
 
 
crossdarwin.patch (9,455 bytes)

Tomas Hajny

2016-12-11 10:01

manager   ~0096675

Hi, all the IFNDEF MSWINDOWS conditions do not belong there. As you may have noticed, there are different TAsmScript descendants for different platforms. You should simply ensure using the right one in the particular cross-compiling case rather than mixing together syntax of Dos/Windows/OS/2 batch files and Unix shell scripts.

Alfred

2016-12-11 10:27

reporter   ~0096676

As you will know, the supplied patches show a way to get a working cross- environment. They have allowed me to test and use.
I have however no knowledge of the rules to make the correct changes into the compiler. This is how these patches are to be reviewed.

Its the same with the Darwin Makefile: I have shown a working makefile. But naturally, the real changes have to be made into another file, followed by a re-generation.

Tomas Hajny

2016-12-11 11:04

manager   ~0096677

Well, I tried to suggest what should be changed in the patch in order to make it usable for incorporation into the compiler.

If you only want to throw unfinished stuff for others to spend their time on finishing it, it may work only if somebody wants this functionality to become part of FPC strongly enough to spend his/her time on it. If you want to contribute your effort to FPC, I'm ready to help with clarifying unclear things as far as my available time allows it, and I'm sure the same is true for some other members of the FPC team. On the other hand, I don't use or have Darwin, so I couldn't modify _and_ test the patch myself even if I had enough motivation for spending time on that (actually, I don't have MS Windows on any of my own machines either, but that doesn't matter really). I hope that my comments provided clear directions on what to do in order to make the patch usable for FPC. If it isn't clear from the suggestions and current source, feel free to ask.

Jonas Maebe

2016-12-11 13:19

manager   ~0096682

Last edited: 2016-12-11 13:26

View 2 revisions

As Tomas explained, there is a difference between supplying a patch that performs the correct changes to the wrong file, and a patch that is fundamentally wrong (changes the wrong things in the wrong places). There are even no explanations at all how you came to the conclusion that this is the right approach, or why you made changes to the DOS/Windows script class even though compiling on Windows has worked fine for decades and the target OS should not influence the syntax of .bat files in any way.

In summary, this patch is not something that we can start to work with. You need to understand what the problem is (rather than just randomly changing things to address symptoms until you have something that seems to work for you), and at the very least find a solution that does not add any ifdef to script.pas.

For starters, you may want to make sure you are not trying to execute the compiler in a Cygwin environment and that you are not trying to executing Cygwin tools, because afaik that is not supported by the FPC Windows maintainers. I think that everything has to be MinGW.

Alfred

2016-12-11 13:21

reporter  

crossdarwinnew.patch (6,884 bytes)
Index: compiler/systems/t_bsd.pas
===================================================================
--- compiler/systems/t_bsd.pas	(revision 35106)
+++ compiler/systems/t_bsd.pas	(working copy)
@@ -147,8 +147,8 @@
        begin
          if not(target_info.system in systems_darwin) then
            begin
-             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';
-             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'
+             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES $FILELIST ';
+             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES $FILELIST'
            end
          else
            begin
@@ -167,16 +167,16 @@
                programs with problems that require Valgrind will have more
                than 60KB of data (first 4KB of address space is always invalid)
              }
-               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
+               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
              if not(cs_gdb_valgrind in current_settings.globalswitches) then
                ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
 {$else ndef cpu64bitaddr}
-             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
+             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
 {$endif ndef cpu64bitaddr}
              if (apptype<>app_bundle) then
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
              else
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
            end
        end
      else
@@ -388,6 +388,7 @@
 Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
 Var
   linkres      : TLinkRes;
+  FilesList    : TLinkRes;
   i            : longint;
   cprtobj,
   gprtobj,
@@ -589,15 +590,41 @@
              LinkRes.AddFileName(s);
    end;
   { main objectfiles }
+
+  { Generate linkfiles.res file if needed }
+  { Always needed on Windows, due to the limitation of 8196 characters for command line }
+  { linkfiles.res will be piped if possible }
+  if LdSupportsNoResponseFile then
+  begin
+    FilesList:=TLinkRes.Create(outputexedir+'linkfiles.res',not LdSupportsNoResponseFile);
   while not ObjectFiles.Empty do
    begin
      s:=ObjectFiles.GetFirst;
      if s<>'' then
-      if LdSupportsNoResponseFile then
-        LinkRes.AddFileName(s)
+      begin
+        {$ifdef MSWINDOWS}
+        // osxcross specific, but does no harm
+        // osxcross can only handle '/'
+        repeat
+          i:=Pos('\',s);
+          if i>0 then s[i]:='/';
+        until i=0;
+        {$ENDIF}
+        FilesList.Add(s);
+      end;
+    end;
+    FilesList.writetodisk;
+    FilesList.Free;
+  end
       else
-        LinkRes.AddFileName(maybequoted(s));
+  begin
+    while not ObjectFiles.Empty do
+    begin
+      s:=ObjectFiles.GetFirst;
+      if s<>'' then LinkRes.AddFileName(maybequoted(s));
    end;
+  end;
+
   if not LdSupportsNoResponseFile then
    LinkRes.Add(')');
 
@@ -784,6 +811,9 @@
   Replace(cmdstr,'$EMUL',EmulStr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+  if LdSupportsNoResponseFile
+     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
+     else Replace(cmdstr,'$FILELIST','');
   Replace(cmdstr,'$STATIC',StaticStr);
   Replace(cmdstr,'$STRIP',StripStr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
@@ -807,14 +837,20 @@
      not(cs_link_nolink in current_settings.globalswitches) then
     begin
       { we have to use a script to use the IFS hack }
+      {$ifndef MSWINDOWS}
       linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
+      {$else}
+      linkscript:=TAsmScriptDos.create(outputexedir+'ppaslink');
+      {$endif}
       linkscript.AddLinkCommand(BinStr,CmdStr,'');
       if (extdbgcmdstr<>'') then
         linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
       linkscript.WriteToDisk;
       BinStr:=linkscript.fn;
+      {$ifndef MSWINDOWS}
       if not path_absolute(BinStr) then
         BinStr:='./'+BinStr;
+      {$endif}
       CmdStr:='';
     end;
 
@@ -836,6 +872,9 @@
        end;
    end;
 
+  { Remove linkfiles.res }
+  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
+
   MakeExecutable:=success;   { otherwise a recursive call to link method }
 end;
 
@@ -902,6 +941,9 @@
   Replace(cmdstr,'$TARGET',targetstr);
   Replace(cmdstr,'$EMUL',EmulStr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
+  if LdSupportsNoResponseFile
+     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
+     else Replace(cmdstr,'$FILELIST','');
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
   Replace(cmdstr,'$INIT',InitStr);
   Replace(cmdstr,'$FINI',FiniStr);
@@ -941,14 +983,20 @@
      not(cs_link_nolink in current_settings.globalswitches) then
     begin
       { we have to use a script to use the IFS hack }
+      {$ifndef MSWINDOWS}
       linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
+      {$else}
+      linkscript:=TAsmScriptDos.create(outputexedir+'ppaslink');
+      {$endif}
       linkscript.AddLinkCommand(BinStr,CmdStr,'');
       if (extdbgbinstr<>'') then
         linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
       linkscript.WriteToDisk;
       BinStr:=linkscript.fn;
+      {$ifndef MSWINDOWS}
       if not path_absolute(BinStr) then
         BinStr:='./'+BinStr;
+      {$endif}
       CmdStr:='';
     end;
 
@@ -979,6 +1027,9 @@
         DeleteFile(outputexedir+'linksyms.fpc');
     end;
 
+  { Remove linkfiles.res }
+  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
+
   MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
 end;
 
crossdarwinnew.patch (6,884 bytes)

Alfred

2016-12-11 13:27

reporter   ~0096684

New patch. Using correct linker script. No changes anymore to script.pas
Cleaner ? Better ?

About cycwin and mingw.
Osxcross has been made suitable for cygwin.
I am busy with osxcross changes for mingw (msys2).

Jonas Maebe

2016-12-11 13:47

manager   ~0096686

Yes, it's better. Some improvements that are still needed:
* all the {$if(n)def mswindows} must disappear from t_bsd. The compiler can both generate scripts to run on the host or the target OS (-sh and -st command line parameters), so you cannot use an ifdef based on the host OS to decide how to generate your scripts. E.g. use GenerateScript() (script unit) instead of ifdefs to decide which tscript class to instantiate. There are also many helpers in the cfilutil unit that you can use.
* your indentation is wrong, please follow the indentation of surrounding code (e.g. you have to indent "begin" after "while", and you need a newline after "then" and "else")

Alfred

2016-12-12 09:19

reporter  

crossdarwinnewer.patch (6,960 bytes)
Index: compiler/systems/t_bsd.pas
===================================================================
--- compiler/systems/t_bsd.pas	(revision 35106)
+++ compiler/systems/t_bsd.pas	(working copy)
@@ -147,8 +147,8 @@
        begin
          if not(target_info.system in systems_darwin) then
            begin
-             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';
-             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'
+             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES $FILELIST ';
+             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES $FILELIST'
            end
          else
            begin
@@ -167,16 +167,16 @@
                programs with problems that require Valgrind will have more
                than 60KB of data (first 4KB of address space is always invalid)
              }
-               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
+               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
              if not(cs_gdb_valgrind in current_settings.globalswitches) then
                ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
 {$else ndef cpu64bitaddr}
-             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
+             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
 {$endif ndef cpu64bitaddr}
              if (apptype<>app_bundle) then
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
              else
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
            end
        end
      else
@@ -388,6 +388,7 @@
 Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
 Var
   linkres      : TLinkRes;
+  FilesList    : TLinkRes;
   i            : longint;
   cprtobj,
   gprtobj,
@@ -589,15 +590,37 @@
              LinkRes.AddFileName(s);
    end;
   { main objectfiles }
+
+  { Generate linkfiles.res file if needed }
+  { Always needed on Windows, due to the limitation of 8196 characters for command line }
+  { linkfiles.res will be piped if possible }
+  if LdSupportsNoResponseFile then
+   begin
+     FilesList:=TLinkRes.Create(outputexedir+'linkfiles.res',not LdSupportsNoResponseFile);
   while not ObjectFiles.Empty do
    begin
      s:=ObjectFiles.GetFirst;
      if s<>'' then
-      if LdSupportsNoResponseFile then
-        LinkRes.AddFileName(s)
+         begin
+           repeat
+            i:=Pos(source_info.dirsep,s);
+            if i>0 then s[i]:=target_info.dirsep;
+           until i=0;
+           FilesList.Add(s);
+         end;
+      end;
+     FilesList.writetodisk;
+     FilesList.Free;
+   end
       else
-        LinkRes.AddFileName(maybequoted(s));
+   begin
+     while not ObjectFiles.Empty do
+      begin
+        s:=ObjectFiles.GetFirst;
+        if s<>'' then LinkRes.AddFileName(maybequoted(s));
    end;
+   end;
+
   if not LdSupportsNoResponseFile then
    LinkRes.Add(')');
 
@@ -784,6 +807,9 @@
   Replace(cmdstr,'$EMUL',EmulStr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+  if LdSupportsNoResponseFile
+     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
+     else Replace(cmdstr,'$FILELIST','');
   Replace(cmdstr,'$STATIC',StaticStr);
   Replace(cmdstr,'$STRIP',StripStr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
@@ -807,14 +833,17 @@
      not(cs_link_nolink in current_settings.globalswitches) then
     begin
       { we have to use a script to use the IFS hack }
-      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
+      linkscript:=GenerateScript(outputexedir+'ppaslink');
       linkscript.AddLinkCommand(BinStr,CmdStr,'');
       if (extdbgcmdstr<>'') then
         linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
       linkscript.WriteToDisk;
       BinStr:=linkscript.fn;
       if not path_absolute(BinStr) then
-        BinStr:='./'+BinStr;
+        if cs_link_on_target in current_settings.globalswitches then
+          BinStr:='.'+target_info.dirsep+BinStr
+        else
+          BinStr:='.'+source_info.dirsep+BinStr;
       CmdStr:='';
     end;
 
@@ -836,6 +865,9 @@
        end;
    end;
 
+  { Remove linkfiles.res }
+  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
+
   MakeExecutable:=success;   { otherwise a recursive call to link method }
 end;
 
@@ -902,6 +934,9 @@
   Replace(cmdstr,'$TARGET',targetstr);
   Replace(cmdstr,'$EMUL',EmulStr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
+  if LdSupportsNoResponseFile
+     then Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
+     else Replace(cmdstr,'$FILELIST','');
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
   Replace(cmdstr,'$INIT',InitStr);
   Replace(cmdstr,'$FINI',FiniStr);
@@ -941,14 +976,17 @@
      not(cs_link_nolink in current_settings.globalswitches) then
     begin
       { we have to use a script to use the IFS hack }
-      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
+      linkscript:=GenerateScript(outputexedir+'ppaslink');
       linkscript.AddLinkCommand(BinStr,CmdStr,'');
       if (extdbgbinstr<>'') then
         linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
       linkscript.WriteToDisk;
       BinStr:=linkscript.fn;
       if not path_absolute(BinStr) then
-        BinStr:='./'+BinStr;
+        if cs_link_on_target in current_settings.globalswitches then
+          BinStr:='.'+target_info.dirsep+BinStr
+        else
+          BinStr:='.'+source_info.dirsep+BinStr;
       CmdStr:='';
     end;
 
@@ -979,6 +1017,9 @@
         DeleteFile(outputexedir+'linksyms.fpc');
     end;
 
+  { Remove linkfiles.res }
+  if (success) and (LdSupportsNoResponseFile) then DeleteFile(outputexedir+'linkfiles.res');
+
   MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
 end;
 
crossdarwinnewer.patch (6,960 bytes)

Alfred

2016-12-12 09:20

reporter   ~0096715

New patch attached. No switches anymore. Even adjusted indentation.
No regressions detected.

Alfred

2017-03-15 08:18

reporter   ~0098913

May I ask for info about this patch.

It has been in use for some time now (NewPascal) without any regressions reported. Does it need some more changes before inclusion, or are there other problems ?

Thanks.

Alfred

2017-05-09 19:08

reporter  

crossdarwinnewest.patch (7,203 bytes)
Index: compiler/systems/t_bsd.pas
===================================================================
--- compiler/systems/t_bsd.pas	(revision 36160)
+++ compiler/systems/t_bsd.pas	(working copy)
@@ -147,8 +147,8 @@
        begin
          if not(target_info.system in systems_darwin) then
            begin
-             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';
-             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'
+             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES $FILELIST ';
+             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES $FILELIST'
            end
          else
            begin
@@ -167,16 +167,16 @@
                programs with problems that require Valgrind will have more
                than 60KB of data (first 4KB of address space is always invalid)
              }
-               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
+               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
              if not(cs_gdb_valgrind in current_settings.globalswitches) then
                ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
 {$else ndef cpu64bitaddr}
-             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';
+             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
 {$endif ndef cpu64bitaddr}
              if (apptype<>app_bundle) then
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
              else
-               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'
+               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
            end
        end
      else
@@ -388,6 +388,7 @@
 Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
 Var
   linkres      : TLinkRes;
+  FilesList    : TLinkRes;
   i            : longint;
   cprtobj,
   gprtobj,
@@ -588,16 +589,42 @@
          else if librarysearchpath.FindFile('crtbegin.o',false,s) then
              LinkRes.AddFileName(s);
    end;
+
   { main objectfiles }
+
+  { Generate linkfiles.res file if needed }
+  { Only needed on Windows, due to the limitation of 8196 characters for command line }
+  if (LdSupportsNoResponseFile) AND (source_info.system in systems_all_windows) then
+   begin
+     FilesList:=TLinkRes.Create(outputexedir+'linkfiles.res',false);
   while not ObjectFiles.Empty do
    begin
      s:=ObjectFiles.GetFirst;
      if s<>'' then
+         begin
+           repeat
+             i:=Pos(source_info.dirsep,s);
+             if i>0 then s[i]:=target_info.dirsep;
+           until i=0;
+           FilesList.Add(s);
+         end;
+      end;
+     FilesList.writetodisk;
+     FilesList.Free;
+   end
+  else
+   begin
+     while not ObjectFiles.Empty do
+      begin
+        s:=ObjectFiles.GetFirst;
+        if s<>'' then
       if LdSupportsNoResponseFile then
         LinkRes.AddFileName(s)
       else
         LinkRes.AddFileName(maybequoted(s));
    end;
+   end;
+
   if not LdSupportsNoResponseFile then
    LinkRes.Add(')');
 
@@ -784,6 +811,10 @@
   Replace(cmdstr,'$EMUL',EmulStr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+  if (LdSupportsNoResponseFile) AND (source_info.system in systems_all_windows) then
+    Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
+  else
+    Replace(cmdstr,'$FILELIST','');
   Replace(cmdstr,'$STATIC',StaticStr);
   Replace(cmdstr,'$STRIP',StripStr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
@@ -807,14 +838,17 @@
      not(cs_link_nolink in current_settings.globalswitches) then
     begin
       { we have to use a script to use the IFS hack }
-      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
+      linkscript:=GenerateScript(outputexedir+'ppaslink');
       linkscript.AddLinkCommand(BinStr,CmdStr,'');
       if (extdbgcmdstr<>'') then
         linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
       linkscript.WriteToDisk;
       BinStr:=linkscript.fn;
       if not path_absolute(BinStr) then
-        BinStr:='./'+BinStr;
+        if cs_link_on_target in current_settings.globalswitches then
+          BinStr:='.'+target_info.dirsep+BinStr
+        else
+          BinStr:='.'+source_info.dirsep+BinStr;
       CmdStr:='';
     end;
 
@@ -836,6 +870,10 @@
        end;
    end;
 
+  { Remove linkfiles.res }
+  if (success) and (LdSupportsNoResponseFile) and (source_info.system in systems_all_windows) then
+    DeleteFile(outputexedir+'linkfiles.res');
+
   MakeExecutable:=success;   { otherwise a recursive call to link method }
 end;
 
@@ -902,6 +940,10 @@
   Replace(cmdstr,'$TARGET',targetstr);
   Replace(cmdstr,'$EMUL',EmulStr);
   Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
+  if (LdSupportsNoResponseFile) AND (source_info.system in systems_all_windows) then
+    Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+'linkfiles.res'))
+  else
+    Replace(cmdstr,'$FILELIST','');
   Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
   Replace(cmdstr,'$INIT',InitStr);
   Replace(cmdstr,'$FINI',FiniStr);
@@ -941,14 +983,17 @@
      not(cs_link_nolink in current_settings.globalswitches) then
     begin
       { we have to use a script to use the IFS hack }
-      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');
+      linkscript:=GenerateScript(outputexedir+'ppaslink');
       linkscript.AddLinkCommand(BinStr,CmdStr,'');
       if (extdbgbinstr<>'') then
         linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
       linkscript.WriteToDisk;
       BinStr:=linkscript.fn;
       if not path_absolute(BinStr) then
-        BinStr:='./'+BinStr;
+        if cs_link_on_target in current_settings.globalswitches then
+          BinStr:='.'+target_info.dirsep+BinStr
+        else
+          BinStr:='.'+source_info.dirsep+BinStr;
       CmdStr:='';
     end;
 
@@ -979,6 +1024,10 @@
         DeleteFile(outputexedir+'linksyms.fpc');
     end;
 
+  { Remove linkfiles.res }
+  if (success) and (LdSupportsNoResponseFile) and (source_info.system in systems_all_windows) then
+    DeleteFile(outputexedir+'linkfiles.res');
+
   MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
 end;
 
crossdarwinnewest.patch (7,203 bytes)

Alfred

2017-05-09 19:11

reporter   ~0100178

Uploaded a new patch.
Link filelist will only be created on Windows, if needed.
Regression test done on Darwin, Linux, FreeBSD, Windows.
Cross-compiling (still) working for:
Windows>Darwin
Windows>FreeBSD
Linux>Darwin
Linux>FreeBSD

Maciej Izak

2017-05-10 09:54

reporter   ~0100188

Accepted with minor changes. Thanks!

Issue History

Date Modified Username Field Change
2016-12-11 09:41 Alfred New Issue
2016-12-11 09:41 Alfred File Added: crossdarwin.patch
2016-12-11 10:01 Tomas Hajny Note Added: 0096675
2016-12-11 10:27 Alfred Note Added: 0096676
2016-12-11 11:04 Tomas Hajny Note Added: 0096677
2016-12-11 13:19 Jonas Maebe Note Added: 0096682
2016-12-11 13:21 Alfred File Added: crossdarwinnew.patch
2016-12-11 13:26 Jonas Maebe Note Edited: 0096682 View Revisions
2016-12-11 13:27 Alfred Note Added: 0096684
2016-12-11 13:47 Jonas Maebe Note Added: 0096686
2016-12-12 09:19 Alfred File Added: crossdarwinnewer.patch
2016-12-12 09:20 Alfred Note Added: 0096715
2017-03-15 08:18 Alfred Note Added: 0098913
2017-05-09 19:08 Alfred File Added: crossdarwinnewest.patch
2017-05-09 19:11 Alfred Note Added: 0100178
2017-05-10 09:54 Maciej Izak Fixed in Revision => 36168
2017-05-10 09:54 Maciej Izak Note Added: 0100188
2017-05-10 09:54 Maciej Izak Status new => resolved
2017-05-10 09:54 Maciej Izak Resolution open => fixed
2017-05-10 09:54 Maciej Izak Assigned To => Maciej Izak
2017-12-31 16:22 Jonas Maebe Relationship added has duplicate 0029114
2019-06-21 18:20 Jonas Maebe Relationship added related to 0035743