232 lines
7.0 KiB
CMake
232 lines
7.0 KiB
CMake
cmake_minimum_required(VERSION 3.19)
|
|
include(cmake/Utilities.cmake)
|
|
include(cmake/GetGitRevisionDescription.cmake)
|
|
include(cmake/ProjectVersion.cmake)
|
|
include(cmake/ReproducibleBuild.cmake)
|
|
|
|
project(
|
|
MMU
|
|
LANGUAGES C CXX ASM
|
|
VERSION ${PROJECT_VERSION}
|
|
)
|
|
|
|
#
|
|
# Command Line Options
|
|
#
|
|
# You should specify those options when invoking CMake. Example:
|
|
# ~~~
|
|
# cmake .. <other options> -DCUSTOM_COMPILE_OPTIONS=-DENABLE_FEATURE_X
|
|
# ~~~
|
|
|
|
set(PROJECT_VERSION_SUFFIX
|
|
"<auto>"
|
|
CACHE
|
|
STRING
|
|
"Full version suffix to be shown on the info screen in settings (e.g. full_version=4.0.3-BETA+1035.PR111.B4, suffix=-BETA+1035.PR111.B4). Defaults to '+<commit sha>.<dirty?>.<debug?>' if set to '<auto>'."
|
|
)
|
|
set(PROJECT_VERSION_SUFFIX_SHORT
|
|
"<auto>"
|
|
CACHE
|
|
STRING
|
|
"Short version suffix to be shown on splash screen. Defaults to '+<BUILD_NUMBER>' if set to '<auto>'."
|
|
)
|
|
set(BUILD_NUMBER
|
|
""
|
|
CACHE STRING "Build number of the firmware. Resolved automatically if not specified."
|
|
)
|
|
set(CUSTOM_COMPILE_OPTIONS
|
|
""
|
|
CACHE STRING "Allows adding custom C/C++ flags"
|
|
)
|
|
|
|
# Resolve BUILD_NUMBER and PROJECT_VERSION_* variables
|
|
resolve_version_variables()
|
|
|
|
add_compile_definitions(
|
|
PROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
|
|
PROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR}
|
|
PROJECT_VERSION_REV=${PROJECT_VERSION_REV}
|
|
PROJECT_BUILD_NUMBER=${BUILD_NUMBER}
|
|
FW_VERSION_FULL_STR="${PROJECT_VERSION_FULL}"
|
|
FW_VERSION_STR="${PROJECT_VERSION}"
|
|
FW_VERSION_SUFFIX_STR="${PROJECT_VERSION_SUFFIX}"
|
|
FW_VERSION_SUFFIX_SHORT_STR="${PROJECT_VERSION_SUFFIX_SHORT}"
|
|
)
|
|
|
|
# Check GCC Version
|
|
get_recommended_gcc_version(RECOMMENDED_TOOLCHAIN_VERSION)
|
|
if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL
|
|
${RECOMMENDED_TOOLCHAIN_VERSION}
|
|
)
|
|
message(WARNING "Recommended AVR toolchain is ${RECOMMENDED_TOOLCHAIN_VERSION}"
|
|
", but you have ${CMAKE_CXX_COMPILER_VERSION}"
|
|
)
|
|
|
|
elseif(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
message(
|
|
WARNING
|
|
"Recommended compiler for host tools and unittests is GCC, you have ${CMAKE_CXX_COMPILER_ID}."
|
|
)
|
|
endif()
|
|
|
|
# Inform user about the resolved settings
|
|
message(STATUS "Project version: ${PROJECT_VERSION}")
|
|
message(STATUS "Project version with full suffix: ${PROJECT_VERSION_FULL}")
|
|
message(
|
|
STATUS "Project version with short suffix: ${PROJECT_VERSION}${PROJECT_VERSION_SUFFIX_SHORT}"
|
|
)
|
|
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.")
|
|
|
|
# eclipse sets those variables, so lets just use them so we don't get a warning about unused
|
|
# variables
|
|
set(unused "${CMAKE_VERBOSE_MAKEFILE} ${CMAKE_RULE_MESSAGES}")
|
|
|
|
# append custom C/C++ flags
|
|
if(CUSTOM_COMPILE_OPTIONS)
|
|
string(REPLACE " " ";" CUSTOM_COMPILE_OPTIONS "${CUSTOM_COMPILE_OPTIONS}")
|
|
add_compile_options(${CUSTOM_COMPILE_OPTIONS})
|
|
endif()
|
|
|
|
#
|
|
# Global Compiler & Linker Configuration
|
|
#
|
|
|
|
# include symbols
|
|
add_compile_options(-g)
|
|
|
|
# optimizations
|
|
if(CMAKE_CROSSCOMPILING)
|
|
# 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")
|
|
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: It would be nice to add "-mrelax" but due to some avr-gcc/linker bug it
|
|
# breaks functionality of the FW (LoadFilament stopped working and only return Finished) The bad
|
|
# news is that -mrelax was saving ~450B of CPU FLASH
|
|
set(MCU_FLAGS -mmcu=atmega32u4 -DF_CPU=16000000L)
|
|
add_compile_options(${MCU_FLAGS})
|
|
add_link_options(${MCU_FLAGS})
|
|
|
|
# disable some C++ language features
|
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-threadsafe-statics>)
|
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>)
|
|
|
|
# disable exceptions
|
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>)
|
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-unwind-tables>)
|
|
|
|
# split and gc sections
|
|
add_compile_options(-ffunction-sections -fdata-sections)
|
|
add_link_options(-ffunction-sections -fdata-sections -Wl,--gc-sections)
|
|
else()
|
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
add_compile_options(-O0)
|
|
else()
|
|
add_compile_options(-O2)
|
|
endif()
|
|
endif()
|
|
|
|
# enable all warnings (well, not all, but some)
|
|
add_compile_options(-Wall -Wsign-compare)
|
|
|
|
# support _DEBUG macro (some code uses to recognize debug builds)
|
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
add_compile_definitions(_DEBUG)
|
|
endif()
|
|
|
|
#
|
|
# Import definitions of all libraries
|
|
#
|
|
|
|
add_subdirectory(lib)
|
|
|
|
#
|
|
# MMU firmware
|
|
#
|
|
|
|
add_executable(firmware)
|
|
|
|
set_target_properties(firmware PROPERTIES CXX_STANDARD 17)
|
|
set_target_properties(firmware PROPERTIES INTERPROCEDURAL_OPTIMIZATION True)
|
|
|
|
if(CMAKE_CROSSCOMPILING)
|
|
#[[
|
|
# configure linker script
|
|
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/src/avr5.xn)
|
|
target_link_options(firmware PUBLIC -Wl,-T,${LINKER_SCRIPT})
|
|
add_link_dependency(firmware ${LINKER_SCRIPT})
|
|
#]]
|
|
|
|
# limit the text section to 28K (32K - 4k reserved for the bootloader)
|
|
target_link_options(firmware PUBLIC -Wl,--defsym=__TEXT_REGION_LENGTH__=28K)
|
|
|
|
# generate firmware .hex file
|
|
objcopy(firmware "ihex" ".hex")
|
|
|
|
get_dependency_directory(prusa3dboards PRUSA_BOARDS_DIR)
|
|
|
|
add_custom_command(
|
|
TARGET firmware
|
|
POST_BUILD
|
|
COMMAND
|
|
${CMAKE_OBJCOPY} -I ihex -O binary
|
|
${PRUSA_BOARDS_DIR}/bootloaders/prusa_mm_control/Caterina-prusa_mm_control.hex bootloader.bin
|
|
COMMAND ${CMAKE_OBJCOPY} firmware -O binary firmware.bin
|
|
COMMAND ${CMAKE_COMMAND} -E cat bootloader.bin firmware.bin > fw_bootloader.bin
|
|
COMMAND ${CMAKE_OBJCOPY} -I binary -O ihex fw_bootloader.bin
|
|
"MMU2SR_${PROJECT_VERSION}${PROJECT_VERSION_SUFFIX_SHORT}_bootloader.hex"
|
|
BYPRODUCTS bootloader.bin firmware.bin fw_bootloader.bin
|
|
)
|
|
|
|
# produce ASM listing
|
|
add_custom_command(
|
|
TARGET firmware
|
|
POST_BUILD
|
|
COMMAND ${CMAKE_OBJDUMP} --prefix ${CMAKE_SOURCE_DIR} -CSd firmware > firmware.asm
|
|
BYPRODUCTS 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
|
|
)
|
|
report_size(firmware)
|
|
|
|
# generate linker map file
|
|
target_link_options(firmware PUBLIC -Wl,-Map=firmware.map)
|
|
|
|
# Put Prusa Magic™ at the beginning of the hex
|
|
add_custom_command(
|
|
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
|
|
)
|
|
|
|
endif()
|
|
|
|
target_include_directories(firmware PRIVATE src lib)
|
|
|
|
target_compile_options(firmware PRIVATE -Wdouble-promotion)
|
|
|
|
add_subdirectory(src)
|
|
|
|
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)
|
|
|
|
enable_testing()
|
|
add_subdirectory(tests)
|
|
endif()
|