浏览代码

Extract linker script generation as separate method. Check if esp linker scripts can be found in library paths, if not then generate scritps.

ccrause 3 年之前
父节点
当前提交
f66dd54bc2
共有 1 个文件被更改,包括 104 次插入70 次删除
  1. 104 70
      compiler/systems/t_freertos.pas

+ 104 - 70
compiler/systems/t_freertos.pas

@@ -39,6 +39,9 @@ implementation
        TlinkerFreeRTOS=class(texternallinker)
        TlinkerFreeRTOS=class(texternallinker)
        private
        private
           Function  WriteResponseFile: Boolean;
           Function  WriteResponseFile: Boolean;
+{$ifdef XTENSA}
+          procedure GenerateDefaultLinkerScripts(out out_ld_filename,project_ld_filename: AnsiString);
+{$endif XTENSA}
        public
        public
           constructor Create; override;
           constructor Create; override;
           procedure SetDefaultInfo; override;
           procedure SetDefaultInfo; override;
@@ -51,7 +54,7 @@ implementation
                                   TlinkerEmbedded
                                   TlinkerEmbedded
 *****************************************************************************}
 *****************************************************************************}
 
 
-Constructor TlinkerFreeRTOS.Create;
+constructor TlinkerFreeRTOS.Create;
 begin
 begin
   Inherited Create;
   Inherited Create;
   SharedLibFiles.doubles:=true;
   SharedLibFiles.doubles:=true;
@@ -75,7 +78,7 @@ begin
 end;
 end;
 
 
 
 
-Function TlinkerFreeRTOS.WriteResponseFile: Boolean;
+function TlinkerFreeRTOS.WriteResponseFile: Boolean;
 Var
 Var
   linkres  : TLinkRes;
   linkres  : TLinkRes;
   i        : longint;
   i        : longint;
@@ -938,46 +941,28 @@ begin
 
 
 end;
 end;
 
 
-
-function TlinkerFreeRTOS.MakeExecutable:boolean;
-var
-  StaticStr,
-  binstr,
-  cmdstr,
-  mapstr: Ansistring;
-  success : boolean;
-  GCSectionsStr,
-  DynLinkStr,
-  StripStr,
-  FixedExeFileName: string;
 {$ifdef XTENSA}
 {$ifdef XTENSA}
+{ If espX.project.ld or espX_out.ld scripts cannot be located, generate
+  default scripts so that linking can proceed.  Note: the generated
+  scripts may not match the actual options chosen when the libraries
+  were built. }
+procedure TlinkerFreeRTOS.GenerateDefaultLinkerScripts(out out_ld_filename,
+  project_ld_filename: AnsiString);
+var
   S: Ansistring;
   S: Ansistring;
   t: Text;
   t: Text;
   hp: TCmdStrListItem;
   hp: TCmdStrListItem;
-  filepath: TCmdStr;
+  filepath: TCmdStr = '';
   i,j: integer;
   i,j: integer;
-  lib: AnsiString;
-{$endif XTENSA}
+  lib,
+  binstr,
+  cmdstr: AnsiString;
+  success: boolean;
 begin
 begin
-{$ifdef XTENSA}
-  { idfpath can be set by -Ff, else default to environment value of IDF_PATH }
-  if idfpath='' then
-    idfpath := trim(GetEnvironmentVariable('IDF_PATH'));
-  idfpath:=ExcludeTrailingBackslash(idfpath);
-{$endif XTENSA}
-
-  { for future use }
-  StaticStr:='';
-  StripStr:='';
-  mapstr:='';
-  DynLinkStr:='';
-
-  success:=true;
-  Result:=false;
-
-{$ifdef XTENSA}
   { generate a sdkconfig.h if none is provided,
   { generate a sdkconfig.h if none is provided,
-    only a few fields are provided to far }
+    only a few fields are provided to far.
+    Assume that if linker scripts are not located,
+    sdkconfig.h is also missing }
   Assign(t,outputexedir+'/sdkconfig.h');
   Assign(t,outputexedir+'/sdkconfig.h');
   {$push}{$I-}
   {$push}{$I-}
   Rewrite(t);
   Rewrite(t);
