Selectively controlling optimization levels in Zephyr project

We are building a Zephyr project as a freestanding application.  Is there a way to compile all Zephyr libraries optimized for size but not optimize our application files?  We've found that having optimization disabled gave us the best debugging experience.  However, when we build with optimization or even -Og, the generated code exceeds the allocated flash memory.  Therefore, we'd  like to selectively choose which application files (app PRIVATE) are not optimized.

Here's an incomplete example of our cmakelists file....

set(CONF_FILE "prj.${CMAKE_BUILD_TYPE}.conf" "prj.common.conf")
set(ENV{ZEPHYR_BASE} "../../../../../ncs/zephyr")
set(BOARD_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../PM_FW/Build")

set(BOARD nrf5340)

message(STATUS "CMAKE_BUILD_TYPE VALUE: ${CMAKE_BUILD_TYPE}")

cmake_minimum_required(VERSION 3.20.0)
# Use minimum Zephyr release
find_package(Zephyr 3.2.99 REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(ourapp C ASM)
list(APPEND Common_SOURCES

"${CMAKE_CURRENT_SOURCE_DIR}/../../../../PMLib/PMCOMMON_Lib/ap_globals.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_spim.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_usbd.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_usbreg.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_pwm.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_qspi.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_usbreg.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_rtc.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_saadc.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_gpiote.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_nvmc.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_uarte.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../../../ncs/modules/hal/nordic/nrfx/drivers/src/nrfx_dppi.c"
)

target_sources(app PRIVATE
${Common_SOURCES}
)
  • Meddeling with compiler options is going to be a nightmare in the Cmakelists.

    I recommend selectively using different optimization for code to be debugged only via gcc #pragma (tutorial).

    This allows you to set optimization for specific funtions only.

  • Thank you!  I've been able to test your recommendations.

    It's unfortunate such a flexible tool ends up being inflexible due to the complexity of the build scripts.  I've done a lot of development with the IAR compilers and it's very easy to selectively control which files/libraries get optimized.

  • Hi,

    I am not a CMake expert, so beware of unforeseen side-effects.
    But I think I found something that might work:

    So first I looked for how to override a single file in CMake, and found this: https://stackoverflow.com/questions/13638408/override-compile-flags-for-single-files.

    The nRF Connect SDK does a lot of things, and we only want to change the optimization flag. However, set_source_files_properties() looks like it overrides the flags of a file.
    So lets find the flags set by our  build system.

    There might be an easier/automated way to get the flash, but I found that if we build with "CONFIG_MAKEFILE_EXPORTS=y", the build generates the file "build/Makefile.exports.C", in where we can find

    Z_CFLAGS = -I/home/bruk/nrf_connect_sdk/zephyr/include -I/home/bruk/nrf_connect_sdk/zephyr/samples/hello_world/build/zephyr/include/generated -I/home/bruk/nrf_connect_sdk/zephyr/soc/arm/nordic_nrf/nrf52 -I/home/bruk/nrf_connect_sdk/zephyr/lib/libc/minimal/include -I/home/bruk/nrf_connect_sdk/zephyr/soc/arm/nordic_nrf/common/. -I/home/bruk/nrf_connect_sdk/nrf/include -I/home/bruk/nrf_connect_sdk/nrf/tests/include -I/home/bruk/nrf_connect_sdk/modules/hal/cmsis/CMSIS/Core/Include -I/home/bruk/nrf_connect_sdk/modules/hal/nordic/nrfx -I/home/bruk/nrf_connect_sdk/modules/hal/nordic/nrfx/drivers/include -I/home/bruk/nrf_connect_sdk/modules/hal/nordic/nrfx/mdk -I/home/bruk/nrf_connect_sdk/zephyr/modules/hal_nordic/nrfx/. -I/home/bruk/nrf_connect_sdk/modules/debug/segger/SEGGER -I/home/bruk/nrf_connect_sdk/modules/debug/segger/Config -I/home/bruk/nrf_connect_sdk/zephyr/modules/segger/. -I/home/bruk/zephyr-sdk-0.15.1/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.1.0/include -I/home/bruk/zephyr-sdk-0.15.1/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.1.0/include-fixed -I/home/bruk/nrf_connect_sdk/zephyr/samples/hello_world/src -I/home/bruk/nrf_connect_sdk/nrfxlib/crypto/nrf_cc310_platform/include -isystem /home/bruk/nrf_connect_sdk/zephyr/lib/libc/minimal/include -isystem /home/bruk/zephyr-sdk-0.15.1/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.1.0/include -isystem /home/bruk/zephyr-sdk-0.15.1/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.1.0/include-fixed -DKERNEL -D__ZEPHYR__=1 -DUSE_PARTITION_MANAGER=0 -D__PROGRAM_START -DNRF52840_XXAA  -fno-strict-aliasing -Os -imacros /home/bruk/nrf_connect_sdk/zephyr/samples/hello_world/build/zephyr/include/generated/autoconf.h -ffreestanding -fno-common -g -gdwarf-4 -fdiagnostics-color=always -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfp16-format=ieee --sysroot=/home/bruk/zephyr-sdk-0.15.1/arm-zephyr-eabi/arm-zephyr-eabi -imacros /home/bruk/nrf_connect_sdk/zephyr/include/zephyr/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wformat -Wno-format-zero-length -Wno-main -Wno-pointer-sign -Wpointer-arith -Wexpansion-to-defined -Wno-unused-but-set-variable -Werror=implicit-int -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fno-reorder-functions --param=min-pagesize=0 -fno-defer-pop -fmacro-prefix-map=/home/bruk/nrf_connect_sdk/zephyr/samples/hello_world=CMAKE_SOURCE_DIR -fmacro-prefix-map=/home/bruk/nrf_connect_sdk/zephyr=ZEPHYR_BASE -fmacro-prefix-map=/home/bruk/nrf_connect_sdk=WEST_TOPDIR -ffunction-sections -fdata-sections -std=c99 -nostdinc 
    

    So I copy this variable to CMakeLists.txt, and use this with set_source_files_properties(). The only difference is that I substitute -Os for -O0 to disable optimization for the selected file.

    Then I stepped through my project using VS Code Debugging, and the debugger skips stuff in main.c, but steps through it in bloat.c. So it looks like it works to me.

    Is this what you were looking for?

    Tested for v2.3.0 and nRF52840DK, but should not really be dependent on board:

    single_file_not_optimized_sample.zip

    Regards,
    Sigurd Hellesvik

  • Thank you Sigurd!  I'll give this a try today.  Your idea of exporting the project build variables was very useful!


    Best,
    Kurt

Related