Skip to content

Commit 86d69ab

Browse files
committed
Merge branch 'linker-optimization-flag' into combined-west-updates
2 parents 5514fce + 19cc9f0 commit 86d69ab

File tree

11 files changed

+186
-60
lines changed

11 files changed

+186
-60
lines changed

CMakeLists.txt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,12 @@ get_property(ASM_OPTIMIZE_FOR_SPEED_FLAG TARGET asm PROPERTY optimization_speed)
226226
get_property(ASM_OPTIMIZE_FOR_SIZE_FLAG TARGET asm PROPERTY optimization_size)
227227
get_property(ASM_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG TARGET asm PROPERTY optimization_size_aggressive)
228228

229+
get_property(LINKER_OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG TARGET linker PROPERTY no_optimization)
230+
get_property(LINKER_OPTIMIZE_FOR_DEBUG_FLAG TARGET linker PROPERTY optimization_debug)
231+
get_property(LINKER_OPTIMIZE_FOR_SPEED_FLAG TARGET linker PROPERTY optimization_speed)
232+
get_property(LINKER_OPTIMIZE_FOR_SIZE_FLAG TARGET linker PROPERTY optimization_size)
233+
get_property(LINKER_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG TARGET linker PROPERTY optimization_size_aggressive)
234+
229235
# Let the assembler inherit the optimization flags of the compiler if it is
230236
# not set explicitly.
231237
if(NOT ASM_OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG)
@@ -244,23 +250,46 @@ if(NOT ASM_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG)
244250
set(ASM_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG ${COMPILER_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG})
245251
endif()
246252

253+
# Let the linker inherit the optimization flags of the compiler if it is
254+
# not set explicitly.
255+
if(NOT LINKER_OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG)
256+
set(LINKER_OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG ${COMPILER_OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG})
257+
endif()
258+
if(NOT LINKER_OPTIMIZE_FOR_DEBUG_FLAG)
259+
set(LINKER_OPTIMIZE_FOR_DEBUG_FLAG ${COMPILER_OPTIMIZE_FOR_DEBUG_FLAG})
260+
endif()
261+
if(NOT LINKER_OPTIMIZE_FOR_SPEED_FLAG)
262+
set(LINKER_OPTIMIZE_FOR_SPEED_FLAG ${COMPILER_OPTIMIZE_FOR_SPEED_FLAG})
263+
endif()
264+
if(NOT LINKER_OPTIMIZE_FOR_SIZE_FLAG)
265+
set(LINKER_OPTIMIZE_FOR_SIZE_FLAG ${COMPILER_OPTIMIZE_FOR_SIZE_FLAG})
266+
endif()
267+
if(NOT LINKER_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG)
268+
set(LINKER_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG ${COMPILER_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG})
269+
endif()
270+
247271
# From kconfig choice, pick the actual OPTIMIZATION_FLAG to use.
248272
# Kconfig choice ensures only one of these CONFIG_*_OPTIMIZATIONS is set.
249273
if(CONFIG_NO_OPTIMIZATIONS)
250274
set(COMPILER_OPTIMIZATION_FLAG ${COMPILER_OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG})
251275
set(ASM_OPTIMIZATION_FLAG ${ASM_OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG})
276+
set(LINKER_OPTIMIZATION_FLAG ${LINKER_OPTIMIZE_FOR_NO_OPTIMIZATIONS_FLAG})
252277
elseif(CONFIG_DEBUG_OPTIMIZATIONS)
253278
set(COMPILER_OPTIMIZATION_FLAG ${COMPILER_OPTIMIZE_FOR_DEBUG_FLAG})
254279
set(ASM_OPTIMIZATION_FLAG ${ASM_OPTIMIZE_FOR_DEBUG_FLAG})
280+
set(LINKER_OPTIMIZATION_FLAG ${LINKER_OPTIMIZE_FOR_DEBUG_FLAG})
255281
elseif(CONFIG_SPEED_OPTIMIZATIONS)
256282
set(COMPILER_OPTIMIZATION_FLAG ${COMPILER_OPTIMIZE_FOR_SPEED_FLAG})
257283
set(ASM_OPTIMIZATION_FLAG ${ASM_OPTIMIZE_FOR_SPEED_FLAG})
284+
set(LINKER_OPTIMIZATION_FLAG ${LINKER_OPTIMIZE_FOR_SPEED_FLAG})
258285
elseif(CONFIG_SIZE_OPTIMIZATIONS)
259286
set(COMPILER_OPTIMIZATION_FLAG ${COMPILER_OPTIMIZE_FOR_SIZE_FLAG}) # Default in kconfig
260287
set(ASM_OPTIMIZATION_FLAG ${ASM_OPTIMIZE_FOR_SIZE_FLAG})
288+
set(LINKER_OPTIMIZATION_FLAG ${LINKER_OPTIMIZE_FOR_SIZE_FLAG})
261289
elseif(CONFIG_SIZE_OPTIMIZATIONS_AGGRESSIVE)
262290
set(COMPILER_OPTIMIZATION_FLAG ${COMPILER_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG})
263291
set(ASM_OPTIMIZATION_FLAG ${ASM_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG})
292+
set(LINKER_OPTIMIZATION_FLAG ${LINKER_OPTIMIZE_FOR_SIZE_AGGRESSIVE_FLAG})
264293
else()
265294
message(FATAL_ERROR
266295
"Unreachable code. Expected optimization level to have been chosen. See Kconfig.zephyr")
@@ -277,6 +306,9 @@ endif()
277306
zephyr_compile_options($<$<COMPILE_LANGUAGE:ASM>:${ASM_OPTIMIZATION_FLAG}>)
278307
zephyr_compile_options($<$<COMPILE_LANGUAGE:C>:${COMPILER_OPTIMIZATION_FLAG}>)
279308
zephyr_compile_options($<$<COMPILE_LANGUAGE:CXX>:${COMPILER_OPTIMIZATION_FLAG}>)
309+
add_link_options(${LINKER_OPTIMIZATION_FLAG})
310+
compiler_simple_options(simple_options)
311+
toolchain_linker_add_compiler_options(${simple_options})
280312

