From 1592dd6e42bf7082f3703913fa49469d7a4faed3 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 9 Sep 2026 19:34:35 +0200 Subject: [PATCH 1/2] Fix files being rebuild on CMake reconfigure Because of the usage of file(WRITE), reconfiguring CMake would trigger rebuilding of all the files. Source files for templates etc have been moved to just be files on disc, and the hpp generation step has been moved to use configure_file(). --- CMakeLists.txt | 323 +------------------------- script/embed_header_file_template.hpp | 118 ++++++++++ script/embed_impl.cpp | 137 +++++++++++ script/embed_source_file_template.cpp | 21 ++ script/generate.cmake | 10 + 5 files changed, 295 insertions(+), 314 deletions(-) create mode 100644 script/embed_header_file_template.hpp create mode 100644 script/embed_impl.cpp create mode 100644 script/embed_source_file_template.cpp create mode 100644 script/generate.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index c057b31..7153ce9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,312 +9,7 @@ option(B_EMBED_SILENCE_DEVMODE_WARNING "Disable the battery::embed devmode warni # Remember the binary dir for later set(EMBED_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/embed CACHE INTERNAL "binary directory of the battery::embed library" FORCE) - -# The template for how to generate the .cpp file -set(EMBED_SOURCE_FILE_TEMPLATE [==[ -// File generated using battery::embed (https://github.com/batterycenter/embed) -// Embedded file: '${FILENAME}' as '${IDENTIFIER}' -// Filesize: ${FILESIZE} bytes -// DO NOT EDIT THIS FILE!!! - -#include "battery/embed.hpp" - -namespace b { - - EmbedInternal::EmbeddedFile EmbedInternal::${IDENTIFIER} = { - std::string_view( - ${GENERATED_BYTE_ARRAY}, - ${FILESIZE} - ) - , "${FILENAME}" -#ifndef B_PRODUCTION_MODE - , "${FULL_PATH}" -#endif // !B_PRODUCTION_MODE - }; - -} // namespace b -]==]) -file(WRITE ${EMBED_BINARY_DIR}/embed_source_file_template.cpp "${EMBED_SOURCE_FILE_TEMPLATE}") - -# The single b::embed master source file which is compiled into the app -set(EMBED_MASTER_SOURCE_FILE [==[ -// File generated using battery::embed (https://github.com/batterycenter/embed) -// DO NOT EDIT THIS FILE!!! - -#include "battery/embed.hpp" - -#if !defined(B_PRODUCTION_MODE) && !defined(B_OS_WEB) -#include -#include -#include -#include -#include -#include -#include -#endif // !B_PRODUCTION_MODE and !B_OS_WEB - -namespace b { - -#if !defined(B_PRODUCTION_MODE) && !defined(B_OS_WEB) - - // All this crazyness is necessary because we need to use std::string_view because of constexpr, - // and the string_view only points to a char array, so we need a string that outlives - // the string_view it is assigned to. - - struct FileData { - std::string filename; - std::string newContent; - std::string filepath; - std::filesystem::file_time_type lastWriteTime; - std::function callback; - }; - - static std::mutex embeddedFilesMapMutex; - static std::unordered_map embeddedFiles; - -#ifdef _WIN32 -#ifdef __clang__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - - static std::wstring embed_widen(const std::string& str) { - std::wstring_convert> converter; - return converter.from_bytes(str); - } - -#ifdef __clang__ -#pragma GCC diagnostic pop -#endif - -#endif // _WIN32 - - static std::optional embed_read_file(const std::string_view& filename) { -#ifdef _WIN32 - std::ifstream file(embed_widen(std::string(filename)).c_str(), std::ios::binary); -#else // _WIN32 - std::ifstream file(std::string(filename), std::ios::binary); -#endif // _WIN32 - if (file.fail()) { - return {}; - } - return std::string((std::istreambuf_iterator(file)), std::istreambuf_iterator()); - } - - // Apple-Clang does not support std::jthread yet, hence we make our own version of jthread here: - class AutoThread { - public: - template - AutoThread(Tfunc&& function) - : m_thread([&]() { function(m_shouldStop); }) - {} - - ~AutoThread() { - m_shouldStop = true; - m_thread.join(); - } - - AutoThread(const AutoThread& other) = delete; - AutoThread(AutoThread&& other) = delete; - AutoThread& operator=(const AutoThread& other) = delete; - AutoThread& operator=(AutoThread&& other) = delete; - - private: - std::thread m_thread; - std::atomic m_shouldStop = false; - }; - - // This is a global file watcher thread that is created at program start and automatically destroyed at program end - // All embedded files are hot-reloaded by this thread. - AutoThread embeddedFileWatcherThread = AutoThread([](std::atomic& shouldStop) { - while (!shouldStop) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - std::lock_guard lock(embeddedFilesMapMutex); - for (auto& [key, filedata] : embeddedFiles) { - std::filesystem::path filepath(key); - std::error_code ec; - auto newWriteTime = std::filesystem::last_write_time(filepath, ec); - if (!ec) { - if (newWriteTime != filedata.lastWriteTime) { - filedata.lastWriteTime = newWriteTime; - auto fileresult = embed_read_file(key); - if (!fileresult) { - continue; - } - filedata.newContent = *fileresult; - EmbedInternal::EmbeddedFile newFile(filedata.newContent, filedata.filename, filedata.filepath); - filedata.callback(newFile); - } - } - } - } - }); - -#endif // !B_PRODUCTION_MODE and !B_OS_WEB - - void EmbedInternal::EmbeddedFile::get(const std::function& callback) { -#if defined(B_PRODUCTION_MODE) || defined(B_OS_WEB) - callback(*this); -#else // B_PRODUCTION_MODE or B_OS_WEB - auto fileresult = embed_read_file(m_fullFilepath); - if (fileresult) { - m_data = *fileresult; - } - callback(*this); - - FileData fileData; - fileData.filename = m_filename; - fileData.newContent = m_data; - fileData.filepath = m_fullFilepath; - fileData.callback = callback; - fileData.lastWriteTime = std::filesystem::last_write_time(m_fullFilepath); - - std::lock_guard lock(embeddedFilesMapMutex); - embeddedFiles[std::string(m_fullFilepath)] = fileData; -#endif // B_PRODUCTION_MODE or B_OS_WEB - } - -} // namespace b -]==]) -file(WRITE ${EMBED_BINARY_DIR}/embed_impl.cpp "${EMBED_MASTER_SOURCE_FILE}") - -# The common battery::embed header and source files -set(EMBED_HEADER_FILE [=[ -// File generated by battery::embed -// DO NOT EDIT THIS FILE!!! -#ifndef BATTERY_EMBED_HPP -#define BATTERY_EMBED_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef __cpp_constexpr_dynamic_alloc -# error "battery::embed requires C++20 (Your compiler does not provide __cpp_constexpr_dynamic_alloc, which is needed for battery::embed)" -#endif - -namespace b { - - struct EmbedInternal { - - class EmbeddedFile { - public: - constexpr EmbeddedFile() = default; - - constexpr EmbeddedFile( - const std::string_view& data, - const std::string_view& filename -#ifndef B_PRODUCTION_MODE - , const std::string_view& fullFilepath -#endif // !B_PRODUCTION_MODE - ) - : m_data(data) - , m_filename(filename) -#ifndef B_PRODUCTION_MODE - , m_fullFilepath(fullFilepath) -#endif // !B_PRODUCTION_MODE - {} - - [[nodiscard]] std::string str() const { - return m_data.data(); - } - - [[nodiscard]] const char* data() const { - return m_data.data(); - } - - [[nodiscard]] std::vector vec() const { - return { m_data.begin(), m_data.end() }; - } - - [[nodiscard]] size_t length() const { - return m_data.size(); - } - - [[nodiscard]] size_t size() const { - return m_data.size(); - } - - operator std::string() const { - return str(); - } - - operator std::vector() const { - return vec(); - } - - void get(const std::function& callback); - - private: - std::string_view m_data; - std::string_view m_filename; -#ifndef B_PRODUCTION_MODE - std::string_view m_fullFilepath; -#endif - }; // class EmbeddedFile - - ${EMBEDDED_FILES_DECLARATIONS} - }; // struct embedded_files - - template - struct embed_string_literal { - constexpr embed_string_literal(const char (&str)[N]) { - std::copy_n(str, N, value); - } - constexpr bool operator!=(const embed_string_literal& other) const { - return std::equal(value, value + N, other.value); - } - [[nodiscard]] std::string str() const { - return std::string(value, N); - } - [[nodiscard]] constexpr bool _false() const { - return false; - } - char value[N]; - }; - - template - constexpr bool operator==(const embed_string_literal& left, const char (&right)[M]) { - return std::equal(left.value, left.value + N, right); - } - - template - constexpr EmbedInternal::EmbeddedFile embed() { - ${EMBEDDED_FILES_RETURNS}{ - static_assert(identifier._false(), "[b::embed<>] No such file or directory"); - } - } - -} // namespace b - -inline std::ostream& operator<<(std::ostream& stream, const b::EmbedInternal::EmbeddedFile& file) { - stream << file.str(); - return stream; -} - -#endif // BATTERY_EMBED_HPP -]=]) -file(WRITE ${EMBED_BINARY_DIR}/embed_header_file_template.hpp "${EMBED_HEADER_FILE}") - -# The cmake script to embed the files. This is called later on-demand, in a separate process -set(EMBED_GENERATE_SCRIPT [=[ -file(READ "${FULL_PATH}" GENERATED_BYTE_ARRAY HEX) -string(LENGTH "${GENERATED_BYTE_ARRAY}" FILESIZE) -math(EXPR FILESIZE "${FILESIZE} / 2") - -string(REPEAT "[0-9a-f]" 32 PATTERN) -set(GENERATED_BYTE_ARRAY "\"${GENERATED_BYTE_ARRAY}") -string(REGEX REPLACE "${PATTERN}" "\\0\"\n \"" GENERATED_BYTE_ARRAY ${GENERATED_BYTE_ARRAY}) -string(REGEX REPLACE "([0-9a-f][0-9a-f])" "\\\\x\\1" GENERATED_BYTE_ARRAY ${GENERATED_BYTE_ARRAY}) -set(GENERATED_BYTE_ARRAY "${GENERATED_BYTE_ARRAY}\"") -configure_file(${INFILE} ${OUTFILE}) -]=]) -file(WRITE ${EMBED_BINARY_DIR}/generate.cmake ${EMBED_GENERATE_SCRIPT}) +set(EMBED_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "source directory of the battery::embed library" FORCE) set(EMBED_IDENTIFIERS "" CACHE INTERNAL "list of all identifiers used by battery::embed") set(EMBED_FILENAMES "" CACHE INTERNAL "list of all filenames used by battery::embed") @@ -353,10 +48,10 @@ function(_embed_generate_hpp TARGET) set(EMBEDDED_FILES_RETURNS "${EMBEDDED_FILES_RETURNS}if constexpr (identifier == \"${FILENAME}\") { return EmbedInternal::${IDENTIFIER}; }\n else ") endif() endforeach() - file(READ ${EMBED_BINARY_DIR}/embed_header_file_template.hpp EMBED_HEADER_FILE) - string(CONFIGURE "${EMBED_HEADER_FILE}" EMBED_HEADER_FILE_GENERATED) set(EMBED_HPP "${EMBED_BINARY_DIR}/autogen/${TARGET}/include/battery/embed.hpp") - file(WRITE "${EMBED_HPP}" "${EMBED_HEADER_FILE_GENERATED}") + configure_file( + "${EMBED_SOURCE_DIR}/script/embed_header_file_template.hpp" + "${EMBED_HPP}") endfunction(_embed_generate_hpp) # Internal function for validating an identifier @@ -395,7 +90,7 @@ function(b_embed TARGET FILENAME) # This action generates both files and is called on-demand whenever the resource file changes set(EMBED_HPP "${EMBED_BINARY_DIR}/autogen/${TARGET_ID}/include/battery/embed.hpp") - set(EMBED_CPP_TEMPLATE "${EMBED_BINARY_DIR}/embed_source_file_template.cpp") + set(EMBED_CPP_TEMPLATE "${EMBED_SOURCE_DIR}/script/embed_source_file_template.cpp") add_custom_command( COMMAND ${CMAKE_COMMAND} -DINFILE=${EMBED_CPP_TEMPLATE} @@ -403,8 +98,8 @@ function(b_embed TARGET FILENAME) -DFULL_PATH=${FULL_PATH} -DIDENTIFIER=${IDENTIFIER} -DFILENAME=${FILENAME} - -P "${EMBED_BINARY_DIR}/generate.cmake" - DEPENDS "${FULL_PATH}" "${EMBED_HPP}" "${EMBED_BINARY_DIR}/generate.cmake" "${EMBED_BINARY_DIR}/embed_source_file_template.cpp" + -P "${EMBED_SOURCE_DIR}/script/generate.cmake" + DEPENDS "${FULL_PATH}" "${EMBED_HPP}" "${EMBED_SOURCE_DIR}/script/generate.cmake" "${EMBED_SOURCE_DIR}/script/embed_source_file_template.cpp" OUTPUT ${CPP_FILE} VERBATIM ) @@ -414,7 +109,7 @@ function(b_embed TARGET FILENAME) $ $ ) - target_sources(${TARGET} PRIVATE ${CPP_FILE} ${EMBED_BINARY_DIR}/embed_impl.cpp ${EMBED_HPP}) + target_sources(${TARGET} PRIVATE ${CPP_FILE} ${EMBED_SOURCE_DIR}/script/embed_impl.cpp ${EMBED_HPP}) target_compile_definitions(${TARGET} PRIVATE _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING) if (NOT B_PRODUCTION_MODE) @@ -427,7 +122,7 @@ function(b_embed TARGET FILENAME) if (MSVC) target_sources(${TARGET} PRIVATE ${FULL_PATH}) source_group(TREE ${EMBED_BINARY_DIR}/autogen/${TARGET_ID}/src PREFIX "embed/autogen" FILES ${CPP_FILE}) - source_group(TREE ${EMBED_BINARY_DIR} PREFIX "embed/autogen" FILES ${EMBED_BINARY_DIR}/embed_impl.cpp) + source_group(TREE ${EMBED_BINARY_DIR} PREFIX "embed/autogen" FILES ${EMBED_SOURCE_DIR}/script/embed_impl.cpp) source_group(TREE ${EMBED_BINARY_DIR}/autogen/${TARGET_ID}/include/battery PREFIX "embed/autogen" FILES ${EMBED_HPP}) source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "/embed" FILES ${FULL_PATH}) endif() diff --git a/script/embed_header_file_template.hpp b/script/embed_header_file_template.hpp new file mode 100644 index 0000000..7320f93 --- /dev/null +++ b/script/embed_header_file_template.hpp @@ -0,0 +1,118 @@ +// File generated by battery::embed +// DO NOT EDIT THIS FILE!!! +#ifndef BATTERY_EMBED_HPP +#define BATTERY_EMBED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __cpp_constexpr_dynamic_alloc +# error "battery::embed requires C++20 (Your compiler does not provide __cpp_constexpr_dynamic_alloc, which is needed for battery::embed)" +#endif + +namespace b { + + struct EmbedInternal { + + class EmbeddedFile { + public: + constexpr EmbeddedFile() = default; + + constexpr EmbeddedFile( + const std::string_view& data, + const std::string_view& filename +#ifndef B_PRODUCTION_MODE + , const std::string_view& fullFilepath +#endif // !B_PRODUCTION_MODE + ) + : m_data(data) + , m_filename(filename) +#ifndef B_PRODUCTION_MODE + , m_fullFilepath(fullFilepath) +#endif // !B_PRODUCTION_MODE + {} + + [[nodiscard]] std::string str() const { + return m_data.data(); + } + + [[nodiscard]] const char* data() const { + return m_data.data(); + } + + [[nodiscard]] std::vector vec() const { + return { m_data.begin(), m_data.end() }; + } + + [[nodiscard]] size_t length() const { + return m_data.size(); + } + + [[nodiscard]] size_t size() const { + return m_data.size(); + } + + operator std::string() const { + return str(); + } + + operator std::vector() const { + return vec(); + } + + void get(const std::function& callback); + + private: + std::string_view m_data; + std::string_view m_filename; +#ifndef B_PRODUCTION_MODE + std::string_view m_fullFilepath; +#endif + }; // class EmbeddedFile + + ${EMBEDDED_FILES_DECLARATIONS} + }; // struct embedded_files + + template + struct embed_string_literal { + constexpr embed_string_literal(const char (&str)[N]) { + std::copy_n(str, N, value); + } + constexpr bool operator!=(const embed_string_literal& other) const { + return std::equal(value, value + N, other.value); + } + [[nodiscard]] std::string str() const { + return std::string(value, N); + } + [[nodiscard]] constexpr bool _false() const { + return false; + } + char value[N]; + }; + + template + constexpr bool operator==(const embed_string_literal& left, const char (&right)[M]) { + return std::equal(left.value, left.value + N, right); + } + + template + constexpr EmbedInternal::EmbeddedFile embed() { + ${EMBEDDED_FILES_RETURNS}{ + static_assert(identifier._false(), "[b::embed<>] No such file or directory"); + } + } + +} // namespace b + +inline std::ostream& operator<<(std::ostream& stream, const b::EmbedInternal::EmbeddedFile& file) { + stream << file.str(); + return stream; +} + +#endif // BATTERY_EMBED_HPP diff --git a/script/embed_impl.cpp b/script/embed_impl.cpp new file mode 100644 index 0000000..2aa3cd7 --- /dev/null +++ b/script/embed_impl.cpp @@ -0,0 +1,137 @@ +// File generated using battery::embed (https://github.com/batterycenter/embed) +// DO NOT EDIT THIS FILE!!! + +#include "battery/embed.hpp" + +#if !defined(B_PRODUCTION_MODE) && !defined(B_OS_WEB) +#include +#include +#include +#include +#include +#include +#include +#endif // !B_PRODUCTION_MODE and !B_OS_WEB + +namespace b { + +#if !defined(B_PRODUCTION_MODE) && !defined(B_OS_WEB) + + // All this crazyness is necessary because we need to use std::string_view because of constexpr, + // and the string_view only points to a char array, so we need a string that outlives + // the string_view it is assigned to. + + struct FileData { + std::string filename; + std::string newContent; + std::string filepath; + std::filesystem::file_time_type lastWriteTime; + std::function callback; + }; + + static std::mutex embeddedFilesMapMutex; + static std::unordered_map embeddedFiles; + +#ifdef _WIN32 +#ifdef __clang__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + + static std::wstring embed_widen(const std::string& str) { + std::wstring_convert> converter; + return converter.from_bytes(str); + } + +#ifdef __clang__ +#pragma GCC diagnostic pop +#endif + +#endif // _WIN32 + + static std::optional embed_read_file(const std::string_view& filename) { +#ifdef _WIN32 + std::ifstream file(embed_widen(std::string(filename)).c_str(), std::ios::binary); +#else // _WIN32 + std::ifstream file(std::string(filename), std::ios::binary); +#endif // _WIN32 + if (file.fail()) { + return {}; + } + return std::string((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + } + + // Apple-Clang does not support std::jthread yet, hence we make our own version of jthread here: + class AutoThread { + public: + template + AutoThread(Tfunc&& function) + : m_thread([&]() { function(m_shouldStop); }) + {} + + ~AutoThread() { + m_shouldStop = true; + m_thread.join(); + } + + AutoThread(const AutoThread& other) = delete; + AutoThread(AutoThread&& other) = delete; + AutoThread& operator=(const AutoThread& other) = delete; + AutoThread& operator=(AutoThread&& other) = delete; + + private: + std::thread m_thread; + std::atomic m_shouldStop = false; + }; + + // This is a global file watcher thread that is created at program start and automatically destroyed at program end + // All embedded files are hot-reloaded by this thread. + AutoThread embeddedFileWatcherThread = AutoThread([](std::atomic& shouldStop) { + while (!shouldStop) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::lock_guard lock(embeddedFilesMapMutex); + for (auto& [key, filedata] : embeddedFiles) { + std::filesystem::path filepath(key); + std::error_code ec; + auto newWriteTime = std::filesystem::last_write_time(filepath, ec); + if (!ec) { + if (newWriteTime != filedata.lastWriteTime) { + filedata.lastWriteTime = newWriteTime; + auto fileresult = embed_read_file(key); + if (!fileresult) { + continue; + } + filedata.newContent = *fileresult; + EmbedInternal::EmbeddedFile newFile(filedata.newContent, filedata.filename, filedata.filepath); + filedata.callback(newFile); + } + } + } + } + }); + +#endif // !B_PRODUCTION_MODE and !B_OS_WEB + + void EmbedInternal::EmbeddedFile::get(const std::function& callback) { +#if defined(B_PRODUCTION_MODE) || defined(B_OS_WEB) + callback(*this); +#else // B_PRODUCTION_MODE or B_OS_WEB + auto fileresult = embed_read_file(m_fullFilepath); + if (fileresult) { + m_data = *fileresult; + } + callback(*this); + + FileData fileData; + fileData.filename = m_filename; + fileData.newContent = m_data; + fileData.filepath = m_fullFilepath; + fileData.callback = callback; + fileData.lastWriteTime = std::filesystem::last_write_time(m_fullFilepath); + + std::lock_guard lock(embeddedFilesMapMutex); + embeddedFiles[std::string(m_fullFilepath)] = fileData; +#endif // B_PRODUCTION_MODE or B_OS_WEB + } + +} // namespace b diff --git a/script/embed_source_file_template.cpp b/script/embed_source_file_template.cpp new file mode 100644 index 0000000..c2cb848 --- /dev/null +++ b/script/embed_source_file_template.cpp @@ -0,0 +1,21 @@ +// File generated using battery::embed (https://github.com/batterycenter/embed) +// Embedded file: '${FILENAME}' as '${IDENTIFIER}' +// Filesize: ${FILESIZE} bytes +// DO NOT EDIT THIS FILE!!! + +#include "battery/embed.hpp" + +namespace b { + +EmbedInternal::EmbeddedFile EmbedInternal::${IDENTIFIER} = { + std::string_view( + ${GENERATED_BYTE_ARRAY}, + ${FILESIZE} + ) + , "${FILENAME}" +#ifndef B_PRODUCTION_MODE + , "${FULL_PATH}" +#endif // !B_PRODUCTION_MODE +}; + +} // namespace b diff --git a/script/generate.cmake b/script/generate.cmake new file mode 100644 index 0000000..c9c4628 --- /dev/null +++ b/script/generate.cmake @@ -0,0 +1,10 @@ +file(READ "${FULL_PATH}" GENERATED_BYTE_ARRAY HEX) +string(LENGTH "${GENERATED_BYTE_ARRAY}" FILESIZE) +math(EXPR FILESIZE "${FILESIZE} / 2") + +string(REPEAT "[0-9a-f]" 32 PATTERN) +set(GENERATED_BYTE_ARRAY "\"${GENERATED_BYTE_ARRAY}") +string(REGEX REPLACE "${PATTERN}" "\\0\"\n \"" GENERATED_BYTE_ARRAY ${GENERATED_BYTE_ARRAY}) +string(REGEX REPLACE "([0-9a-f][0-9a-f])" "\\\\x\\1" GENERATED_BYTE_ARRAY ${GENERATED_BYTE_ARRAY}) +set(GENERATED_BYTE_ARRAY "${GENERATED_BYTE_ARRAY}\"") +configure_file(${INFILE} ${OUTFILE}) From e7ac2e4985bf802667bddbd05d8f2449aec2a5a6 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Fri, 11 Sep 2026 03:37:23 +0200 Subject: [PATCH 2/2] Fix MSVC source_group directives --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7153ce9..1d6b6a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,7 +122,7 @@ function(b_embed TARGET FILENAME) if (MSVC) target_sources(${TARGET} PRIVATE ${FULL_PATH}) source_group(TREE ${EMBED_BINARY_DIR}/autogen/${TARGET_ID}/src PREFIX "embed/autogen" FILES ${CPP_FILE}) - source_group(TREE ${EMBED_BINARY_DIR} PREFIX "embed/autogen" FILES ${EMBED_SOURCE_DIR}/script/embed_impl.cpp) + source_group(TREE ${EMBED_SOURCE_DIR} PREFIX "embed/autogen" FILES ${EMBED_SOURCE_DIR}/script/embed_impl.cpp) source_group(TREE ${EMBED_BINARY_DIR}/autogen/${TARGET_ID}/include/battery PREFIX "embed/autogen" FILES ${EMBED_HPP}) source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "/embed" FILES ${FULL_PATH}) endif()