@@ -1190,44 +1175,93 @@ begin
     binstr:=binstr+source_info.exeext;
     binstr:=binstr+source_info.exeext;
   S:=FindUtil(utilsprefix+'objdump');
   S:=FindUtil(utilsprefix+'objdump');
   if (current_settings.controllertype = ct_esp32) then
   if (current_settings.controllertype = ct_esp32) then
-    cmdstr:={$ifndef UNIX}'$IDF_PATH/tools/ldgen/ldgen.py '+{$endif UNIX}
-            '--config $OUTPUT/sdkconfig '+
-            '--fragments $IDF_PATH/components/xtensa/linker.lf $IDF_PATH/components/soc/linker.lf $IDF_PATH/components/esp_event/linker.lf '+
-            '$IDF_PATH/components/spi_flash/linker.lf $IDF_PATH/components/esp_wifi/linker.lf $IDF_PATH/components/lwip/linker.lf '+
-            '$IDF_PATH/components/heap/linker.lf $IDF_PATH/components/esp_ringbuf/linker.lf $IDF_PATH/components/espcoredump/linker.lf $IDF_PATH/components/esp32/linker.lf '+
-            '$IDF_PATH/components/esp32/ld/esp32_fragments.lf $IDF_PATH/components/freertos/linker.lf $IDF_PATH/components/newlib/newlib.lf '+
-            '$IDF_PATH/components/esp_gdbstub/linker.lf '+
-            '--input $IDF_PATH/components/esp32/ld/esp32.project.ld.in '+
-            '--output $OUTPUT/esp32.project.ld '+
-            '--kconfig $IDF_PATH/Kconfig '+
-            '--env-file $OUTPUT/config.env '+
-            '--libraries-file $OUTPUT/ldgen_libraries '+
-            '--objdump '+S
+    begin
+      project_ld_filename:=outputexedir+'/esp32.project.ld';
+      cmdstr:={$ifndef UNIX}'$IDF_PATH/tools/ldgen/ldgen.py '+{$endif UNIX}
+              '--config $OUTPUT/sdkconfig '+
+              '--fragments $IDF_PATH/components/xtensa/linker.lf $IDF_PATH/components/soc/linker.lf $IDF_PATH/components/esp_event/linker.lf '+
+              '$IDF_PATH/components/spi_flash/linker.lf $IDF_PATH/components/esp_wifi/linker.lf $IDF_PATH/components/lwip/linker.lf '+
+              '$IDF_PATH/components/heap/linker.lf $IDF_PATH/components/esp_ringbuf/linker.lf $IDF_PATH/components/espcoredump/linker.lf $IDF_PATH/components/esp32/linker.lf '+
+              '$IDF_PATH/components/esp32/ld/esp32_fragments.lf $IDF_PATH/components/freertos/linker.lf $IDF_PATH/components/newlib/newlib.lf '+
+              '$IDF_PATH/components/esp_gdbstub/linker.lf '+
+              '--input $IDF_PATH/components/esp32/ld/esp32.project.ld.in '+
+              '--output '+project_ld_filename+' '+
+              '--kconfig $IDF_PATH/Kconfig '+
+              '--env-file $OUTPUT/config.env '+
+              '--libraries-file $OUTPUT/ldgen_libraries '+
+              '--objdump '+S;
+    end
   else
   else
