diff --git a/CMakeLists.txt b/CMakeLists.txt index 01f2fa4b..ef0d335d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,6 @@ configure_file( # add targets ############################################################ add_subdirectory(src) -add_subdirectory(tools) if(ADM_EXAMPLES) add_subdirectory(examples) endif() diff --git a/cmake/embed_resource.cmake b/cmake/embed_resource.cmake new file mode 100644 index 00000000..708749bf --- /dev/null +++ b/cmake/embed_resource.cmake @@ -0,0 +1,70 @@ +set(current_dir ${CMAKE_CURRENT_LIST_DIR}) +function(embed_resource) + # parse function arguments + set(options "") + set(oneValueArguments NAMESPACE BASE_NAME) + set(multiValueArguments RESOURCE_FILES) + cmake_parse_arguments(EMBED "${options}" "${oneValueArguments}" + "${multiValueArguments}" ${ARGN}) + foreach(arg ${oneValueArguments} ${multiValueArguments}) + if(NOT EMBED_${arg}) + message(WARNING "Argument ${arg} not defined in call to embed_resource") + endif() + endforeach() + + set_property( + DIRECTORY + APPEND + PROPERTY CMAKE_CONFIGURE_DEPENDS ${EMBED_RESOURCE_FILES}) + + set(byte_array_template + "const char file_@FILE_COUNT@[] = { @FILE_BYTE_ARRAY@ }") + set(lookup_template + "if (fileName == \"@FILE_NAME@\") { stream.write(file_@FILE_COUNT@, @ARRAY_SIZE@)\; return true\; }" + ) + + set(FILE_COUNT 1) + foreach(file_path ${EMBED_RESOURCE_FILES}) + # read resource file as hex with no byte separator + file(READ ${file_path} file_contents HEX) + # split into 2 char hex bytes + string(REGEX MATCHALL "(..)" file_bytes ${file_contents}) + # need length for call to ostream.write() + list(LENGTH file_bytes ARRAY_SIZE) + + # add 0x prefix and , separator TRANSFORM only valid in cmake 3.14+ or we + # could just do list(TRANSFORM file_bytes PREPEND "0x") list(JOIN file_bytes + # "," FILE_BYTE_ARRAY) + list(POP_FRONT file_bytes first_byte) + string(PREPEND first_byte "0x") + list(PREPEND file_bytes ${first_byte}) + list(JOIN file_bytes ",0x" FILE_BYTE_ARRAY) + + # strip path from data file, leaving name + get_filename_component(FILE_NAME "${file_path}" NAME) + # generate single byte array from template + string(CONFIGURE ${byte_array_template} byte_array @ONLY) + # add the trailing semicolon here as it gets interpreted as a list seperator + # if in template + list(APPEND byte_arrays "${byte_array}\;") + # generate single lookup entry + string(CONFIGURE "${lookup_template}" lookup @ONLY) + list(APPEND lookups "${lookup}") + math(EXPR FILE_COUNT "${FILE_COUNT} + 1") + endforeach() + + # join entries with newline for readability + if(WIN32) + set(line_end "\n\r") + else() + set(line_end "\n") + endif() + list(JOIN byte_arrays "${line_end}" EMBED_BYTE_ARRAYS) + list(JOIN lookups "${line_end}" EMBED_LOOKUPS) + + # generate files + configure_file("${current_dir}/embedded_resource.hpp.in" + "${CMAKE_CURRENT_BINARY_DIR}/${EMBED_BASE_NAME}.hpp" @ONLY) + configure_file("${current_dir}/embedded_resource.cpp.in" + "${CMAKE_CURRENT_BINARY_DIR}/${EMBED_BASE_NAME}.cpp" @ONLY) +endfunction() diff --git a/cmake/embedded_resource.cpp.in b/cmake/embedded_resource.cpp.in new file mode 100644 index 00000000..549d0de9 --- /dev/null +++ b/cmake/embedded_resource.cpp.in @@ -0,0 +1,13 @@ +// WARNING This file is auto-generated during configuration by the cmake +// function embed_resource(). Do not manually edit as changes will be lost + +#include "@EMBED_BASE_NAME@.hpp" + +namespace { +@EMBED_BYTE_ARRAYS@ +} + +bool @EMBED_NAMESPACE@::getEmbeddedFile(std::string const& fileName, std::ostream& stream) { +@EMBED_LOOKUPS@ + return false; +} diff --git a/cmake/embedded_resource.hpp.in b/cmake/embedded_resource.hpp.in new file mode 100644 index 00000000..7c90f422 --- /dev/null +++ b/cmake/embedded_resource.hpp.in @@ -0,0 +1,10 @@ +// WARNING This file is auto-generated during configuration by the cmake +// function embed_resource(). Do not manually edit as changes will be lost + +#pragma once +#include +#include + +namespace @EMBED_NAMESPACE@ { + bool getEmbeddedFile(std::string const& fileName, std::ostream& stream); +} diff --git a/format.sh b/format.sh index daca0f63..b18272b2 100755 --- a/format.sh +++ b/format.sh @@ -1,5 +1,5 @@ #!/bin/bash -DIRS="examples include src tests tools" +DIRS="examples include src tests" IGNORE=" src/elements/time.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c7ee5c0..ebf13b30 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,14 +2,11 @@ include(${PROJECT_SOURCE_DIR}/submodules/rapidxml.cmake) -add_custom_command( - OUTPUT ${PROJECT_BINARY_DIR}/resources.hpp - COMMAND resource_embedder common_definitions.xml > ${PROJECT_BINARY_DIR}/resources.hpp - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/resources - DEPENDS resource_embedder ${PROJECT_SOURCE_DIR}/resources/common_definitions.xml - COMMENT "Running resource embedder." - VERBATIM -) +include(embed_resource) +embed_resource( + NAMESPACE adm + BASE_NAME resources + RESOURCE_FILES ${PROJECT_SOURCE_DIR}/resources/common_definitions.xml) add_library(adm document.cpp @@ -66,10 +63,13 @@ add_library(adm detail/id_assigner.cpp parse.cpp write.cpp - ${PROJECT_BINARY_DIR}/resources.hpp + ${CMAKE_CURRENT_BINARY_DIR}/resources.hpp + ${CMAKE_CURRENT_BINARY_DIR}/resources.cpp ) target_include_directories(adm + PRIVATE + $ # resources.hpp PUBLIC # Headers used from source/build location: $ diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt deleted file mode 100644 index ed2702a4..00000000 --- a/tools/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# --- tools --- - -add_executable(resource_embedder resource_embedder.cpp) diff --git a/tools/resource_embedder.cpp b/tools/resource_embedder.cpp deleted file mode 100644 index d803c9ae..00000000 --- a/tools/resource_embedder.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include - -int main(int argc, char* argv[]) { - std::cout << "#pragma once" << std::endl << std::endl; - std::cout << "#include " << std::endl; - std::cout << "#include " << std::endl; - - for (int fileIndex = 1; fileIndex < argc; ++fileIndex) { - std::ifstream file(argv[fileIndex]); - if (file.is_open()) { - std::cout << "static const unsigned char v" << fileIndex << "[] = {"; - long long int charIndex = 0; - char character; - while (file.get(character)) { - if ((charIndex % 12) == 0) { - std::cout << std::endl << " "; - } - std::cout << "0x" << std::setw(2) << std::setfill('0') << std::hex - << (int)character << ", "; - ++charIndex; - } - // Make null-terminated - std::cout << "0x00" << std::endl << " };" << std::endl; - file.close(); - } else { - throw std::runtime_error("file not found."); - } - } - - std::cout << std::endl << std::endl; - - for (int fileIndex = 1; fileIndex < argc; ++fileIndex) { - std::cout << "inline bool getEmbeddedFile(const std::string& filename,\n" - " std::stringstream& stream) {" - << std::endl; - std::cout << " if (filename == \"" << argv[fileIndex] << "\") {" - << std::endl; - std::cout << " stream << v" << fileIndex << ";" << std::endl; - std::cout << " return true;" << std::endl; - std::cout << " }" << std::endl; - std::cout << " return false;" << std::endl; - std::cout << "}" << std::endl; - } - return 0; -}