281313
if(CONFIG_LTO)
282314
zephyr_compile_options($<TARGET_PROPERTY:compiler,optimization_lto>)
@@ -2371,6 +2403,9 @@ add_subdirectory_ifdef(
23712403
cmake/makefile_exports
23722404
)
23732405

2406+
# Ask the compiler to set the lib_include_dir and rt_library properties
2407+
compiler_set_linker_properties()
2408+
23742409
toolchain_linker_finalize()
23752410

23762411
# export build information

cmake/compiler/clang/target.cmake

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,21 +100,6 @@ if(NOT "${ARCH}" STREQUAL "posix")
100100
endif()
101101
endif()
102102

103-
# This libgcc code is partially duplicated in compiler/*/target.cmake
104-
execute_process(
105-
COMMAND ${CMAKE_C_COMPILER} ${clang_target_flag} ${TOOLCHAIN_C_FLAGS}
106-
--print-libgcc-file-name
107-
OUTPUT_VARIABLE RTLIB_FILE_NAME
108-
OUTPUT_STRIP_TRAILING_WHITESPACE
109-
)
110-
111-
get_filename_component(RTLIB_DIR ${RTLIB_FILE_NAME} DIRECTORY)
112-
get_filename_component(RTLIB_NAME_WITH_PREFIX ${RTLIB_FILE_NAME} NAME_WLE)
113-
string(REPLACE lib "" RTLIB_NAME ${RTLIB_NAME_WITH_PREFIX})
114-
115-
set_property(TARGET linker PROPERTY lib_include_dir "-L${RTLIB_DIR}")
116-
set_property(TARGET linker PROPERTY rt_library "-l${RTLIB_NAME}")
117-
118103
list(APPEND CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags})
119104
string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
120105

cmake/compiler/gcc/target.cmake

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,6 @@ if(SYSROOT_DIR)
9898
set(LIBC_LIBRARY_DIR "\"${SYSROOT_DIR}\"/lib/${NEWLIB_DIR}")
9999
endif()
100100

101-
# This libgcc code is partially duplicated in compiler/*/target.cmake
102-
execute_process(
103-
COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} --print-libgcc-file-name
104-
OUTPUT_VARIABLE LIBGCC_FILE_NAME
105-
OUTPUT_STRIP_TRAILING_WHITESPACE
106-
)
107-
108-
assert_exists(LIBGCC_FILE_NAME)
109-
110-
get_filename_component(LIBGCC_DIR ${LIBGCC_FILE_NAME} DIRECTORY)
111-
112-
assert_exists(LIBGCC_DIR)
113-
114-
set_linker_property(PROPERTY lib_include_dir "-L\"${LIBGCC_DIR}\"")
115-
116101
# For CMake to be able to test if a compiler flag is supported by the
117102
# toolchain we need to give CMake the necessary flags to compile and
118103
# link a dummy C file.

cmake/compiler/icx/target.cmake

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,6 @@ else()
4545
list(APPEND TOOLCHAIN_C_FLAGS "-m32")
4646
endif()
4747

48-
49-
# This libgcc code is partially duplicated in compiler/*/target.cmake
50-
execute_process(
51-
COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} --print-libgcc-file-name
52-
OUTPUT_VARIABLE LIBGCC_FILE_NAME
53-
OUTPUT_STRIP_TRAILING_WHITESPACE
54-
)
55-
56-
get_filename_component(LIBGCC_DIR ${LIBGCC_FILE_NAME} DIRECTORY)
57-
58-
list(APPEND LIB_INCLUDE_DIR "-L\"${LIBGCC_DIR}\"")
59-
if(LIBGCC_DIR)
60-
list(APPEND TOOLCHAIN_LIBS gcc)
61-
endif()
62-
6348
set(CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags})
6449
string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
6550

