summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.at>2025-02-25 23:37:17 +0100
committerMarkus Mittendrein <git@maxmitti.at>2025-02-25 23:39:45 +0100
commit1b3d654c764b25cdd979acca0c956564cfe8358d (patch)
tree25b08bca9fb82d4bc7b293d273dc095207e9d0d8 /cmake
downloadmsp432_test-1b3d654c764b25cdd979acca0c956564cfe8358d.tar.gz
msp432_test-1b3d654c764b25cdd979acca0c956564cfe8358d.zip
InitialHEADmaster
Diffstat (limited to 'cmake')
-rw-r--r--cmake/arm-gcc-toolchain.cmake35
-rw-r--r--cmake/clang-arm-gcc-toolchain.cmake91
-rw-r--r--cmake/device.cmake2
-rw-r--r--cmake/device_utils.cmake15
-rw-r--r--cmake/utils.cmake123
5 files changed, 266 insertions, 0 deletions
diff --git a/cmake/arm-gcc-toolchain.cmake b/cmake/arm-gcc-toolchain.cmake
new file mode 100644
index 0000000..d7dc340
--- /dev/null
+++ b/cmake/arm-gcc-toolchain.cmake
@@ -0,0 +1,35 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR ARM)
+
+set(TOOLCHAIN_PREFIX "arm-none-eabi-")
+
+set(SPECS "-specs=nosys.specs -specs=nano.specs")
+
+# Without that flag CMake is not able to pass test compilation check
+if (${CMAKE_VERSION} VERSION_EQUAL "3.6.0" OR ${CMAKE_VERSION} VERSION_GREATER "3.6")
+ set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+endif ()
+
+set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc CACHE STRING "")
+set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER} CACHE STRING "")
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++ CACHE STRING "")
+
+# Default C compiler flags
+set(CMAKE_C_FLAGS_DEBUG_INIT "-g3 -Og -Wall -DDEBUG ${SPECS}")
+set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -Wall ${SPECS}")
+set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -Wall ${SPECS}")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -Wall ${SPECS}")
+# Default C++ compiler flags
+set(CMAKE_CXX_FLAGS_DEBUG_INIT "-g3 -Og -Wall -DDEBUG ${SPECS}")
+set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -Wall ${SPECS}")
+set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -Wall ${SPECS}")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -Wall ${SPECS}")
+
+find_program(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy DOC "objcopy tool")
+find_program(CMAKE_SIZE_UTIL ${TOOLCHAIN_PREFIX}size DOC "size tool")
+
+if (NOT TARGET toolchain)
+ add_library(toolchain INTERFACE)
+ target_compile_options(toolchain INTERFACE "-fno-exceptions")
+ target_link_options(toolchain INTERFACE "-Wl,--gc-sections" "-Wl,--print-memory-usage")
+endif ()
diff --git a/cmake/clang-arm-gcc-toolchain.cmake b/cmake/clang-arm-gcc-toolchain.cmake
new file mode 100644
index 0000000..091dad3
--- /dev/null
+++ b/cmake/clang-arm-gcc-toolchain.cmake
@@ -0,0 +1,91 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR ARM)
+
+set(TOOLCHAIN_PREFIX arm-none-eabi-)
+set(TOOLCHAIN_TRIPLE arm-none-eabi)
+find_program(BINUTILS_PATH ${TOOLCHAIN_PREFIX}gcc NO_CACHE)
+
+if (NOT BINUTILS_PATH)
+ message(FATAL_ERROR "ARM GCC toolchain not found")
+endif ()
+
+cmake_path(GET BINUTILS_PATH PARENT_PATH ARM_TOOLCHAIN_DIR)
+set(ARM_GCC_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
+execute_process(COMMAND ${ARM_GCC_C_COMPILER} -print-sysroot
+ OUTPUT_VARIABLE ARM_GCC_SYSROOT OUTPUT_STRIP_TRAILING_WHITESPACE)
+# get GNU ARM GCC version
+execute_process(COMMAND ${ARM_GCC_C_COMPILER} --version
+ OUTPUT_VARIABLE ARM_GCC_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
+string(REGEX MATCH " [0-9]+\.[0-9]+\.[0-9]+" ARM_GCC_VERSION ${ARM_GCC_VERSION})
+string(STRIP ${ARM_GCC_VERSION} ARM_GCC_VERSION)
+
+# set compiler triple
+set(triple ${TOOLCHAIN_TRIPLE})
+set(CMAKE_ASM_COMPILER clang)
+set(CMAKE_ASM_COMPILER_TARGET ${triple})
+set(CMAKE_C_COMPILER clang)
+set(CMAKE_C_COMPILER_TARGET ${triple})
+set(CMAKE_CXX_COMPILER clang++)
+set(CMAKE_CXX_COMPILER_TARGET ${triple})
+
+set(CMAKE_C_FLAGS_INIT " -B${ARM_TOOLCHAIN_DIR}")
+set(CMAKE_CXX_FLAGS_INIT " -B${ARM_TOOLCHAIN_DIR} ")
+# Without that flag CMake is not able to pass test compilation check
+if (${CMAKE_VERSION} VERSION_EQUAL "3.6.0" OR ${CMAKE_VERSION} VERSION_GREATER "3.6")
+ set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+else ()
+ set(CMAKE_EXE_LINKER_FLAGS_INIT "-nostdlib")
+endif ()
+
+set(CMAKE_OBJCOPY llvm-objcopy CACHE INTERNAL "objcopy tool")
+set(CMAKE_SIZE_UTIL llvm-size CACHE INTERNAL "size tool")
+# Default C compiler flags
+set(CMAKE_C_FLAGS_DEBUG_INIT "-g3 -Og -Wall -pedantic -DDEBUG")
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG_INIT}" CACHE STRING "" FORCE)
+set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -Wall")
+set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE_INIT}" CACHE STRING "" FORCE)
+set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Oz -Wall")
+set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL_INIT}" CACHE STRING "" FORCE)
+set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -Wall")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING "" FORCE)
+# Default C++ compiler flags
+set(TOOLCHAIN_CXX_INCLUDE_DIRS_FLAG "")
+string(APPEND TOOLCHAIN_CXX_INCLUDE_DIRS_FLAG " -cxx-isystem ${ARM_GCC_SYSROOT}/include/c++/${ARM_GCC_VERSION}")
+string(APPEND TOOLCHAIN_CXX_INCLUDE_DIRS_FLAG " -cxx-isystem ${ARM_GCC_SYSROOT}/include/c++/${ARM_GCC_VERSION}/arm-none-eabi")
+string(APPEND TOOLCHAIN_CXX_INCLUDE_DIRS_FLAG " -cxx-isystem ${ARM_GCC_SYSROOT}/include/c++/${ARM_GCC_VERSION}/backward")
+set(CMAKE_CXX_FLAGS_DEBUG_INIT "-g3 -Og -Wall -pedantic -DDEBUG ${TOOLCHAIN_CXX_INCLUDE_DIRS_FLAG}")
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG_INIT}" CACHE STRING "" FORCE)
+set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -Wall ${TOOLCHAIN_CXX_INCLUDE_DIRS_FLAG}")
+set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE_INIT}" CACHE STRING "" FORCE)
+set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Oz -Wall ${TOOLCHAIN_CXX_INCLUDE_DIRS_FLAG}")
+set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT}" CACHE STRING "" FORCE)
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -Wall ${TOOLCHAIN_CXX_INCLUDE_DIRS_FLAG}")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING "" FORCE)
+
+set(CMAKE_SYSROOT ${ARM_GCC_SYSROOT})
+set(CMAKE_FIND_ROOT_PATH ${ARM_GCC_SYSROOT})
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
+
+
+if (ARCH_FLAGS)
+ execute_process(COMMAND ${ARM_GCC_C_COMPILER} ${ARCH_FLAGS} -print-libgcc-file-name
+ OUTPUT_VARIABLE __ARM_GCC_LIBGCC
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ cmake_path(GET __ARM_GCC_LIBGCC PARENT_PATH LIBGCC_DIR)
+
+ execute_process(COMMAND ${ARM_GCC_C_COMPILER} ${ARCH_FLAGS} -print-multi-directory
+ OUTPUT_VARIABLE ARM_GCC_MULTIDIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if (NOT TARGET toolchain)
+ add_library(toolchain INTERFACE)
+ target_compile_options(toolchain INTERFACE "-fno-exceptions")
+ target_link_directories(toolchain INTERFACE "${LIBGCC_DIR}")
+ target_link_libraries(toolchain INTERFACE -nostdlib -lc_nano -lnosys -lgcc -lstdc++_nano -lm)
+ target_link_options(toolchain INTERFACE "-Wl,--gc-sections" "-Wl,--print-memory-usage")
+
+ target_sources(toolchain INTERFACE "${LIBGCC_DIR}/crti.o" "${ARM_GCC_SYSROOT}/lib/${ARM_GCC_MULTIDIR}/crt0.o" "${LIBGCC_DIR}/crtbegin.o" "${LIBGCC_DIR}/crtend.o" "${LIBGCC_DIR}/crtn.o")
+ endif ()
+endif ()
diff --git a/cmake/device.cmake b/cmake/device.cmake
new file mode 100644
index 0000000..d5b28da
--- /dev/null
+++ b/cmake/device.cmake
@@ -0,0 +1,2 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/device/${DEVICE}/${DEVICE}.cmake")
+message(STATUS "Device: ${DEVICE}")
diff --git a/cmake/device_utils.cmake b/cmake/device_utils.cmake
new file mode 100644
index 0000000..5309f5c
--- /dev/null
+++ b/cmake/device_utils.cmake
@@ -0,0 +1,15 @@
+include(utils)
+
+function (create_device_target arch_flags device_defines include_dirs linker_script system_code)
+ add_library(device OBJECT)
+
+ target_sources(device PRIVATE "${system_code}")
+
+ target_compile_options(device PUBLIC "${arch_flags}")
+ target_compile_definitions(device PUBLIC "${device_defines}")
+ target_include_directories(device PRIVATE "${include_dirs}")
+ target_include_directories(device PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/device")
+
+ target_link_options(device INTERFACE "${arch_flags}")
+ target_linker_script(device INTERFACE "${linker_script}")
+endfunction ()
diff --git a/cmake/utils.cmake b/cmake/utils.cmake
new file mode 100644
index 0000000..17fb235
--- /dev/null
+++ b/cmake/utils.cmake
@@ -0,0 +1,123 @@
+# Get all subdirectories under ${current_dir} and store them in ${result} variable
+macro(subdirlist result current_dir)
+ file(GLOB children "${current_dir}/*")
+ set(dirlist "")
+
+ foreach(child ${children})
+ if (IS_DIRECTORY "${child}")
+ list(APPEND dirlist "${child}")
+ endif()
+ endforeach()
+
+ set(${result} ${dirlist})
+endmacro()
+
+# Prepend ${CMAKE_CURRENT_SOURCE_DIR} to a ${directory} name and save it in PARENT_SCOPE ${variable}
+macro(prepend_cur_dir variable directory)
+ set(${variable} "${CMAKE_CURRENT_SOURCE_DIR}/${directory}")
+endmacro()
+
+# Add custom command to print firmware size in Berkeley format
+function(firmware_size target)
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_SIZE_UTIL} -B "$<TARGET_FILE:${target}>"
+ )
+endfunction()
+
+# Add a command to generate firmware in a provided format
+function(generate_object target suffix type)
+ add_custom_command(TARGET ${target} POST_BUILD
+ COMMAND ${CMAKE_OBJCOPY} -O ${type} "$<TARGET_FILE:${target}>" "${CMAKE_CURRENT_BINARY_DIR}/${target}${suffix}"
+ )
+endfunction()
+
+# Set linker script for a target
+function(target_linker_script target scope script)
+ target_link_options(${target} "${scope}" "-T${script}")
+
+ get_target_property(_cur_link_deps ${target} LINK_DEPENDS)
+ if (_cur_link_deps STREQUAL "_cur_link_deps-NOTFOUND")
+ set(_cur_link_deps "")
+ endif()
+
+ string(APPEND _cur_link_deps "${script}")
+ set_target_properties(${target} PROPERTIES LINK_DEPENDS ${_cur_link_deps})
+endfunction()
+
+# Write file only if content has changed
+function(write_file_if_changed file content)
+ if (EXISTS "${file}")
+ file(READ "${file}" existing_content)
+ else()
+ set(existing_content "")
+ endif()
+
+ if (NOT "${existing_content}" STREQUAL "${content}")
+ file(WRITE "${file}" "${content}")
+ endif()
+endfunction()
+
+# Embed a file into a target
+function(embed_file target file symbol)
+ cmake_path(IS_ABSOLUTE file is_absolute)
+ if (NOT is_absolute)
+ set(file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
+ endif()
+
+ cmake_path(GET file FILENAME filename)
+
+ set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
+ if (NOT EXISTS "${generated_dir}")
+ file(MAKE_DIRECTORY "${generated_dir}")
+ endif()
+
+ set(generated_objects "${generated_dir}_objects")
+ if (NOT EXISTS "${generated_objects}")
+ file(MAKE_DIRECTORY "${generated_objects}")
+ endif()
+
+ set(asm_path "${generated_objects}/${filename}.S")
+ write_file_if_changed("${asm_path}"
+".global ${symbol}_data
+.global ${symbol}_size
+.section .rodata
+.align 4
+${symbol}_data:
+ .incbin \"${file}\"
+1:
+${symbol}_size:
+ .int 1b - ${symbol}_data
+")
+
+ add_custom_command(OUTPUT "${asm_path}"
+ COMMAND ${CMAKE_COMMAND} -E touch "${asm_path}"
+ DEPENDS "${file}")
+
+ target_sources("${target}" PRIVATE "${asm_path}")
+
+ set(header_path "${generated_dir}/${filename}")
+
+ write_file_if_changed("${header_path}.h"
+"#pragma once
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+extern const char ${symbol}_data[];
+extern const unsigned int ${symbol}_size;
+
+#ifdef __cplusplus
+}
+#endif
+")
+
+ write_file_if_changed("${header_path}.hpp"
+"#pragma once
+
+#include \"${header_path}.h\"
+#include <span>
+
+inline const std::span<const char> ${symbol}{${symbol}_data, ${symbol}_size};
+")
+endfunction()