From 38657f5d777abef5f8167a1e3bd634553f7e6298 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 2 Oct 2022 00:19:32 +0200 Subject: [PATCH 1/6] cmake: Improved way to set default compiler flags --- CMakeLists.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d450716..41d0087 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,11 +95,12 @@ add_compile_options(-g) # optimizations if(CMAKE_CROSSCOMPILING) - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - add_compile_options(-Og) - else() - add_compile_options(-Os) - endif() + + # default optimization flags + set(CMAKE_CXX_FLAGS_DEBUG "-Og -g") + set(CMAKE_CXX_FLAGS_RELEASE "-Os -g -DNDEBUG") + set(CMAKE_C_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + set(CMAKE_C_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) # mcu related settings set(MCU_FLAGS -mmcu=atmega32u4 -DF_CPU=16000000L) From c6b600d62373744efa9d30493fe131eb4b89e21c Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 2 Oct 2022 00:20:02 +0200 Subject: [PATCH 2/6] cmake: Strip prefix from debug info Paves the way for some extra reproducibility. --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d0087..f6a283d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,12 @@ add_compile_options(-g) # optimizations if(CMAKE_CROSSCOMPILING) + # Reproducible build support + add_link_options(-fdebug-prefix-map=${CMAKE_SOURCE_DIR}=) + add_link_options(-fdebug-prefix-map=${CMAKE_BINARY_DIR}=) + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "8") + add_compile_options(-ffile-prefix-map=${CMAKE_SOURCE_DIR}=) + endif() # default optimization flags set(CMAKE_CXX_FLAGS_DEBUG "-Og -g") From 74dfb27c20d45a0850754fe0212aa7cc0daf3bef Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 2 Oct 2022 00:20:45 +0200 Subject: [PATCH 3/6] cmake: Improve AVR target flags - Filter C++-only flags correctly - Split sections correctly at link time with LTO - Remove uneeded linker flags --- CMakeLists.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6a283d..1a4a090 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,14 +113,17 @@ if(CMAKE_CROSSCOMPILING) add_compile_options(${MCU_FLAGS}) add_link_options(${MCU_FLAGS}) + # disable some C++ language features + add_compile_options($<$:-fno-threadsafe-statics>) + add_compile_options($<$:-fno-rtti>) + + # disable exceptions + add_compile_options($<$:-fno-exceptions>) + add_compile_options($<$:-fno-unwind-tables>) + # split and gc sections add_compile_options(-ffunction-sections -fdata-sections) - add_link_options(-Wl,--gc-sections) - - # disable exceptions and related metadata - add_compile_options(-fno-exceptions -fno-unwind-tables) - add_compile_options($<$:-fno-rtti>) - add_link_options(-Wl,--defsym,__exidx_start=0,--defsym,__exidx_end=0) + add_link_options(-ffunction-sections -fdata-sections -Wl,--gc-sections) else() if(CMAKE_BUILD_TYPE STREQUAL "Debug") add_compile_options(-O0) From ea381151529fae26dd4fdee0edd4d3be273b90ad Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 2 Oct 2022 00:22:06 +0200 Subject: [PATCH 4/6] cmake: Generate correct inline source listings in asm output Manually provide a source path prefix to objdump --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a4a090..2fe4ab2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,7 +171,9 @@ if(CMAKE_CROSSCOMPILING) # produce ASM listing add_custom_command( - TARGET firmware POST_BUILD COMMAND ${CMAKE_OBJDUMP} -CSd firmware > firmware.asm + TARGET firmware POST_BUILD + COMMAND + ${CMAKE_OBJDUMP} --prefix ${CMAKE_SOURCE_DIR} -CSd firmware > firmware.asm ) # inform about the firmware's size in terminal From d287ab23572f02c9f985efe6d3a80e88bd023cb7 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 10 Oct 2022 14:18:26 +0200 Subject: [PATCH 5/6] cmake: Full reproducibility support --- CMakeLists.txt | 15 ++++---- cmake/ReproducibleBuild.cmake | 66 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 cmake/ReproducibleBuild.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fe4ab2..556c09e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.19) include(cmake/Utilities.cmake) include(cmake/GetGitRevisionDescription.cmake) include(cmake/ProjectVersion.cmake) +include(cmake/ReproducibleBuild.cmake) project( MMU @@ -95,12 +96,8 @@ add_compile_options(-g) # optimizations if(CMAKE_CROSSCOMPILING) - # Reproducible build support - add_link_options(-fdebug-prefix-map=${CMAKE_SOURCE_DIR}=) - add_link_options(-fdebug-prefix-map=${CMAKE_BINARY_DIR}=) - if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "8") - add_compile_options(-ffile-prefix-map=${CMAKE_SOURCE_DIR}=) - endif() + # TODO: get date from the last git commit to set as epoch + set_source_epoch(0) # default optimization flags set(CMAKE_CXX_FLAGS_DEBUG "-Og -g") @@ -203,7 +200,9 @@ target_compile_options(firmware PRIVATE -Wdouble-promotion) add_subdirectory(src) -if(NOT CMAKE_CROSSCOMPILING) +if(CMAKE_CROSSCOMPILING) + set_all_targets_reproducible() +else() # do not build the firmware by default (tests are the focus if not crosscompiling) set_target_properties(firmware PROPERTIES EXCLUDE_FROM_ALL YES) diff --git a/cmake/ReproducibleBuild.cmake b/cmake/ReproducibleBuild.cmake new file mode 100644 index 0000000..bdc7995 --- /dev/null +++ b/cmake/ReproducibleBuild.cmake @@ -0,0 +1,66 @@ +# +# Functions and utilities for build reproducibility +# + +# Set a target to be reproducible +function(set_reproducible_target target) + # properties for static libraries + set_target_properties(${target} PROPERTIES STATIC_LIBRARY_OPTIONS "-D") + + # properties on executables + target_link_options(${target} PRIVATE -fdebug-prefix-map=${CMAKE_SOURCE_DIR}=) + target_link_options(${target} PRIVATE -fdebug-prefix-map=${CMAKE_BINARY_DIR}=) + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "8") + target_compile_options(${target} PRIVATE -ffile-prefix-map=${CMAKE_SOURCE_DIR}=) + endif() + + # properties on sources + get_target_property(sources ${target} SOURCES) + get_target_property(source_dir ${target} SOURCE_DIR) + foreach(file IN LISTS sources) + cmake_path(ABSOLUTE_PATH file BASE_DIRECTORY ${source_dir}) + cmake_path(RELATIVE_PATH file BASE_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE rpath) + set_property( + SOURCE ${file} + DIRECTORY ${source_dir} + APPEND + PROPERTY COMPILE_OPTIONS "-frandom-seed=${rpath}" + ) + endforeach() +endfunction() + +# Get the list of targets for all directories +function(get_all_targets _result _dir) + get_property( + _subdirs + DIRECTORY "${_dir}" + PROPERTY SUBDIRECTORIES + ) + foreach(_subdir IN LISTS _subdirs) + get_all_targets(${_result} "${_subdir}") + endforeach() + get_directory_property(_sub_targets DIRECTORY "${_dir}" BUILDSYSTEM_TARGETS) + set(${_result} + ${${_result}} ${_sub_targets} + PARENT_SCOPE + ) +endfunction() + +# Make every target reproducible +function(set_all_targets_reproducible) + get_all_targets(targets ${CMAKE_SOURCE_DIR}) + foreach(target IN LISTS targets) + set_reproducible_target(${target}) + endforeach() +endfunction() + +# Set source epoch +function(set_source_epoch epoch) + set(ENV{SOURCE_DATE_EPOCH} ${epoch}) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8") + string(TIMESTAMP SOURCE_DATE_EPOCH "%Y-%m-%d") + add_compile_definitions(SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH}") + string(TIMESTAMP SOURCE_TIME_EPOCH "%H:%M:%S") + add_compile_definitions(SOURCE_TIME_EPOCH="${SOURCE_TIME_EPOCH}") + endif() +endfunction() From 03e1757b0f1a461dff455541c8f4783779460c01 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 10 Oct 2022 14:18:09 +0200 Subject: [PATCH 6/6] cmake: Reformat --- CMakeLists.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 556c09e..86136b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,14 +168,16 @@ if(CMAKE_CROSSCOMPILING) # produce ASM listing add_custom_command( - TARGET firmware POST_BUILD - COMMAND - ${CMAKE_OBJDUMP} --prefix ${CMAKE_SOURCE_DIR} -CSd firmware > firmware.asm + TARGET firmware + POST_BUILD + COMMAND ${CMAKE_OBJDUMP} --prefix ${CMAKE_SOURCE_DIR} -CSd firmware > firmware.asm ) # inform about the firmware's size in terminal add_custom_command( - TARGET firmware POST_BUILD COMMAND ${CMAKE_SIZE_UTIL} -C --mcu=atmega32u4 firmware + TARGET firmware + POST_BUILD + COMMAND ${CMAKE_SIZE_UTIL} -C --mcu=atmega32u4 firmware ) report_size(firmware) @@ -184,12 +186,12 @@ if(CMAKE_CROSSCOMPILING) # Put Prusa Magicâ„¢ at the beginning of the hex add_custom_command( - TARGET firmware POST_BUILD + TARGET firmware + POST_BUILD COMMAND ${CMAKE_COMMAND} -D WORK_DIR=${CMAKE_BINARY_DIR} -D HEX_NAME="MMU2SR_${PROJECT_VERSION}${PROJECT_VERSION_SUFFIX_SHORT}.hex" -P - ${CMAKE_SOURCE_DIR}/cmake/HexConcat.cmake - DEPENDS firmware.hex + ${CMAKE_SOURCE_DIR}/cmake/HexConcat.cmake DEPENDS firmware.hex ) endif()