In the Uno case, there is no explicit linker script given to the compiler. That can be observed by verbose-compiling (pio run -v) a standard Uno project.
opened script file c:\users\max\.platformio\packages\toolchain-atmelavr\avr\bin\../lib\ldscripts/avr5.xn
using external linker script:
==================================================
/* Script for -n: mix text and data on same page */
/* Copyright (C) 2014-2015 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xffa0;
__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K;
__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K;
__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K;
__SIGNATURE_REGION_LENGTH__ = DEFINED(__SIGNATURE_REGION_LENGTH__) ? __SIGNATURE_REGION_LENGTH__ : 1K;
__USER_SIGNATURE_REGION_LENGTH__ = DEFINED(__USER_SIGNATURE_REGION_LENGTH__) ? __USER_SIGNATURE_REGION_LENGTH__ : 1K;
__DATA_REGION_ORIGIN__ = DEFINED(__DATA_REGION_ORIGIN__) ? __DATA_REGION_ORIGIN__ : 0x800060;
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
data (rw!x) : ORIGIN = __DATA_REGION_ORIGIN__, LENGTH = __DATA_REGION_LENGTH__
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
lock (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__
signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__
user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__
}
[...]
So, PlatformIO itself in this case doesn’t explicitly know what linkerscript is used, it’s handled compiler-internally, in this case, c:\users\max\.platformio\packages\toolchain-atmelavr\avr\lib\ldscripts\avr5.xn
Other platforms make use of explicit linker scripts. The standard is that the linkerscript is either written in the board’s JSON manifest in the build → ldscript info, or automatically determined by a builder script and written into env["LDSCRIPT_PATH"].
Note that in this special case, there are even two linkerscripts in play, with -Wl,--default-script. A verbose compilation of a standard nucleo_f103rb Arduino project shows
and -Wl,--default-script C:/Users/Max/.platformio/packages/framework-arduinoststm32/variants/STM32F1xx/F103R(8-B)T/ldscript.ld
script is used for building. Linkerscripts can be additive and even include each other, leading to such possibilities.
PlatformIO has the capability of outputting the compile commands without actually compiling the project, this is referred to as the compile_commands.json and can also be output by running pio run -t compiledb. Sadly I just found out that that does not include the critical final linker command for the .elf where the used linkerscript would be shown – too bad.
A work-around for this could be to inspect env["LINKFLAGS"], since that is the construction variable used by SCons to construct the linker command.
As shown in pio run -t envdump for a Nucleo F103RB project again, it shows
Eventually I found the linkerscripts for Arduino projects. For the native Embeetle projects (makefile-based), I just copy them into the project. This way, the user has a local linkerscript in his project and is able to modify it at will. Case closed.
For PIO projects, I don’t want to do this. I let go of my earlier plans to modify existing PIO projects. Instead, I want to modify Embeetle IDE such that it can open a PIO project as-is.
That being said, Embeetle IDE would still like to know where the linkerscript is located, just to analyze it. It looks like this is no easy task. It would be very unfortunate if I have to build the project first with full verbosity, then look throughout the build output with regexes to locate the linkerscript. I could do this, but it’s opening a can of worms. What if the build fails? Just to mention one issue…