Skip to content

Commit 5df037c

Browse files
committed
loader: nano_connect: fix linking error with picolibc
The Zephyr SDK's picolibc.specs file unconditionally injects --gc-sections into the linker flags. --gc-sections removes any section not reachable from an entry point. But boot_stage2.ld has no ENTRY() directive, so the linker thinks everything is unreachable and discards all sections and then objcopy fails with the input file 'boot_stage2' has no sections. The fix overrides the default cmake configs with --no-gc-sections. Signed-off-by: Gilberto Conti <g.conti@arduino.cc>
1 parent afc79e5 commit 5df037c

3 files changed

Lines changed: 69 additions & 0 deletions

File tree

loader/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards)
1010
set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay)
1111
set(EXTRA_CONF_FILE ${CMAKE_CURRENT_LIST_DIR}/../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.conf)
1212

13+
# Register our project as a MODULE_EXT_ROOT so our module overrides
14+
# (e.g. modules/hal_rpi_pico) take precedence over zephyr's defaults.
15+
list(APPEND MODULE_EXT_ROOT ${CMAKE_CURRENT_LIST_DIR})
16+
1317
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
1418

1519
project(app LANGUAGES C CXX)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Override for hal_rpi_pico module: patches the boot_stage2 ExternalProject
4+
# to add -Wl,--no-gc-sections (picolibc.specs injects --gc-sections which
5+
# discards all sections because boot_stage2.ld has no ENTRY()).
6+
#
7+
# Instead of maintaining a full copy of the zephyr CMakeLists.txt, we read
8+
# the original, apply targeted patches, and include the patched version.
9+
10+
set(_orig_dir ${ZEPHYR_BASE}/modules/hal_rpi_pico)
11+
set(_patch_dir ${CMAKE_CURRENT_BINARY_DIR}/_patched_hal_rpi_pico)
12+
13+
# --- Patch the main CMakeLists.txt ---
14+
file(READ ${_orig_dir}/CMakeLists.txt _content)
15+
16+
# Point the ExternalProject to our patched bootloader dir
17+
string(REPLACE
18+
"SOURCE_DIR \${CMAKE_CURRENT_LIST_DIR}/bootloader"
19+
"SOURCE_DIR ${_patch_dir}/bootloader"
20+
_content "${_content}")
21+
22+
# Fix remaining CMAKE_CURRENT_LIST_DIR refs (include dirs, linker scripts)
23+
string(REPLACE
24+
"\${CMAKE_CURRENT_LIST_DIR}"
25+
"${_orig_dir}"
26+
_content "${_content}")
27+
28+
# Fix relative linker script paths (resolved via CMAKE_CURRENT_SOURCE_DIR)
29+
string(REPLACE " timecritical.ld)" " ${_orig_dir}/timecritical.ld)" _content "${_content}")
30+
string(REPLACE " uninit_data.ld)" " ${_orig_dir}/uninit_data.ld)" _content "${_content}")
31+
32+
file(WRITE ${_patch_dir}/CMakeLists.txt "${_content}")
33+
34+
# --- Patch the bootloader CMakeLists.txt ---
35+
file(READ ${_orig_dir}/bootloader/CMakeLists.txt _boot_content)
36+
37+
# Add --no-gc-sections after picolibc.specs
38+
string(REPLACE
39+
"\"--specs=picolibc.specs\""
40+
"\"--specs=picolibc.specs\"\n \"-Wl,--no-gc-sections\""
41+
_boot_content "${_boot_content}")
42+
43+
# Fix ".." include dir to point to original zephyr module dir
44+
string(REPLACE
45+
"\n ..\n"
46+
"\n ${_orig_dir}\n"
47+
_boot_content "${_boot_content}")
48+
49+
file(MAKE_DIRECTORY ${_patch_dir}/bootloader)
50+
file(WRITE ${_patch_dir}/bootloader/CMakeLists.txt "${_boot_content}")
51+
52+
# --- Include the patched version ---
53+
include(${_patch_dir}/CMakeLists.txt)

loader/modules/modules.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# Override module cmake dirs with our local versions.
3+
4+
file(GLOB cmake_modules "${CMAKE_CURRENT_LIST_DIR}/*/CMakeLists.txt")
5+
6+
foreach(module ${cmake_modules})
7+
get_filename_component(module_dir ${module} DIRECTORY)
8+
get_filename_component(module_name ${module_dir} NAME)
9+
zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name})
10+
11+
set(ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR ${module_dir})
12+
endforeach()

0 commit comments

Comments
 (0)