-    cmdstr:={$ifndef UNIX}'$IDF_PATH/tools/ldgen/ldgen.py '+{$endif UNIX}
-            '--config $OUTPUT/sdkconfig '+
-            '--fragments $IDF_PATH/components/esp8266/ld/esp8266_fragments.lf '+
-            '$IDF_PATH/components/esp8266/ld/esp8266_bss_fragments.lf $IDF_PATH/components/esp8266/linker.lf '+
-            '$IDF_PATH/components/freertos/linker.lf $IDF_PATH/components/log/linker.lf '+
-            '$IDF_PATH/components/lwip/linker.lf $IDF_PATH/components/spi_flash/linker.lf '+
-            '--env "COMPONENT_KCONFIGS_PROJBUILD=  $IDF_PATH/components/bootloader/Kconfig.projbuild '+
-            '$IDF_PATH/components/esptool_py/Kconfig.projbuild  $IDF_PATH/components/partition_table/Kconfig.projbuild"'+
-            '--env "COMPONENT_KCONFIGS=$IDF_PATH/components/app_update/Kconfig '+
-            '$IDF_PATH/components/esp8266/Kconfig  $IDF_PATH/components/freertos/Kconfig '+
-            '$IDF_PATH/components/log/Kconfig $IDF_PATH/components/lwip/Kconfig" '+
-            '--input $IDF_PATH/components/esp8266/ld/esp8266.project.ld.in '+
-            '--output $OUTPUT/esp8266.project.ld '+
-            '--kconfig $IDF_PATH/Kconfig '+
-            '--env-file $OUTPUT/config.env '+
-            '--libraries-file $OUTPUT/ldgen_libraries '+
-            '--objdump '+S;
+    begin
+      project_ld_filename:=outputexedir+'/esp8266.project.ld';
+      cmdstr:={$ifndef UNIX}'$IDF_PATH/tools/ldgen/ldgen.py '+{$endif UNIX}
+              '--config $OUTPUT/sdkconfig '+
+              '--fragments $IDF_PATH/components/esp8266/ld/esp8266_fragments.lf '+
+              '$IDF_PATH/components/esp8266/ld/esp8266_bss_fragments.lf $IDF_PATH/components/esp8266/linker.lf '+
+              '$IDF_PATH/components/freertos/linker.lf $IDF_PATH/components/log/linker.lf '+
+              '$IDF_PATH/components/lwip/linker.lf $IDF_PATH/components/spi_flash/linker.lf '+
+              '--env "COMPONENT_KCONFIGS_PROJBUILD=  $IDF_PATH/components/bootloader/Kconfig.projbuild '+
+              '$IDF_PATH/components/esptool_py/Kconfig.projbuild  $IDF_PATH/components/partition_table/Kconfig.projbuild"'+
+              '--env "COMPONENT_KCONFIGS=$IDF_PATH/components/app_update/Kconfig '+
+              '$IDF_PATH/components/esp8266/Kconfig  $IDF_PATH/components/freertos/Kconfig '+
+              '$IDF_PATH/components/log/Kconfig $IDF_PATH/components/lwip/Kconfig" '+
+              '--input $IDF_PATH/components/esp8266/ld/esp8266.project.ld.in '+
+              '--output '+project_ld_filename+' '+
+              '--kconfig $IDF_PATH/Kconfig '+
+              '--env-file $OUTPUT/config.env '+
+              '--libraries-file $OUTPUT/ldgen_libraries '+
+              '--objdump '+S;
+    end;
 
 
   Replace(cmdstr,'$IDF_PATH',idfpath);
   Replace(cmdstr,'$IDF_PATH',idfpath);
   Replace(cmdstr,'$OUTPUT',outputexedir);
   Replace(cmdstr,'$OUTPUT',outputexedir);
