From 4f8a4e4e2bd983202e87f515f51a88273b0b150d Mon Sep 17 00:00:00 2001 From: Mark Roszko Date: Thu, 7 Aug 2025 00:13:54 -0400 Subject: [PATCH] Add CreateResourceCpp helpers for future use --- cmake/BuildSteps/CreateResourceCpp.cmake | 99 +++++++++++++++++++ .../CreateResourceCppFunction.cmake | 39 ++++++++ 2 files changed, 138 insertions(+) create mode 100644 cmake/BuildSteps/CreateResourceCpp.cmake create mode 100644 cmake/BuildSteps/CreateResourceCppFunction.cmake diff --git a/cmake/BuildSteps/CreateResourceCpp.cmake b/cmake/BuildSteps/CreateResourceCpp.cmake new file mode 100644 index 0000000000..13827fdd54 --- /dev/null +++ b/cmake/BuildSteps/CreateResourceCpp.cmake @@ -0,0 +1,99 @@ +# +# Used as a standalone cmake script to process a given file into binary arrays +# at compile-time +# +# Include CreateResourceCppFunction.cmake to get access to the add_compiled_resource +# function +# +# This file is structured to be invoked from add_custom_command in order +# to have GENERATED marked output files that can be rebuilt on change. +# +# Required Arguments: +# SOURCE_FILE - Path to source shader file +# OUT_CPP_DIR - Destination path for cpp file +# OUT_HEADER_DIR - Destination path for header file +# OUT_CPP_FILENAME - cpp filename +# OUT_HEADER_FILENAME - header filename +# OUT_VAR_NAME - Name of variable containing shader to be created +# +# Parts taken from https://github.com/sivachandran/cmake-bin2h +# Copyright 2020 Sivachandran Paramasivam +# + +# Function to wrap a given string into multiple lines at the given column position. +# Parameters: +# VARIABLE - The name of the CMake variable holding the string. +# AT_COLUMN - The column position at which string will be wrapped. +function(WRAP_STRING) + set(oneValueArgs VARIABLE AT_COLUMN) + cmake_parse_arguments(WRAP_STRING "${options}" "${oneValueArgs}" "" ${ARGN}) + + string(LENGTH ${${WRAP_STRING_VARIABLE}} stringLength) + math(EXPR offset "0") + + while(stringLength GREATER 0) + + if(stringLength GREATER ${WRAP_STRING_AT_COLUMN}) + math(EXPR length "${WRAP_STRING_AT_COLUMN}") + else() + math(EXPR length "${stringLength}") + endif() + + string(SUBSTRING ${${WRAP_STRING_VARIABLE}} ${offset} ${length} line) + set(lines "${lines}\n${line}") + + math(EXPR stringLength "${stringLength} - ${length}") + math(EXPR offset "${offset} + ${length}") + endwhile() + + set(${WRAP_STRING_VARIABLE} "${lines}" PARENT_SCOPE) +endfunction() + + +file( READ ${SOURCE_FILE} _SOURCE_BINARY HEX ) +string(LENGTH ${_SOURCE_BINARY} _SOURCE_BINARY_LENGTH) + +set(SOURCE_BINARY "${_SOURCE_BINARY}00") # null terminate for the sake of it + +wrap_string(VARIABLE _SOURCE_BINARY AT_COLUMN 32) +math(EXPR _ARRAY_SIZE "${_SOURCE_BINARY_LENGTH} / 2") + + +# adds '0x' prefix and comma suffix before and after every byte respectively +string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " _ARRAY_VALUES ${_SOURCE_BINARY}) +# removes trailing comma +string(REGEX REPLACE ", $" "" _ARRAY_VALUES ${_ARRAY_VALUES}) + +set( outCppTextByteArray "unsigned char ${OUT_VAR_NAME}_bytes[] = { ${_ARRAY_VALUES} };") +set( outCppTextByteSize "size_t ${OUT_VAR_NAME}_size = ${_ARRAY_SIZE};") + +set( outCppText +" +#include +#include <${OUT_HEADER_FILENAME}> + +namespace RESOURCE { +${outCppTextByteArray} +${outCppTextByteSize} +} +" ) + +file( + WRITE ${OUT_CPP_DIR}/${OUT_CPP_FILENAME} + "${outCppText}" +) + + +set( outHeaderText +"namespace RESOURCE { + extern unsigned char ${OUT_VAR_NAME}_bytes[]; + extern size_t ${OUT_VAR_NAME}_size; +}" +) + +file( + WRITE ${OUT_HEADER_DIR}/${OUT_HEADER_FILENAME} + "${outHeaderText}" +) + +message(STATUS "Resource ${SOURCE_FILE} converted to ${OUT_CPP_DIR}/${OUT_CPP_FILENAME}") \ No newline at end of file diff --git a/cmake/BuildSteps/CreateResourceCppFunction.cmake b/cmake/BuildSteps/CreateResourceCppFunction.cmake new file mode 100644 index 0000000000..2543400611 --- /dev/null +++ b/cmake/BuildSteps/CreateResourceCppFunction.cmake @@ -0,0 +1,39 @@ +# +# Used to mark and generate resource files to conversion to binary arrays +# +# Usage example: +# add_compiled_resource( pcbnew ${CMAKE_SOURCE_DIR}/resources/html/about.html about_html) +# +# The source file about.html above will be converted to about_html.cpp/.h and placed into +# the /resources/cpp cmake binary directory folder. The include directories for the target are also +# expanded to cover including about_html.h +# +# The output is marked as depends so changes to about.html will trigger a update of the about_html.cpp/.h +# +# The CreateResourceCpp.cmake helper script is also marked a depends so any changes to our output writing +# will cause updates. +# + + +function( add_compiled_resource outTarget inFile resourceName ) + set(outCppName "${resourceName}.cpp") + set(outHeaderName "${resourceName}.h") + + add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/resources/cpp/${outCppName} + ${CMAKE_BINARY_DIR}/resources/cpp/${outHeaderName} + COMMAND ${CMAKE_COMMAND} + -DSOURCE_FILE="${inFile}" + -DOUT_CPP_DIR="${CMAKE_BINARY_DIR}/resources/cpp" + -DOUT_HEADER_DIR="${CMAKE_BINARY_DIR}/resources/cpp" + -DOUT_CPP_FILENAME="${outCppName}" + -DOUT_HEADER_FILENAME="${outHeaderName}" + -DOUT_VAR_NAME="${resourceName}" + -P ${KICAD_CMAKE_MODULE_PATH}/BuildSteps/CreateResourceCpp.cmake + DEPENDS ${inFile} + ${KICAD_CMAKE_MODULE_PATH}/BuildSteps/CreateResourceCpp.cmake + ) + + target_sources( ${outTarget} PRIVATE ${CMAKE_BINARY_DIR}/resources/cpp/${outCppName} ) + target_include_directories( ${outTarget} PUBLIC ${CMAKE_BINARY_DIR}/resources/cpp ) +endfunction() \ No newline at end of file