diff --git a/CMakeLists.txt b/CMakeLists.txt index c7e499304b..d684bbd9c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,11 @@ if(CONFIG_COMPILER_DUMP_RTL_FILES) list(APPEND compile_options "-fdump-rtl-expand") endif() +if(CONFIG_COMPILER_HIDE_PATHS_MACROS) + list(APPEND compile_options "-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.") + list(APPEND compile_options "-fmacro-prefix-map=${IDF_PATH}=IDF") +endif() + # GCC-specific options if(CMAKE_C_COMPILER_ID STREQUAL "GNU") list(APPEND compile_options "-fstrict-volatile-bitfields" diff --git a/Kconfig b/Kconfig index 1d498baf59..6ea56d39ac 100644 --- a/Kconfig +++ b/Kconfig @@ -279,6 +279,22 @@ mainmenu "Espressif IoT Development Framework Configuration" endchoice # assertions + menuconfig COMPILER_HIDE_PATHS_MACROS + bool "Replace ESP-IDF and project paths in binaries" + default y + depends on IDF_CMAKE + help + When expanding the __FILE__ and __BASE_FILE__ macros, replace paths inside ESP-IDF + with paths relative to the placeholder string "IDF", and convert paths inside the + project directory to relative paths. + + This allows building the project with assertions or other code that embeds file paths, + without the binary containing the exact path to the IDF or project directories. + + This option passes -fmacro-prefix-map options to the GCC command line. To replace additional + paths in your binaries, modify the project CMakeLists.txt file to pass custom -fmacro-prefix-map or + -ffile-prefix-map arguments. + menuconfig COMPILER_CXX_EXCEPTIONS bool "Enable C++ exceptions" default n diff --git a/tools/test_apps/system/no_embedded_paths/CMakeLists.txt b/tools/test_apps/system/no_embedded_paths/CMakeLists.txt index e6fdc3cb6b..4edc089d8e 100644 --- a/tools/test_apps/system/no_embedded_paths/CMakeLists.txt +++ b/tools/test_apps/system/no_embedded_paths/CMakeLists.txt @@ -9,9 +9,11 @@ idf_build_get_property(idf_path IDF_PATH) idf_build_get_property(python PYTHON) idf_build_get_property(elf EXECUTABLE) -# If the configuration is one that doesn't expect any paths to be found then run this build step +# If the configuration is one that doesn't expect the IDF_PATH to be found in binaries then run this build step # after building the ELF, will fail if it finds any file paths in binary files -if(CONFIG_OPTIMIZATION_ASSERTIONS_SILENT OR CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED) +if(CONFIG_OPTIMIZATION_ASSERTIONS_SILENT OR + CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED OR + CONFIG_COMPILER_HIDE_PATHS_MACROS) add_custom_command( TARGET ${elf} POST_BUILD diff --git a/tools/test_apps/system/no_embedded_paths/README.md b/tools/test_apps/system/no_embedded_paths/README.md index 32a9312a32..5206c2df8e 100644 --- a/tools/test_apps/system/no_embedded_paths/README.md +++ b/tools/test_apps/system/no_embedded_paths/README.md @@ -3,12 +3,12 @@ This test app exists to verify that paths (like __FILE__) are not compiled into any object files in configurations where this should be avoided. -It doubles up as a build-time check that disabling assertions doesn't lead to -any warnings. +Configurations where this is relevant include: -(These configurations include: assertions disabled, 'silent' asserts, any reproducible -builds configuration.) +* Assertions disabled (doubles up as a build-time check that disabling assertions doesn't lead to any warnings) +* Silent assertions +* CONFIG_COMPILER_HIDE_PATHS_MACROS is set to replace IDF_PATH and project dir with placeholders when expanding `__FILE__` Not embedding paths reduces the binary size, avoids leaking information about -the compilation environment, and is a necessary step to supporet reproducible +the compilation environment, and is a necessary step to support reproducible builds across projects built in different directories. diff --git a/tools/test_apps/system/no_embedded_paths/main/test_no_embedded_paths_main.c b/tools/test_apps/system/no_embedded_paths/main/test_no_embedded_paths_main.c index c6d6340883..7fce3f7efc 100644 --- a/tools/test_apps/system/no_embedded_paths/main/test_no_embedded_paths_main.c +++ b/tools/test_apps/system/no_embedded_paths/main/test_no_embedded_paths_main.c @@ -1,4 +1,14 @@ -/* This test app only exists for the build stage, so doesn't need to do anything at runtime */ +/* This test app only exists for the build stage, so doesn't need to do anything at runtime + apart from embedding an assert to check asserts inside the project dir */ +#include + +// Declared non-static to avoid the assert being optimized out +int other_function(void) +{ + return 3; +} + void app_main(void) { + assert(other_function() == 3); } diff --git a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.noasserts b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.noasserts index 446a04da0b..22cb4d70ea 100644 --- a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.noasserts +++ b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.noasserts @@ -1,5 +1,6 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y CONFIG_FREERTOS_ASSERT_DISABLE=y +CONFIG_COMPILER_HIDE_PATHS_MACROS=n # compiling as many files as possible here (we don't have 100% coverage of course, due to config options, but # try to maximize what we can check diff --git a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.noasserts.nimble b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.noasserts.nimble index b91ad2022d..7d8ccfe182 100644 --- a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.noasserts.nimble +++ b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.noasserts.nimble @@ -1,5 +1,6 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y CONFIG_FREERTOS_ASSERT_DISABLE=y +CONFIG_COMPILER_HIDE_PATHS_MACROS=n # the other sdkconfig builds Bluedroid, build NimBLE here # diff --git a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.replacepaths b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.replacepaths new file mode 100644 index 0000000000..966b86d989 --- /dev/null +++ b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.replacepaths @@ -0,0 +1,8 @@ +# this is the default value, actually +CONFIG_COMPILER_HIDE_PATHS_MACROS=y + +# compiling as many files as possible here (we don't have 100% coverage of course, due to config options, but +# try to maximize what we can check +CONFIG_BT_ENABLED=y +CONFIG_BT_BLUEDROID_ENABLED=y +CONFIG_BLE_MESH=y diff --git a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.silentasserts b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.silentasserts index 9b54479ee9..f75fef7686 100644 --- a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.silentasserts +++ b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.silentasserts @@ -1,4 +1,5 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +CONFIG_COMPILER_HIDE_PATHS_MACROS=n # compiling as many files as possible here (we don't have 100% coverage of course, due to config options, but # try to maximize what we can check diff --git a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.silentasserts.nimble b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.silentasserts.nimble index ab0cd5aa6d..640f0fd2e1 100644 --- a/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.silentasserts.nimble +++ b/tools/test_apps/system/no_embedded_paths/sdkconfig.ci.silentasserts.nimble @@ -1,5 +1,6 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y CONFIG_FREERTOS_ASSERT_DISABLE=y +CONFIG_COMPILER_HIDE_PATHS_MACROS=n # the other sdkconfig builds Bluedroid, build NimBLE here #