summaryrefslogtreecommitdiffstats
path: root/cmake/utils.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/utils.cmake
downloadmsp432_test-master.tar.gz
msp432_test-master.zip
InitialHEADmaster
Diffstat (limited to 'cmake/utils.cmake')
-rw-r--r--cmake/utils.cmake123
1 files changed, 123 insertions, 0 deletions
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()