View Issue Details

IDProjectCategoryView StatusLast Update
0037308FPCCompilerpublic2020-07-10 12:14
ReporterAlfred Assigned To 
Status newResolutionopen 
Product Version3.3.1 
Summary0037308: FreeRTOS tool settings cause tools (gcc) not found.
DescriptionThe file t_freertos.pas does not follow the normal tool search in some cases (especially gcc). The included patch solves, but also adds some extras.
For $IDF_PATH, the environment is used. The included patch tries to resolve this directory also without this variable present.
Besides, it removes maybequoted for $IDF_PATH. This will never work when only a part of a path is replaced by $IDF_PATH.
TagsNo tags attached.
Fixed in Revision
Attached Files



2020-07-07 11:20


freertos.patch (6,280 bytes)   
--- compiler/systems/t_freertos.pas
+++ compiler/systems/t_freertos.pas
@@ -38,6 +38,7 @@ implementation
+          IDFPath:TCmdStr;
           Function  WriteResponseFile: Boolean;
           constructor Create; override;
@@ -72,7 +73,58 @@ const
+ ESPIDFDIR='esp-idf';
+ aPath:TCmdStr;
+ hs:TCmdStr;
+  aPath:=Trim(GetEnvironmentVariable('IDF_PATH'));
+  while true do
+   begin
+    if (aPath<>'') then
+     break;
+    {$ifdef Windows}
+    hs:=GetEnvironmentVariable('USERPROFILE');
+    {$else}
+    hs:=GetEnvironmentVariable('HOME');
+    {$endif}
+    hs:=FixPath(hs,true);
+    aPath:=hs+'.espressif/'+ESPIDFDIR;
+    if PathExists(aPath,false) then
+     break;
+    aPath:=hs+'esp/'+ESPIDFDIR;
+    if PathExists(aPath,false) then
+     break;
+    {$ifdef Windows}
+    // This is the standard esp-idf install path by the Windows installer
+    aPath:=hs+'Desktop\'+ESPIDFDIR;
+    if PathExists(aPath,false) then
+     break;
+    //Try some other locations
+    aPath:=hs+'Documents\'+ESPIDFDIR;
+    if PathExists(aPath,false) then
+     break;
+    aPath:=hs+ESPIDFDIR;
+    if PathExists(aPath,false) then
+     break;
+    {$endif}
+    if (utilsdirectory<>'') then
+     begin
+      aPath:=utilsdirectory+'/../'+ESPIDFDIR;
+      if PathExists(aPath,false) then
+       break;
+     end;
+    {$ifdef UNIX}
+    aPath:='/opt/esp/'+ESPIDFDIR;
+    if PathExists(aPath,false) then
+     break;
+    {$endif}
+    aPath:=FixPath(GetCurrentDir,false)+ESPIDFDIR;
+    break;
+   end;
+  IDFPath:=aPath;
   with Info do
 {$ifdef xtensa}
@@ -1108,7 +1160,7 @@ begin
           writeln(t,'    "COMPONENT_KCONFIGS_PROJBUILD": "Kconfig.projbuild",');
           writeln(t,'    "IDF_CMAKE": "y",');
           writeln(t,'    "IDF_TARGET": "esp32",');
-          writeln(t,'    "IDF_PATH": "'+GetEnvironmentVariable('IDF_PATH')+'",');
+          writeln(t,'    "IDF_PATH": "'+IDFPath+'",');
           writeln(t,'    "COMPONENT_KCONFIGS_SOURCE_FILE": "",');
           writeln(t,'    "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE": ""');
@@ -1139,30 +1191,30 @@ begin
-      binstr:='xtensa-esp32-elf-gcc';
+      binstr:='gcc';
       cmdstr:='-C -P -x c -E -o esp32_out.ld -I . $IDF_PATH/components/esp32/ld/esp32.ld';
-      Replace(binstr,'$IDF_PATH',maybequoted(GetEnvironmentVariable('IDF_PATH')));
-      Replace(cmdstr,'$IDF_PATH',maybequoted(GetEnvironmentVariable('IDF_PATH')));
-      success:=DoExec(binstr,cmdstr,true,true);
+      Replace(cmdstr,'$IDF_PATH',IDFPath);
+      success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,true);
       { generate linker maps for esp32 }
+      S:=FindUtil(utilsprefix+'objdump');
       cmdstr:='--config 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/ --output ./esp32.project.ld --kconfig $IDF_PATH/Kconfig --env-file config.env '+
-        '--libraries-file ldgen_libraries --objdump xtensa-esp32-elf-objdump';
-      Replace(binstr,'$IDF_PATH',maybequoted(GetEnvironmentVariable('IDF_PATH')));
-      Replace(cmdstr,'$IDF_PATH',maybequoted(GetEnvironmentVariable('IDF_PATH')));
+        '--libraries-file ldgen_libraries --objdump '+S;
+      Replace(binstr,'$IDF_PATH',IDFPath);
+      Replace(cmdstr,'$IDF_PATH',IDFPath);
       if success and not(cs_link_nolink in current_settings.globalswitches) then
   if IDF_PATH <> '' then
-    Replace(Info.ExeCmd[1],'$'+IDF_PATH,maybequoted(GetEnvironmentVariable(IDF_PATH)));
+    Replace(Info.ExeCmd[1],'$'+IDF_PATH,IDFPath);
@@ -1180,7 +1232,7 @@ begin
   if target_info.system=system_xtensa_freertos then
-    Replace(cmdstr,'$'+IDF_PATH,maybequoted(GetEnvironmentVariable(IDF_PATH)));
+    Replace(cmdstr,'$'+IDF_PATH,IDFPath);
   if not(cs_link_on_target in current_settings.globalswitches) then
@@ -1217,7 +1269,7 @@ begin
     if (current_settings.controllertype = ct_esp32) then
-        Replace(binstr,'$'+IDF_PATH,maybequoted(GetEnvironmentVariable(IDF_PATH)));
+        Replace(binstr,'$'+IDF_PATH,IDFPath);
         success:=DoExec(binstr,'--chip esp32 elf2image --flash_mode dio --flash_freq 40m '+
           '--flash_size '+tostr(embedded_controllers[current_settings.controllertype].flashsize div (1024*1024))+'MB '+
           '--elf-sha256-offset 0xb0 '+
@@ -1228,7 +1280,7 @@ begin
     else if (current_settings.controllertype = ct_esp8266) then
-        Replace(binstr,'$'+IDF_PATH,maybequoted(GetEnvironmentVariable(IDF_PATH)));
+        Replace(binstr,'$'+IDF_PATH,IDFPath);
         success:=DoExec(binstr,'--chip esp8266 elf2image --flash_mode dout --flash_freq 40m '+
           '--flash_size '+tostr(embedded_controllers[current_settings.controllertype].flashsize div (1024*1024))+'MB '+
           '--version=3 '+
freertos.patch (6,280 bytes)   

Sven Barth

2020-07-07 13:30

manager   ~0123799

Some remarks:
- we use two spaces for ident
- local variables are written in lowercase with no prefix (and a space in front and after the ':')
- there is SysUtils.GetUserDir to retrieve the user's home directory
- why do you use a potentially infinite loop if a nested function might be more appropriate if you want to use early exits?


2020-07-07 13:58

reporter   ~0123800

About the cosmetics: I will honor all necessary changes if the functionality of this patch is reviewed and approved.
SysUtils.GetUserDir: I was not sure if this function was/is already available in this build-stage. Will use it if available.
Potentially infinite loop: Lets say we agree to dis-agree on this. But sure this could be done in a much more elegant manner !

Main remark.
Please review the functionality of this patch.
Necessary changes will be applied after review.

Sven Barth

2020-07-08 09:32

manager   ~0123812

This will have to wait for Florian then, as he's the one working on Xtensa support.

Christo Crause

2020-07-08 11:38

reporter   ~0123816

Caching the IDF_PATH environment variable is a good idea, it should be invariant during the compilation phase.

Your while loop is an interesting variant of goto logic without actually using the goto statement :-)

On a future related matter: although ESP8266_RTOS_SDK is not yet supported in trunk, I would appreciate ideas on how to integrate that target too. Here the SDK also by default define IDF_PATH to point ot the SDK, so a work-around is required to have side by side installations of both SDKs. This should probably be a separate patch, but thinking how one can combine functionality or need to separate functionality at this stage can make introducing ESP8266 support a little bit easier.

I will test your patch on LInux, but it will have to wait a day or so.


2020-07-08 13:09

reporter   ~0123818

@Christo Crause
Thanks !
While I am not an expert in this target, I might need some advice.
When using this patch, things go very well until error about not finding "libdriver.a". Seems SDK (files) cannot be found. Can you help ?
Its related towards your desire to use separate SDK.
Perhaps tools location and SDK location must/should/could be tightly coupled.
Otherwise, an extra compiler-switch might be needed. Someting like:
-XLS Location of SDK (Darwin, FreeRTOS)

Christo Crause

2020-07-08 14:15

reporter   ~0123819

Apologies for this somewhat wandering reply...

Part of the challenge with linking to these SDKs is that they are distributed as source code, because there are many user configurable options that can be changed. So part of the twists and turns in t_freertos.pas is to try and include user configurable changes into the linking process. One can for instance select to use functionality available in onboard ROM or use a library provided alternative - this requires a different linker script.

The current approach as described in the wiki ( is to configure and build one of the examples shipped with the SDK. This example will then contain an almost complete complement of files required - there may be a library or two required from the toolchain and some binary libraries shipped with the SDK. So a user can either collect all required files and dump them in any folder (as per the wiki), or my suggestion is to dump this library folder in the root of IDF_PATH so that it can be found automatically relative to the SDK folder.

What I do at the moment is to specify the different paths with required library files using the -Fl option, per project. As long as the bintools are in the path no special treatment is required to run ld and friends. Other tools such as or sit inside the SDK at known locations, so as long as the compiler can find the root of the SDK (via IDF_PATH variable or some other search method) it should be OK.

Christo Crause

2020-07-08 20:04

reporter   ~0123832

Alfred, I tested your patch on Linux. When IDF_PATH is defined the compiler works and compiles a test application. This means your patch does not interfere with the existing compiler logic, at least for my setup.

If I delete the IDF_PATH variable from the console the compiler does not locate the esp-idf folder. This is because I pull the source from git into a folder in my home folder. On Windows there is an installer so users on Windows could benefit more from searching standard locations.


2020-07-08 22:07

reporter   ~0123834

Thanks for testing.
And, thanks to your instruction, I can (nearly) build an esp32 binary myself. Just some final stage linking errors, but nothing serious.
For sure, the esp-idf folder will be hard to find with no extra info. On Windows, it looks into the Desktop. That's the path the installer will install the SDK, but I can hardly imagine that many users will use that location.
The patch just does a best-guess. Goal is to get things running without the need of setting/changing the PATH variable or the IDF_PATH variable. This would enable fpcupdeluxe to give users an (isolated, harmless) out-of-the-box experience for xtensa (freertos).
(I am maintainer of fpcupdeluxe: source of my interest)


2020-07-10 12:14

reporter   ~0123867

With a few more t-freertos.pas changes, out-of-the-box success on Windows too !
See screenshot
xtensawin.JPG (190,898 bytes)   
xtensawin.JPG (190,898 bytes)   

Issue History

Date Modified Username Field Change
2020-07-07 11:20 Alfred New Issue
2020-07-07 11:20 Alfred File Added: freertos.patch
2020-07-07 13:30 Sven Barth Note Added: 0123799
2020-07-07 13:58 Alfred Note Added: 0123800
2020-07-08 09:32 Sven Barth Note Added: 0123812
2020-07-08 11:38 Christo Crause Note Added: 0123816
2020-07-08 13:09 Alfred Note Added: 0123818
2020-07-08 14:15 Christo Crause Note Added: 0123819
2020-07-08 20:04 Christo Crause Note Added: 0123832
2020-07-08 22:07 Alfred Note Added: 0123834
2020-07-10 12:14 Alfred Note Added: 0123867
2020-07-10 12:14 Alfred File Added: xtensawin.JPG