I'm trying to make GNUK software buildable with PlatformIO system. I have converted Makefile to platformio.ini
project file, all source files compile well, but I'm getting linker multiple definition errors for two of the arrays defined in one of my C source files. The relevant part of my source file is:
typedef void (*handler)(void);
handler vector[] __attribute__ ((section(".vectors"))) = {
(handler)&__ram_end__,
reset,
(handler)set_led,
flash_unlock,
(handler)flash_program_halfword,
(handler)flash_erase_page,
(handler)flash_check_blank,
(handler)flash_write,
(handler)flash_protect,
(handler)flash_erase_all_and_exec,
usb_lld_sys_init,
usb_lld_sys_shutdown,
nvic_system_reset,
};
const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
3*2+2, /* bLength */
0x03, /* bDescriptorType = USB_STRING_DESCRIPTOR_TYPE*/
/* sys version: "1.0" */
'1', 0, '.', 0, '0', 0,
};
The errors I get are:
.pio\build\OLIMEX_STM32_H103\src\sys.o:(.sys.version+0x0): multiple definition of `sys_version'
.pio\build\OLIMEX_STM32_H103\src\sys.o:(.sys.version+0x0): first defined here
.pio\build\OLIMEX_STM32_H103\src\sys.o:(.vectors+0x0): multiple definition of `vector'
.pio\build\OLIMEX_STM32_H103\src\sys.o:(.vectors+0x0): first defined here
I'm stuck with it and I even don't know where to start. If I add new variables to that source file, I get similar linker errors for them too. Looks like the same file gets linked twice?
The linker script contents are:
__main_stack_size__ = 0x0400;
__process_stack_size__ = 0x0200;
__stacks_total_size__ = __main_stack_size__ + __process_stack_size__;
MEMORY
{
flash0 : org = 0x08000000, len = 4k
flash : org = 0x08000000+0x1000, len = 128k - 4k
ram : org = 0x20000000, len = 20k
}
/* __flash_start__: flash ROM start address regardless of DFU_SUPPORT */
__flash_start__ = 0x08001000;
__flash_end__ = ORIGIN(flash) + LENGTH(flash);
__ram_start__ = ORIGIN(ram);
__ram_size__ = LENGTH(ram);
__ram_end__ = __ram_start__ + __ram_size__;
SECTIONS
{
. = 0;
.sys : ALIGN(16) SUBALIGN(16)
{
_sys = .;
KEEP(*(.vectors))
. = ALIGN(16);
*(.sys.version)
src\sys.o(.text)
src\sys.o(.text.*)
src\sys.o(.rodata)
src\sys.o(.rodata.*)
. = ALIGN(1024);
*(.sys.0)
*(.sys.1)
*(.sys.2)
} > flash0
.text : ALIGN(16) SUBALIGN(16)
{
_text = .;
KEEP(*(vectors))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
*(.glue_7t)
*(.glue_7)
*(.gcc*)
} > flash
.ctors :
{
PROVIDE(_ctors_start_ = .);
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
PROVIDE(_ctors_end_ = .);
} > flash
.dtors :
{
PROVIDE(_dtors_start_ = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(_dtors_end_ = .);
} > flash
.ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)}
__exidx_start = .;
.ARM.exidx : {*(.ARM.exidx* .gnu.linkonce.armexidx.*)} > flash
__exidx_end = .;
.eh_frame_hdr : {*(.eh_frame_hdr)}
.eh_frame : ONLY_IF_RO {*(.eh_frame)}
. = ALIGN(4);
_etext = .;
_textdata = _etext;
.data :
{
_data = .;
*(.data)
. = ALIGN(4);
*(.data.*)
. = ALIGN(4);
*(.ramtext)
. = ALIGN(4);
_edata = .;
} > ram AT > flash
.bss :
{
_bss_start = .;
*(.bss)
. = ALIGN(4);
*(.bss.*)
. = ALIGN(4);
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} > ram
PROVIDE(end = .);
_end = .;
. = ALIGN(512);
_regnual_start = .;
.gnuk_flash :
{
. = ALIGN (1024);
_data_pool = .;
KEEP(*(.gnuk_data))
. = ALIGN(1024);
. += 1024;
_keystore_pool = .;
. += 512*3;
. = ALIGN(1024);
_updatekey_store = .;
. += 1024;
. = ALIGN(1024);
} > flash =0xffffffff
}
__heap_base__ = _end;
__heap_end__ = __ram_end__ - __stacks_total_size__;
The solution was to replace
src\sys.o
in the linker script with*sys.o
.As stated in the ld manual,
The
sys.o
file was specified on the command line with another path than in the linker file, so the linker tried to link it twice.