Add an embedded resource compiler tool
This commit is contained in:
parent
4964a3992e
commit
35ea62bb63
4 changed files with 138 additions and 0 deletions
|
|
@ -10,6 +10,7 @@ if(PSEMEK_BUILD_TYPE STREQUAL "DEBUG")
|
||||||
add_definitions("-DPSEMEK_DEBUG=1")
|
add_definitions("-DPSEMEK_DEBUG=1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(tools)
|
||||||
add_subdirectory(libs)
|
add_subdirectory(libs)
|
||||||
|
|
||||||
add_library(psemek todo.md)
|
add_library(psemek todo.md)
|
||||||
|
|
|
||||||
6
tools/CMakeLists.txt
Normal file
6
tools/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
file(GLOB PSEMEK_TOOLS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*")
|
||||||
|
list(REMOVE_ITEM PSEMEK_TOOLS "CMakeLists.txt")
|
||||||
|
|
||||||
|
foreach(tool ${PSEMEK_TOOLS})
|
||||||
|
add_subdirectory(${tool})
|
||||||
|
endforeach()
|
||||||
29
tools/resource/CMakeLists.txt
Normal file
29
tools/resource/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
add_executable(resource-compiler compiler.cpp)
|
||||||
|
|
||||||
|
function(psemek_add_resources TARGET)
|
||||||
|
get_target_property(OUT_DIR ${TARGET} BINARY_DIR)
|
||||||
|
get_target_property(INPUT_DIR ${TARGET} SOURCE_DIR)
|
||||||
|
|
||||||
|
target_include_directories(${TARGET} PRIVATE "${OUT_DIR}/resource/include")
|
||||||
|
|
||||||
|
while(ARGN)
|
||||||
|
list(GET ARGN 0 FILE)
|
||||||
|
list(GET ARGN 1 NAME)
|
||||||
|
list(REMOVE_AT ARGN 0 1)
|
||||||
|
|
||||||
|
get_filename_component(NAME_PREFIX ${NAME} DIRECTORY)
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY "${OUT_DIR}/resource/include/${NAME_PREFIX}")
|
||||||
|
file(MAKE_DIRECTORY "${OUT_DIR}/resource/source/${NAME_PREFIX}")
|
||||||
|
|
||||||
|
set(OUT_HEADER "${OUT_DIR}/resource/include/${NAME}.hpp")
|
||||||
|
set(OUT_SOURCE "${OUT_DIR}/resource/source/${NAME}.cpp")
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT "${OUT_HEADER}" "${OUT_SOURCE}"
|
||||||
|
COMMAND resource-compiler "${FILE}" ${NAME} "${OUT_HEADER}" "${OUT_SOURCE}"
|
||||||
|
DEPENDS resource-compiler "${FILE}"
|
||||||
|
WORKING_DIRECTORY "${INPUT_DIR}")
|
||||||
|
|
||||||
|
target_sources(${TARGET} PRIVATE "${OUT_SOURCE}")
|
||||||
|
endwhile()
|
||||||
|
endfunction()
|
||||||
102
tools/resource/compiler.cpp
Normal file
102
tools/resource/compiler.cpp
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
if (argc != 5)
|
||||||
|
{
|
||||||
|
std::cerr << "Usage: resource-compiler <input-file> <name> <output-header> <output-source>" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name = argv[2];
|
||||||
|
std::string ns;
|
||||||
|
|
||||||
|
std::size_t const last_slash = name.find_last_of('/');
|
||||||
|
|
||||||
|
if (last_slash != std::string::npos)
|
||||||
|
{
|
||||||
|
ns = name.substr(0, last_slash);
|
||||||
|
for (std::size_t i = 0;;)
|
||||||
|
{
|
||||||
|
i = ns.find('/', i);
|
||||||
|
if (i == std::string::npos) break;
|
||||||
|
ns.replace(i, 1, "::");
|
||||||
|
}
|
||||||
|
|
||||||
|
name = name.substr(last_slash + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string tab;
|
||||||
|
if (!ns.empty()) tab = "\t";
|
||||||
|
|
||||||
|
std::ifstream input_file{argv[1], std::ios::binary};
|
||||||
|
std::vector<char> input_data{std::istreambuf_iterator<char>{input_file}, {}};
|
||||||
|
input_file.close();
|
||||||
|
|
||||||
|
std::ofstream output_header{argv[3]};
|
||||||
|
|
||||||
|
output_header
|
||||||
|
<< "#pragma once\n"
|
||||||
|
<< "\n"
|
||||||
|
<< "#include <string_view>\n"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
if (!ns.empty()) output_header
|
||||||
|
<< "namespace " << ns << "\n"
|
||||||
|
<< "{\n"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
output_header << tab << "extern std::string_view " << name << ";\n";
|
||||||
|
|
||||||
|
if (!ns.empty()) output_header
|
||||||
|
<< "\n"
|
||||||
|
<< "}\n";
|
||||||
|
|
||||||
|
output_header.close();
|
||||||
|
|
||||||
|
std::ofstream output_source{argv[4]};
|
||||||
|
|
||||||
|
output_source
|
||||||
|
<< "#include <string_view>\n"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
output_source << "static const char data[" << input_data.size() << "] = {\n";
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < input_data.size(); ++i)
|
||||||
|
{
|
||||||
|
if ((i % 16) == 0) output_source << "\t";
|
||||||
|
|
||||||
|
char const c = input_data[i];
|
||||||
|
|
||||||
|
if constexpr (std::is_signed_v<char>)
|
||||||
|
{
|
||||||
|
output_source << (c >= 0 ? ' ' : '-') << "0x" << std::setw(2) << std::setfill('0') << std::hex << std::abs(static_cast<int>(c)) << ", ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output_source << "0x" << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(c) << ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((i % 16) == 15) output_source << "\n";
|
||||||
|
}
|
||||||
|
if ((input_data.size() % 16) != 0) output_source << "\n";
|
||||||
|
|
||||||
|
output_source << "};\n\n";
|
||||||
|
|
||||||
|
if (!ns.empty()) output_source
|
||||||
|
<< "namespace " << ns << "\n"
|
||||||
|
<< "{\n"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
output_source << tab << "std::string_view " << name << "{data, sizeof(data)};\n";
|
||||||
|
|
||||||
|
if (!ns.empty()) output_source
|
||||||
|
<< "\n"
|
||||||
|
<< "}\n";
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue