Linker "The command line is too long" (ESP32)

I have a rather large project that has been building quite nicely with PlatformIO compared to the prior Arduino IDE approach in VSCode.

Just last night night I created a new source module for new functionality, all compiles fine, but when I reach the linking stage I get “The command line is too long” error thrown.
Obviously all my object files are being presented on the command line to the linker, resulting in the error.

Is there way instead to create and provide the linker with a file that lists all the object files, obviously using the dependency checker so this list is created automatically?

I have done this in the past with raw makefiles and DOS builds (yeah I’m old) when the command line was only around 256 chars max :smiley:

1 Like

For long commands like these, PIO is supposed to create a longcmd_<hash>.txt file and feed it as the input to GCC/G++. I’ve also seen this happen during building already. But apparently it doesn’t do it for linking, @ivankravets?

Can you upload the linking command during a verbose build (pio run -v) or tell us what length it is, and what OS you’re using?

1 Like

Thanks for your response.

I’m using Windows 10, latest release of PIO.

I hope the following inserts OK, I presume the text that shows after the error is what you are interested in?
I have snipped all the compile stages as it makes it quite large otherwise.
I tried to attach a .zip but it gets rejected.

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS F:\GIT_LOCAL\Afterburner> pio run -v
Processing esp32dev (upload_protocol: espota; extra_scripts: post:add_CRC.py; framework: arduino; upload_flags: --port=3232; build_flags: -Wl,--wrap,millis; monitor_speed: 115200; platform: espressif32; upload_speed: 921600; board: esp32dev; lib_extra_dirs: ~/Documents/Arduino/libraries; upload_port: 192.168.20.40; board_build.partitions: min_spiffs.csv)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32dev.html
PLATFORM: Espressif 32 1.9.0 > Espressif ESP32 Dev Module
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: toolchain-xtensa32 2.50200.80 (5.2.0), tool-openocd-esp32 1.1000.20190708 (10.0), framework-arduinoespressif32 2.10002.190628 (1.0.2), tool-esptoolpy 1.20600.0 (2.6.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 38 compatible libraries
Scanning dependencies...
Dependency Graph

8< 8< 8<

**The command line is too long.**
*** [.pio\build\esp32dev\firmware.elf] Error 1
xtensa-esp32-elf-g++ -o .pio\build\esp32dev\firmware.elf -T esp32_out.ld -Wl,--wrap,millis -nostdlib -Wl,-static -u call_user_start_cpu0 -Wl,--undefined=uxTopUsedPriority -Wl,--gc-sections -Wl,-EL -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld -T esp32.rom.spiram_incompatible_fns.ld
-u ld_include_panic_highint_hdl -u __cxa_guard_dummy -u __cxx_fatal_exception .pio\build\esp32dev\src\Afterburner\Afterburner.cpp.o .pio\build\esp32dev\src\Afterburner\src\Bluetooth\BluetoothESP32.cpp.o .pio\build\esp32dev\src\Afterburner\src\Bluetooth\BluetoothHC05.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\Adafruit-GFX-Library\Adafruit_GFX.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\Adafruit-GFX-Library\Adafruit_SPITFT.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\Adafruit-GFX-Library\fontconvert\fontconvert.c.o .pio\build\esp32dev\src\Afterburner\src\Libraries\Adafruit-GFX-Library\glcdfont.c.o .pio\build\esp32dev\src\Afterburner\src\Libraries\Adafruit_SSD1306\Adafruit_SSD1306.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\PubSubClient\src\PubSubClient.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\RTClib\RTClib.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\TelnetSpy\TelnetSpy.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\WiFiManager-dev\WiFiManager.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\arduinoWebSockets\src\WebSockets.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\arduinoWebSockets\src\WebSocketsClient.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\arduinoWebSockets\src\WebSocketsServer.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\arduinoWebSockets\src\libb64\cdecode.c.o .pio\build\esp32dev\src\Afterburner\src\Libraries\arduinoWebSockets\src\libb64\cencode.c.o .pio\build\esp32dev\src\Afterburner\src\Libraries\arduinoWebSockets\src\libsha1\libsha1.c.o .pio\build\esp32dev\src\Afterburner\src\Libraries\esp32-ds18b20\ds18b20.c.o .pio\build\esp32dev\src\Afterburner\src\Libraries\esp32-ds18b20\owb.c.o .pio\build\esp32dev\src\Afterburner\src\Libraries\esp32-ds18b20\owb_rmt.c.o .pio\build\esp32dev\src\Afterburner\src\Libraries\esp32-sh1106-oled\Adafruit_SH1106.cpp.o .pio\build\esp32dev\src\Afterburner\src\Libraries\esp32FOTA\src\esp32fota.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\128x64OLED.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\BasicScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\ClockScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\DetailedScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\FontDumpScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\FuelCalScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\FuelMixtureScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\GPIOScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\HeaterSettingsScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\HomeMenuSelScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\InheritSettingsScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\KeyPad.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\OtherOptionsScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\PasswordScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\PrimingScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\RebootScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\Screen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\ScreenHeader.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\ScreenManager.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\SetClockScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\SetTimerScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\SettingsScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\ThermostatModeScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\TimerChartScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\VersionInfoScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\WiFiScreen.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\Arial.c.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\FranklinGothic.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\Icons.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\MicroFont.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\MidiFont.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\MiniFont.c.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\OCRfont.cpp.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\Tahoma16.c.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\Tahoma24.c.o .pio\build\esp32dev\src\Afterburner\src\OLED\fonts\Tahoma8.c.o .pio\build\esp32dev\src\Afterburner\src\Protocol\Protocol.cpp.o .pio\build\esp32dev\src\Afterburner\src\Protocol\SmartError.cpp.o .pio\build\esp32dev\src\Afterburner\src\Protocol\TxManage.cpp.o .pio\build\esp32dev\src\Afterburner\src\RTC\BTCDateTime.cpp.o .pio\build\esp32dev\src\Afterburner\src\RTC\Clock.cpp.o .pio\build\esp32dev\src\Afterburner\src\RTC\TimerManager.cpp.o .pio\build\esp32dev\src\Afterburner\src\RTC\Timers.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\BTC_GPIO.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\BTC_JSON.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\BoardDetect.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\DataFilter.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\Debounce.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\FuelGauge.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\MODBUS-CRC16.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\Moderator.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\NVCore.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\NVStorage.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\TempSense.cpp.o .pio\build\esp32dev\src\Afterburner\src\Utility\UtilClasses.cpp.o .pio\build\esp32dev\src\Afterburner\src\WiFi\ABMqtt.cpp.o .pio\build\esp32dev\src\Afterburner\src\WiFi\BTCWebServer.cpp.o .pio\build\esp32dev\src\Afterburner\src\WiFi\BTCWifi.cpp.o .pio\build\esp32dev\src\Afterburner\src\WiFi\BTCota.cpp.o .pio\build\esp32dev\src\Afterburner\src\WiFi\BrowserUpload.cpp.o -L.pio\build\esp32dev -LC:\users\ray\.platformio\packages\framework-arduinoespressif32\tools\sdk\lib -LC:\users\ray\.platformio\packages\framework-arduinoespressif32\tools\sdk\ld -Wl,--start-group .pio\build\esp32dev\libf59\libWire.a .pio\build\esp32dev\lib525\libSPI.a .pio\build\esp32dev\lib08e\libEthernet.a .pio\build\esp32dev\libaa4\libWiFi.a .pio\build\esp32dev\lib217\libDNSServer.a .pio\build\esp32dev\lib6fa\libBluetoothSerial.a .pio\build\esp32dev\lib876\libFS.a .pio\build\esp32dev\lib156\libWebServer.a .pio\build\esp32dev\libfd6\libBLE.a .pio\build\esp32dev\lib2ba\libWiFiClientSecure.a .pio\build\esp32dev\lib650\libSPIFFS.a .pio\build\esp32dev\lib8d0\libHTTPClient.a .pio\build\esp32dev\lib5e9\libESPmDNS.a .pio\build\esp32dev\lib63a\libUpdate.a .pio\build\esp32dev\libda9\libArduinoOTA.a .pio\build\esp32dev\lib77c\libPreferences.a .pio\build\esp32dev\libFrameworkArduinoVariant.a .pio\build\esp32dev\libFrameworkArduino.a -lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lcoexist -lwear_levelling -lesp_http_client -lprotobuf-c -lhal -lnewlib -ldriver -lbootloader_support -lpp -lfreemodbus -lmesh -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lfrmn -lapp_trace -lfr_coefficients -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lesp32-camera -lcxx -lxtensa-debug-module -ltcp_transport -lmdns -lvfs -lmtmn -lesp_ringbuf -lsoc -lcore -lfb_gfx -lsdmmc -llibsodium -lcoap -ltcpip_adapter -lprotocomm -lesp_event -limage_util -lc_nano -lesp-tls -lasio -lrtc -lspi_flash -lwpa2 -lwifi_provisioning -lesp32 -lface_recognition -lapp_update -lnghttp -lspiffs -lface_detection -lespnow -lnvs_flash -lesp_adc_cal -llog -ldl_lib -lsmartconfig_ack -lexpat -lfd_coefficients -lm -lmqtt -lc -lheap -lmbedtls -llwip -lnet80211 -lesp_http_server -lpthread -ljson -lesp_https_ota -lstdc++ -Wl,--end-group
===================================================================================================================================== [ERROR] Took 143.11 seconds =====================================================================================================================================

I saved just the linker command line to a file.
Looks like the 8k limit is being violated?

FYI, You can use triple backticks (```) before and after code blocks so nothing gets made HTML safe, and long blocks look better.

If you’re having issues with a long text paste on the forum, use something like pastebin and just share the link to that.

And ouch… 8k… that’s a long linker command… the things you don’t know your compiler/linker is doing! :laughing: :laughing:

It should work for link command too. See https://github.com/platformio/platformio-core/blob/develop/platformio/builder/tools/piowinhooks.py#L84

@valeros, could you try to generate dummy *.c files in project and reproduce this issue?

Hi @rljonesau! The limit is 32K when the list of your objects is passed to the linker in a form of a file. Please send your project to vkoval@platformio.org, and I’ll look into it.

I have the same problem trying to compile esp-idf and lvgl on Windows 7 (where the OS is not my choice).
The pio run -v output for the command exceeds 8KB.
I also run pio update with no changes.
The platformio.ini is a standard generated file for a Lolin D32 Pro and esp-idf.

1 Like

This error highly depends on certain factors:

  • what’s the length of the file path where the project is stored?
  • number of used libraries and source files?
  • do you have lib_archive set to false in the platformio.ini?
1 Like

Thanks.
That was my fault as I couldnt figure out how to make the lv_conf.h discoverable for the lvgl library, so I copied the whole library to the src directory, which brought up the issue.

Now the lvgl library is at the right place, the lv_conf.h is in the src folder and the src folder is included via the build options/flags in the platformio.ini.

Good day,

I am having this same problems, what build options did you use and how did you set up the work-space?

We’re now coming up against this in our large project, and as the project continues to grow we expect to hit this limit more. So my question is, what other tricks can we employ in the pre-processing stage of PlatformIO to produce a shorter command line? Here are some ideas:

  • Use a short name substitute for env name when naming the .pio/env folder or create a short-named symlink.
  • Set a shell variable for the build path and use the shell var in the linker line.
  • Predetermine which compiled files (no imports or exports) can be excluded from linking.
  • Add an option to put .pio/ closer to the root of C:\.
  • Invoke linking with the cwd inside the env folder, then use relative paths.
  • Don’t link everything all at once, but in two or more invocations.

I’m not sure what we ourselves can do other than make our env entries shorter. Even with that change applied we’re still likely to see this issue a lot.

PlatformIO Build System should handle this automatically. What is your dev-platform? Framework? Board?

Since this only affects Windows and I use macOS I haven’t hit this limit in my everyday work. Users who use Arduino IDE hit the limit more often because our project doesn’t package the platform-specific parts as libraries, so that IDE ends up compiling every file. But if the project folder has a very long path then even PlatformIO can hit the limit (I have been told).

Rather than speculate on this I’ll have a look at the actual linker line that is being output for the build, see whether I can get it to be over 32K in size, and see what PIO is currently doing to mitigate the issue.

We have virtual machines with Windows. Could you prepreare PlatformIO project ot reproduce this issue? We would be glad to fix it ASAP.

Hello, I just ran over the same issue. Replication - as I work on a proprietary solution - is not straightforward, but what should help is that my project imports 76 external libraries thru lib_deps. That results in the final linker command of 10280 bytes.

Please see my platformio.ini and the resulting linker command for building the 21-pin version - it should give You a good idea how to reproduce this issue. I had to mask the files a bit - sorry for this.

Too long line issue - platformio.ini - Pastebin.com
Too long line issue - resulting linker command - Pastebin.com

I will also file an issue to the core library on GitHub

In case someone hits this thread as I did, I managed to work around the issue of command line too long at final linking step, due to multiple libraries. It is documented in the comments for the issue on github.

“Command line is too long” while building large project under Windows · Issue #3792 · platformio/platformio-core (github.com)