cmake/compiler/target_template.cmake

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Copyright (c) 2025, Nordic Semiconductor ASA
4+
5+
# Template file for optional Zephyr compiler functions.
6+
#
7+
# This file will define optional compiler functions for toolchains that are not
8+
# defining these functions themselves.
9+
10+
# Extract all of the compiler options which don't involve generator
11+
# expressions. We hope that none of the flags required to compute compiler
12+
# support library paths depend upon those.
13+
14+
function(compiler_simple_options simple_options_out)
15+
16+
get_property(flags TARGET zephyr_interface PROPERTY INTERFACE_COMPILE_OPTIONS)
17+
18+
set(simple_options "")
19+
20+
foreach(flag ${flags})
21+
22+
# Include this flag if GENEX_STRIP has no effect,
23+
# otherwise skip the whole thing
24+
25+
string(GENEX_STRIP "${flag}" sflag)
26+
if(flag STREQUAL sflag)
27+
if(flag MATCHES "^SHELL:[ ]*(.*)")
28+
separate_arguments(flag UNIX_COMMAND ${CMAKE_MATCH_1})
29+
endif()
30+
list(APPEND simple_options ${flag})
31+
endif()
32+
33+
endforeach()
34+
35+
set(${simple_options_out} "${simple_options}" PARENT_SCOPE)
36+
endfunction()
37+
38+
if(NOT COMMAND compiler_file_path)
39+
40+
# Search for filename in default compiler library path using the
41+
# --print-file-name option which is common to gcc and clang. If the
42+
# file is not found, filepath_out will be set to an empty string.
43+
#
44+
# This only works if none of the compiler flags used to compute
45+
# the library path involve generator expressions as we cannot
46+
# evaluate those in this function.
47+
#
48+
# Compilers needing a different implementation should provide this
49+
# function in their target.cmake file
50+
51+
function(compiler_file_path filename filepath_out)
52+
53+
compiler_simple_options(simple_options)
54+
55+
execute_process(
56+
COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} ${COMPILER_OPTIMIZATION_FLAG} ${simple_options}
57+
--print-file-name ${filename}
58+
OUTPUT_VARIABLE filepath
59+
OUTPUT_STRIP_TRAILING_WHITESPACE
60+
)
61+
if(${filepath} STREQUAL ${filename})
62+
set(filepath "")
63+
endif()
64+
set(${filepath_out} "${filepath}" PARENT_SCOPE)
65+
endfunction()
66+
67+
endif()
68+
69+
if(NOT COMMAND compiler_set_linker_properties)
70+
71+
# Set the lib_include_dir and rt_library linker properties
72+
# by searching for the runtime library in the compiler default
73+
# library search path. If no runtime library is found, these
74+
# properties will remain unset
75+
#
76+
# Compilers needing a different implementation should provide this
77+
# function in their target.cmake file
78+
79+
function(compiler_set_linker_properties)
80+
81+
compiler_simple_options(simple_options)
82+
83+
# Compute complete path to the runtime library using the
84+
# --print-libgcc-file-name compiler flag
85+
execute_process(
86+
COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} ${COMPILER_OPTIMIZATION_FLAG} ${simple_options}
87+
--print-libgcc-file-name
88+
OUTPUT_VARIABLE library_path
89+
OUTPUT_STRIP_TRAILING_WHITESPACE
90+
)
91+
92+
# Compute the library directory name
93+
94+
get_filename_component(library_dir ${library_path} DIRECTORY)
95+
set_linker_property(PROPERTY lib_include_dir "-L${library_dir}")
96+
97+
# Compute the linker option for this library
98+
99+
get_filename_component(library_basename ${library_path} NAME_WLE)
100+
101+
# Remove the leading 'lib' prefix to leave a value suitable for use with
102+
# the linker -l flag
103+
string(REPLACE lib "" library_name ${library_basename})
104+
105+
set_linker_property(PROPERTY rt_library "-l${library_name}")
106+
endfunction()
107+
108+
endif()

cmake/compiler/xcc/target.cmake

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,6 @@ foreach(file_name include/stddef.h include-fixed/limits.h)
5555
endif()
5656
endforeach()
5757

58-
# This libgcc code is partially duplicated in compiler/*/target.cmake
59-
execute_process(
60-
COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} --print-libgcc-file-name
61-
OUTPUT_VARIABLE LIBGCC_FILE_NAME
62-
OUTPUT_STRIP_TRAILING_WHITESPACE
63-
)
64-
65-
get_filename_component(LIBGCC_DIR ${LIBGCC_FILE_NAME} DIRECTORY)
66-
67-
list(APPEND LIB_INCLUDE_DIR "-L\"${LIBGCC_DIR}\"")
68-
6958
# For CMake to be able to test if a compiler flag is supported by the
7059
# toolchain we need to give CMake the necessary flags to compile and
7160
# link a dummy C file.