-  if success and not(cs_link_nolink in current_settings.globalswitches) and
-    { Newer version doesn't need to build linker script via ldgen.py }
-    ((current_settings.controllertype = ct_esp32) and (idf_version < 40300)) then
+  if success and not(cs_link_nolink in current_settings.globalswitches) then
     success:=DoExec(binstr,cmdstr,true,false);
     success:=DoExec(binstr,cmdstr,true,false);
+end;
+{$endif XTENSA}
+
+
+function TlinkerFreeRTOS.MakeExecutable:boolean;
+var
+  StaticStr,
+  binstr,
+  cmdstr,
+  mapstr: Ansistring;
+  success : boolean;
+  GCSectionsStr,
+  DynLinkStr,
+  StripStr,
+  FixedExeFileName: string;
+{$ifdef XTENSA}
+  esp_out_ld_filename,
+  esp_project_ld_filename: AnsiString;
+{$endif XTENSA}
+begin
+{$ifdef XTENSA}
+  { idfpath can be set by -Ff, else default to environment value of IDF_PATH }
+  if idfpath='' then
+    idfpath := trim(GetEnvironmentVariable('IDF_PATH'));
+  idfpath:=ExcludeTrailingBackslash(idfpath);
+{$endif XTENSA}
+
+  { for future use }
+  StaticStr:='';
+  StripStr:='';
+  mapstr:='';
+  DynLinkStr:='';
+
+  success:=true;
+  Result:=false;
+
+{$ifdef XTENSA}
+  { Locate linker scripts.  If not found, generate defaults. }
+  if ((current_settings.controllertype = ct_esp32) and
+      not (FindLibraryFile('esp32_out','', '.ld', esp_out_ld_filename) and
+           FindLibraryFile('esp32.project','', '.ld', esp_project_ld_filename))) or
+     ((current_settings.controllertype = ct_esp8266) and
+      not (FindLibraryFile('esp8266_out','', '.ld', esp_out_ld_filename) and
+           FindLibraryFile('esp8266.project','', '.ld', esp_project_ld_filename))) then
+    GenerateDefaultLinkerScripts(esp_out_ld_filename,esp_project_ld_filename);
 
 
   if (current_settings.controllertype = ct_esp32) then
   if (current_settings.controllertype = ct_esp32) then
     begin
     begin
@@ -1235,7 +1269,7 @@ begin
        '-u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -u app_main -u uxTopUsedPriority '+
        '-u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -u app_main -u uxTopUsedPriority '+
        '-L $IDF_PATH/components/esp_rom/esp32/ld '+
        '-L $IDF_PATH/components/esp_rom/esp32/ld '+
        '-T esp32.rom.ld -T esp32.rom.libgcc.ld -T esp32.rom.newlib-data.ld -T esp32.rom.syscalls.ld -T esp32.rom.newlib-funcs.ld '+
        '-T esp32.rom.ld -T esp32.rom.libgcc.ld -T esp32.rom.newlib-data.ld -T esp32.rom.syscalls.ld -T esp32.rom.newlib-funcs.ld '+
-       '-L $OUTPUT -T esp32_out.ld -T esp32.project.ld '+
+       '-T '+esp_out_ld_filename+' -T '+esp_project_ld_filename+' '+
        '-L $IDF_PATH/components/esp32/ld -T esp32.peripherals.ld';
        '-L $IDF_PATH/components/esp32/ld -T esp32.peripherals.ld';
       if idf_version>=40200 then
       if idf_version>=40200 then
         Info.ExeCmd[1]:=Info.ExeCmd[1]+' -L $IDF_PATH/components/esp32_rom/esp32/ld -T esp32.rom.api.ld';
         Info.ExeCmd[1]:=Info.ExeCmd[1]+' -L $IDF_PATH/components/esp32_rom/esp32/ld -T esp32.rom.api.ld';
@@ -1244,7 +1278,7 @@ begin
     begin
     begin
       Info.ExeCmd[1] := Info.ExeCmd[1]+' -u call_user_start -u g_esp_sys_info -u _printf_float -u _scanf_float '+
       Info.ExeCmd[1] := Info.ExeCmd[1]+' -u call_user_start -u g_esp_sys_info -u _printf_float -u _scanf_float '+
         '-L $IDF_PATH/components/esp8266/ld -T esp8266.peripherals.ld -T esp8266.rom.ld '+ { SDK scripts }
         '-L $IDF_PATH/components/esp8266/ld -T esp8266.peripherals.ld -T esp8266.rom.ld '+ { SDK scripts }
-        '-L $OUTPUT -T esp8266_out.ld -T esp8266.project.ld'; { Project scripts }
+        '-T '+esp_out_ld_filename+' -T '+esp_project_ld_filename; { Project scripts }
     end;
     end;
 
 
   Replace(Info.ExeCmd[1],'$IDF_PATH',idfpath);
   Replace(Info.ExeCmd[1],'$IDF_PATH',idfpath);