cmake/linker/ld/target.cmake

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,25 @@ macro(toolchain_linker_finalize)
159159

160160
set(cpp_link "${common_link}")
161161
if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "host")
162-
if(CONFIG_CPP_EXCEPTIONS AND LIBGCC_DIR)
162+
compiler_file_path(crtbegin.o CRTBEGIN_PATH)
163+
compiler_file_path(crtend.o CRTEND_PATH)
164+
if(CONFIG_CPP_EXCEPTIONS AND CRTBEGIN_PATH AND CRTEND_PATH)
163165
# When building with C++ Exceptions, it is important that crtbegin and crtend
164166
# are linked at specific locations.
165-
set(cpp_link "<LINK_FLAGS> ${LIBGCC_DIR}/crtbegin.o ${link_libraries} ${LIBGCC_DIR}/crtend.o")
167+
set(cpp_link "<LINK_FLAGS> ${CRTBEGIN_PATH} ${link_libraries} ${CRTEND_PATH}")
166168
endif()
167169
endif()
168170
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> ${cpp_link}")
169171
endmacro()
170172

173+
# Function to map compiler flags into suitable linker flags
174+
# When using the compiler driver to run the linker, just pass
175+
# them all through
176+
177+
function(toolchain_linker_add_compiler_options)
178+
add_link_options(${ARGV})
179+
endfunction()
180+
171181
# Load toolchain_ld-family macros
172182
include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_relocation.cmake)
173183
include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake)

cmake/linker/lld/target.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ macro(toolchain_linker_finalize)
128128
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> ${common_link}")
129129
endmacro()
130130

131+
# Function to map compiler flags into suitable linker flags
132+
# When using the compiler driver to run the linker, just pass
133+
# them all through
134+
135+
function(toolchain_linker_add_compiler_options)
136+
add_link_options(${ARGV})
137+
endfunction()
138+
131139
# Load toolchain_ld-family macros
132140
include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake)
133141
include(${ZEPHYR_BASE}/cmake/linker/ld/target_configure.cmake)

cmake/linker/target_template.cmake

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,13 @@ if(NOT COMMAND toolchain_linker_finalize)
1111
macro(toolchain_linker_finalize)
1212
endmacro()
1313
endif()
14+
15+
if(NOT COMMAND toolchain_linker_add_compiler_options)
16+
17+
# If the linker doesn't provide a method for mapping compiler options
18+
# to linker options, then assume we can't. This matters when the linker
19+
# is using additional flags when computing toolchain library paths.
20+
21+
function(toolchain_linker_add_compiler_options)
22+
endfunction()
23+
endif()

cmake/linker/xt-ld/target.cmake

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ find_program(CMAKE_LINKER xt-ld ${LD_SEARCH_PATH})
1111

1212
set_ifndef(LINKERFLAGPREFIX -Wl)
1313

14-
if(CONFIG_CPP_EXCEPTIONS)
14+
compiler_file_path(crtbegin.o CRTBEGIN_PATH)
15+
compiler_file_path(crtend.o CRTEND_PATH)
16+
if(CONFIG_CPP_EXCEPTIONS AND CRTBEGIN_PATH AND CRTEND_PATH)
1517
# When building with C++ Exceptions, it is important that crtbegin and crtend
1618
# are linked at specific locations.
1719
# The location is so important that we cannot let this be controlled by normal
1820
# link libraries, instead we must control the link command specifically as
1921
# part of toolchain.
2022
set(CMAKE_CXX_LINK_EXECUTABLE
21-
"<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${LIBGCC_DIR}/crtbegin.o <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${LIBGCC_DIR}/crtend.o")
23+
"<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> ${CRTBEGIN_PATH} <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${CRTEND_PATH}")
2224
endif()
2325

2426
# Run $LINKER_SCRIPT file through the C preprocessor, producing ${linker_script_gen}
@@ -156,6 +158,14 @@ macro(toolchain_linker_finalize)
156158
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> ${common_link}")
157159
endmacro()
158160

161+
# Function to map compiler flags into suitable linker flags
162+
# When using the compiler driver to run the linker, just pass
163+
# them all through
164+
165+
function(toolchain_linker_add_compiler_options)
166+
add_link_options(${ARGV})
167+
endfunction()
168+
159169
# xt-ld is Xtensa's own version of binutils' ld.
160170
# So we can reuse most of the ld configurations.
161171
include(${ZEPHYR_BASE}/cmake/linker/ld/target_relocation.cmake)

0 commit comments

Comments
 (0)