diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 2923576..282b8d3 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -18,7 +18,9 @@ jobs: strategy: matrix: build_type: ["Debug", "RelWithDebInfo", "Release"] - name: "Build & Test ${{ matrix.build_type }}" + unity_build: ["ON", "OFF"] + conan_profile: ["./ConanProfiles/clang", "./ConanProfiles/clangd", "./ConanProfiles/clangd_asan"] + name: "Build & Test ${{ matrix.build_type }} with ${{ matrix.conan_profile }} (Unity Build: ${{ matrix.unity_build }})" steps: - name: Install Node.js run: apt-get update && apt-get install -y nodejs @@ -28,19 +30,12 @@ jobs: with: submodules: recursive - - name: Show ccache stats before - run: ccache --zero-stats - - name: Build run: | - conan profile detect - conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages --build=missing -s build_type=${{ matrix.build_type }} -o bin2cpp/*:build_tests=True - cmake -S . -B ./build/${{ matrix.build_type }} --toolchain ./build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -G "Ninja" + conan install . --remote=bigfootpackages -pr:h=${{ matrix.conan_profile }} -pr:b=${{ matrix.conan_profile }} --build=missing -s build_type=${{ matrix.build_type }} + cmake -S . -B ./build/${{ matrix.build_type }} --toolchain ./build/${{ matrix.build_type }}/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -G "Ninja" cmake --build build/${{ matrix.build_type }} --parallel $(nproc) - - name: Show ccache stats after - run: ccache --show-stats - - name: Unit Tests run: | cd ./build/${{ matrix.build_type }} diff --git a/.gitea/workflows/package.yml b/.gitea/workflows/package.yml new file mode 100644 index 0000000..338b163 --- /dev/null +++ b/.gitea/workflows/package.yml @@ -0,0 +1,55 @@ +name: Conan Packaging + +on: + push: + branches: + - '**' + workflow_dispatch: + +env: + CCACHE_BASEDIR: ${{ github.workspace }} + +jobs: + conan-packages: + runs-on: ubuntu-latest + timeout-minutes: 120 + container: + image: git.romainboullard.com/bigfootdev/linuxcppbuilder:main + env: + ARTIFACTORY_USER: ${{ secrets.ARTIFACTORY_USER }} + ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} + name: "Package Bin2CPP/1.0.0" + steps: + - name: Set BRANCH_NAME + run: echo "BRANCH_NAME=$(echo $GITHUB_REF_NAME | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV + + - name: Install Node.js + run: apt-get update && apt-get install -y nodejs + + - name: Checkout repository + uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Show ccache stats before + run: ccache --zero-stats + + - name: Run Conan packaging + run: | + echo "Building Bin2CPP@$1.0.0" + CONAN_LOGIN_USERNAME=${ARTIFACTORY_USER} \ + CONAN_PASSWORD=${ARTIFACTORY_PASSWORD} \ + conan create . \ + --version=1.0.0 \ + --user=bigfootdev \ + --channel=${{ env.BRANCH_NAME }} \ + -pr:b=./ConanProfiles/clang -pr:h=./ConanProfiles/clang \ + --build=missing --remote=bigfootpackages + + CONAN_LOGIN_USERNAME=${ARTIFACTORY_USER} \ + CONAN_PASSWORD=${ARTIFACTORY_PASSWORD} \ + conan upload bin2cpp/1.0.0@bigfootdev/${{ env.BRANCH_NAME }} \ + --only-recipe --remote=bigfootpackages + + - name: Show ccache stats after + run: ccache --show-stats diff --git a/.gitea/workflows/sonarqube.yml b/.gitea/workflows/sonarqube.yml index 2d8b34e..683929c 100644 --- a/.gitea/workflows/sonarqube.yml +++ b/.gitea/workflows/sonarqube.yml @@ -26,7 +26,7 @@ jobs: - name: Generate run: | conan profile detect - conan install . --deployer=full_deploy --deployer-folder=build --remote=bigfootpackages --build=missing -s build_type=Debug -o bin2cpp/*:build_tests=True + conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/clang_coverage -pr:b=./ConanProfiles/clang_coverage --build=missing -s build_type=Debug cmake -S . -B ./build/Debug --toolchain ./build/Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -G "Ninja" cmake --build build/Debug --parallel $(nproc) diff --git a/Bin2CPP/Sources/Bin2CPP/CMakeLists.txt b/Bin2CPP/Sources/Bin2CPP/CMakeLists.txt new file mode 100644 index 0000000..c72f1be --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPP/CMakeLists.txt @@ -0,0 +1,56 @@ +get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) +project(${PackageName}) + +add_executable(${PROJECT_NAME}) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20) + +file(GLOB_RECURSE BIN2CPPEXE_SOURCES + CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp +) + +file(GLOB_RECURSE BIN2CPPEXE_HEADERS + CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp +) + +target_sources(${PROJECT_NAME} + PRIVATE + ${BIN2CPPEXE_SOURCES} + PRIVATE + FILE_SET HEADERS + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/Include + FILES + ${BIN2CPPEXE_HEADERS} +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE + Bin2CPPCompileAndLinkFlags + Bin2CPPLib + CLI11::CLI11 + ${CMAKE_DL_LIBS}) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${BIN2CPPEXE_SOURCES} ${BIN2CPPEXE_HEADERS}) + +set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bin2CPP/${ParentFolder}) + +##################ASAN SETUP################### + +if(${ASAN}) + if (MSVC) + get_filename_component(MSVC_BIN_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY) + set(ASAN_DLL "${MSVC_BIN_DIR}/clang_rt.asan_dynamic-x86_64.dll") + + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "Copying ASan DLL: ${ASAN_DLL} to $" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ASAN_DLL}" "$" + ) + endif() +endif() + +########INSTALL + +install(TARGETS ${PROJECT_NAME} DESTINATION bin) \ No newline at end of file diff --git a/Bin2CPP/Sources/Bin2CPP/main.cpp b/Bin2CPP/Sources/Bin2CPP/main.cpp new file mode 100644 index 0000000..d948838 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPP/main.cpp @@ -0,0 +1,68 @@ +#include +#include + +#include + +int main(int argc, char** argv) +{ + CLI::App app {"Bin2CPP allows you to generate a C++ header containing the binary content of an input file"}; + argv = app.ensure_utf8(argv); + + std::string input; + app.add_option("-f,--input", input, "The input file")->required(); + std::string output; + app.add_option("-o,--output", output, "The output file")->required(); + std::optional arrayType; + app.add_option("--arrayType", arrayType, "The type of the array"); + std::optional arrayInclude; + app.add_option("--arrayInclude", arrayInclude, "Include for the array type"); + std::optional arrayName; + app.add_option("--arrayName", arrayName, "The array name"); + std::optional customNamespace; + app.add_option("--namespace", customNamespace, "The namespace"); + bool verbose = false; + app.add_option("--verbose", verbose, "Activate logging"); + + CLI11_PARSE(app, argc, argv); + + std::unique_ptr::Lifetime> loggerLifetime = + verbose ? std::make_unique::Lifetime>() : nullptr; + + Bin2CPP::Generator generator(input); + if (arrayType) + { + generator.SetMapping(Bin2CPP::MappingKey::ARRAY_TYPE, arrayType.value()); + } + if (arrayInclude) + { + generator.SetMapping(Bin2CPP::MappingKey::ARRAY_TYPE_INCLUDE, arrayInclude.value()); + } + if (arrayName) + { + generator.SetMapping(Bin2CPP::MappingKey::ARRAY_NAME, arrayName.value()); + } + if (customNamespace) + { + generator.SetMapping(Bin2CPP::MappingKey::NAMESPACE, customNamespace.value()); + } + + if (!generator.Generate()) + { + BIN2CPP_LOG_ERROR("Failed to generate '{}'", input); + return 1; + } + + std::ofstream out(output); + if (!out) + { + BIN2CPP_LOG_ERROR("Failed to open '{}'", output); + return 1; + } + + out << generator.Get(); + out.close(); + + BIN2CPP_LOG_INFO("'{}' Generated !", output); + + return 0; +} diff --git a/Bin2CPP/Sources/Bin2CPPExe/CMakeLists.txt b/Bin2CPP/Sources/Bin2CPPExe/CMakeLists.txt deleted file mode 100644 index e1d489b..0000000 --- a/Bin2CPP/Sources/Bin2CPPExe/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) -project(${PackageName}) - -add_executable(${PROJECT_NAME}) -set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) - -target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include) - -# collect sources (reconfigure when files are added/removed) -file(GLOB_RECURSE SOURCES - CONFIGURE_DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/*.h - ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp -) - -target_sources(${PROJECT_NAME} - PRIVATE - ${SOURCES} -) - -target_link_libraries(${PROJECT_NAME} PUBLIC CLI11::CLI11 Bin2CPPLib) -target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS}) - -source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${SOURCES}) - -set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bin2CPP/${ParentFolder}) - -bin2cpp_setup_dependencies("Bin2CPPExe") \ No newline at end of file diff --git a/Bin2CPP/Sources/Bin2CPPExe/main.cpp b/Bin2CPP/Sources/Bin2CPPExe/main.cpp deleted file mode 100644 index 427d4ab..0000000 --- a/Bin2CPP/Sources/Bin2CPPExe/main.cpp +++ /dev/null @@ -1,4 +0,0 @@ -int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) -{ - return 0; -} diff --git a/Bin2CPP/Sources/Bin2CPPLib/CMakeLists.txt b/Bin2CPP/Sources/Bin2CPPLib/CMakeLists.txt index 7235b2a..d548139 100644 --- a/Bin2CPP/Sources/Bin2CPPLib/CMakeLists.txt +++ b/Bin2CPP/Sources/Bin2CPPLib/CMakeLists.txt @@ -2,27 +2,51 @@ get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) project(${PackageName}) add_library(${PROJECT_NAME} STATIC) -set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20) -target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include) +file(GLOB_RECURSE BIN2CPPLIB_SOURCES + CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp +) -# collect sources (reconfigure when files are added/removed) -file(GLOB_RECURSE SOURCES +file(GLOB_RECURSE BIN2CPPLIB_HEADERS CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp +) + +file(GLOB_RECURSE BIN2CPPLIB_OTHERS + CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp.in ) target_sources(${PROJECT_NAME} PRIVATE - ${SOURCES} + ${BIN2CPPLIB_SOURCES} + PUBLIC + FILE_SET HEADERS + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/Include + FILES + ${BIN2CPPLIB_HEADERS} ) -target_link_libraries(${PROJECT_NAME} PUBLIC EASTL::EASTL rapidhash::rapidhash mimalloc) -target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_DL_LIBS}) -target_link_libraries(${PROJECT_NAME} PRIVATE $<$:cpptrace::cpptrace> quill::quill) +target_link_libraries(${PROJECT_NAME} + PRIVATE + Bin2CPPCompileAndLinkFlags + PUBLIC + $,mimalloc-asan,mimalloc-static> + quill::quill + $<$:cpptrace::cpptrace> + magic_enum::magic_enum) -source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${SOURCES}) +target_compile_definitions(${PROJECT_NAME} + PUBLIC + QUILL_NO_EXCEPTIONS + QUILL_DISABLE_NON_PREFIXED_MACROS) + +set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/MimallocImpl.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src FILES ${BIN2CPPLIB_SOURCES} ${BIN2CPPLIB_HEADERS} ${BIN2CPPLIB_OTHERS}) set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Bin2CPP/${ParentFolder}) \ No newline at end of file diff --git a/Bin2CPP/Sources/Bin2CPPLib/Generator.cpp b/Bin2CPP/Sources/Bin2CPPLib/Generator.cpp new file mode 100644 index 0000000..1b7e190 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Generator.cpp @@ -0,0 +1,280 @@ +/********************************************************************* + * \file Generator.cpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace Bin2CPP +{ +Generator::Generator(const std::string_view p_inputFile): + m_inputFile(p_inputFile) +{ +} + +/****************************************************************************************/ + +void Generator::SetMapping(const MappingKey p_key, const std::string_view p_value) +{ + const std::optional index = magic_enum::enum_index(p_key); + BIN2CPP_CRITICAL_ASSERT(index.has_value(), "Incorrect mapping key! Got {}", magic_enum::enum_integer(p_key)); + + m_mappingTable[index.value()] = p_value; +} + +/****************************************************************************************/ + +bool Generator::Generate() +{ + if (!ComputeMappings()) + { + BIN2CPP_LOG_ERROR("Invalid mappings! Can't generate file!"); + return false; + } + + m_result = g_generatedTemplate; + + for (std::uint32_t i = 0; i < m_mappingTable.size(); ++i) + { + const std::string KEY = magic_enum::enum_name(magic_enum::enum_value(i)).data(); + const std::string& VALUE = m_mappingTable[i]; + + const std::string pattern = "\\{\\{" + KEY + "\\}\\}"; + std::regex placeholderRegex(pattern); + m_result = std::regex_replace(m_result, placeholderRegex, VALUE); + } + + return Validate(); +} + +/****************************************************************************************/ + +std::string_view Generator::Get() const +{ + return m_result; +} + +/****************************************************************************************/ + +bool Generator::ComputeMappings() +{ + std::filesystem::path file {m_inputFile.data()}; + if (!std::filesystem::exists(file)) + { + BIN2CPP_LOG_ERROR("File '{}' does not exists!", m_inputFile); + return false; + } + if (std::filesystem::is_directory(file)) + { + BIN2CPP_LOG_ERROR("'{}' is not a file!", m_inputFile); + return false; + } + + if (!ComputeFilename()) + { + BIN2CPP_LOG_ERROR("Failed to compute filename"); + return false; + } + if (!ComputeGuardName()) + { + BIN2CPP_LOG_ERROR("Failed to compute GuardName"); + return false; + } + if (!ComputeArrayTypeInclude()) + { + BIN2CPP_LOG_ERROR("Failed to compute ArrayTypeInclude"); + return false; + } + if (!ComputeArrayType()) + { + BIN2CPP_LOG_ERROR("Failed to compute ArrayType"); + return false; + } + if (!ComputeArrayName()) + { + BIN2CPP_LOG_ERROR("Failed to compute ArrayName"); + return false; + } + + std::ifstream in {m_inputFile.data(), std::ios::binary}; + if (!in) + { + BIN2CPP_LOG_ERROR("Failed to open '{}'", m_inputFile); + return false; + } + in.seekg(0, std::ios::end); + const size_t fileSize = static_cast(in.tellg()); + in.seekg(0, std::ios::beg); + + std::vector data(fileSize); + in.read(std::bit_cast(data.data()), fileSize); + + if (!ComputeArraySize(data)) + { + BIN2CPP_LOG_ERROR("Failed to compute ArraySize"); + return false; + } + if (!ComputeData(data)) + { + BIN2CPP_LOG_ERROR("Failed to compute Data"); + return false; + } + + return true; +} + +/****************************************************************************************/ + +bool Generator::ComputeFilename() +{ + std::filesystem::path file {m_inputFile.data()}; + m_mappingTable[magic_enum::enum_index(MappingKey::FILENAME).value()] = file.filename().string().c_str(); + + return true; +} + +/****************************************************************************************/ + +bool Generator::ComputeGuardName() +{ + std::filesystem::path file {m_inputFile.data()}; + std::string guardName = file.filename().string(); + + std::transform(guardName.begin(), + guardName.end(), + guardName.begin(), + [](const char c) + { + if (!std::isalnum(c)) + { + return static_cast('_'); + } + else + { + return std::toupper(c); + } + }); + m_mappingTable[magic_enum::enum_index(MappingKey::GUARD_NAME).value()] = std::format("{}_HPP", guardName); + + return true; +} + +/****************************************************************************************/ + +bool Generator::ComputeArrayTypeInclude() +{ + std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_TYPE_INCLUDE).value()]; + if (value.empty()) + { + value = ""; + } + + return true; +} + +/****************************************************************************************/ + +bool Generator::ComputeArrayType() +{ + std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_TYPE).value()]; + if (value.empty()) + { + value = "std::array"; + } + + return true; +} + +/****************************************************************************************/ + +bool Generator::ComputeArrayName() +{ + std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_NAME).value()]; + if (value.empty()) + { + std::filesystem::path file {m_inputFile.data()}; + value = std::format("g_{}", file.filename().string()); + + std::transform(value.begin(), + value.end(), + value.begin(), + [](const char c) + { + if (!std::isalnum(c)) + { + return static_cast('_'); + } + else + { + return static_cast(c); + } + }); + } + + return true; +} + +/****************************************************************************************/ + +bool Generator::ComputeArraySize(const std::span p_data) +{ + m_mappingTable[magic_enum::enum_index(MappingKey::ARRAY_SIZE).value()] = std::to_string(p_data.size()); + return true; +} + +/****************************************************************************************/ + +bool Generator::ComputeData(const std::span p_data) +{ + std::string& value = m_mappingTable[magic_enum::enum_index(MappingKey::DATA).value()]; + value.clear(); + + constexpr std::size_t bytesPerLine = 16; + constexpr std::string_view linePrefix = "\n "; + + for (std::size_t i = 0; i < p_data.size(); ++i) + { + if (i > 0 && i % bytesPerLine == 0) + { + value.append(linePrefix.data(), linePrefix.size()); + } + + const std::string element = std::format("std::byte{{0x{:02X}}}", std::to_integer(p_data[i])); + value.append(element.data(), element.size()); + + if (i + 1 < p_data.size()) + { + value.append(", "); + } + } + + return true; +} + +/****************************************************************************************/ + +bool Generator::Validate() +{ + std::regex unreplacedRegex(R"(\{\{[A-Z_]+\}\})"); + std::smatch match; + + if (std::regex_search(m_result, match, unreplacedRegex)) + { + BIN2CPP_LOG_ERROR("Warning: Unreplaced placeholder found: {}", match.str()); + return false; + } + + return true; +} +} // namespace Bin2CPP diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Assert.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Assert.hpp new file mode 100644 index 0000000..cd07ce1 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/Assert.hpp @@ -0,0 +1,134 @@ +/********************************************************************* + * \file Assert.hpp + * + * \author Romain BOULLARD + * \date October 2025 + *********************************************************************/ +#ifndef BIN2CPP_ASSERT_HPP +#define BIN2CPP_ASSERT_HPP +#include + +#if defined BIN2CPP_NOT_OPTIMIZED + +#include + +#include +#include + +#if defined BIN2CPP_LINUX +#include +#endif + +namespace Bin2CPP +{ +class AssertHandler +{ + public: + AssertHandler() = delete; + + AssertHandler(const AssertHandler& p_handler) = delete; + AssertHandler(AssertHandler&& p_handler) = delete; + + ~AssertHandler() = delete; + + /** + * Handle an assertion. + * + * \param p_location Location of the assertion. + * \param p_stacktrace The stack trace + * \param p_format Format string for the assertion message. + * \param p_args Arguments for the format string. + */ + template + static void Handle(const std::source_location& p_location, + const std::string_view p_stacktrace, + std::format_string p_format, + ARGS&&... p_args) + { + BIN2CPP_LOG_FATAL("Assert: {} (File:{}, Line:{}, Function:{})\n{}", + std::format(p_format, std::forward(p_args)...), + p_location.file_name(), + p_location.line(), + p_location.function_name(), + p_stacktrace); + } + + AssertHandler& operator=(const AssertHandler& p_handler) = delete; + AssertHandler& operator=(AssertHandler&& p_handler) = delete; +}; +} // namespace Bin2CPP + +#if defined BIN2CPP_WINDOWS +#define BIN2CPP_BREAK \ + do \ + { \ + __debugbreak(); \ + } while (false) +#elif defined BIN2CPP_LINUX +#define BIN2CPP_BREAK \ + do \ + { \ + std::raise(SIGTRAP); \ + } while (false) +#endif + +#define BIN2CPP_ASSERT(p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + Bin2CPP::AssertHandler::Handle(location, \ + cpptrace::generate_trace().to_string(), \ + p_message __VA_OPT__(, ) __VA_ARGS__); \ + if (Bin2CPP::Singleton::HasInstance()) \ + { \ + Bin2CPP::Singleton::Instance().Flush(); \ + } \ + BIN2CPP_BREAK; \ + } \ + } while (false) + +#define BIN2CPP_SOFT_ASSERT(p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + Bin2CPP::AssertHandler::Handle(location, \ + cpptrace::generate_trace().to_string(), \ + p_message __VA_OPT__(, ) __VA_ARGS__); \ + if (Bin2CPP::Singleton::HasInstance()) \ + { \ + Bin2CPP::Singleton::Instance().Flush(); \ + } \ + BIN2CPP_BREAK; \ + } \ + } while (false) + +#define BIN2CPP_CRITICAL_ASSERT(p_assert, p_message, ...) \ + do \ + { \ + constexpr std::source_location location = std::source_location::current(); \ + if (!(p_assert)) [[unlikely]] \ + { \ + Bin2CPP::AssertHandler::Handle(location, \ + cpptrace::generate_trace().to_string(), \ + p_message __VA_OPT__(, ) __VA_ARGS__); \ + if (Bin2CPP::Singleton::HasInstance()) \ + { \ + Bin2CPP::Singleton::Instance().Flush(); \ + } \ + BIN2CPP_BREAK; \ + std::abort(); \ + } \ + } while (false) + +#else +#define BIN2CPP_ASSERT(p_assert, p_message, ...) + +#define BIN2CPP_SOFT_ASSERT(p_assert, p_message, ...) + +#define BIN2CPP_CRITICAL_ASSERT(p_assert, p_message, ...) +#endif +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/GeneratedTemplate.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/GeneratedTemplate.hpp new file mode 100644 index 0000000..2645f23 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/GeneratedTemplate.hpp @@ -0,0 +1,36 @@ +/********************************************************************* + * \file GeneratedTemplate.hpp + * + * \author Romain BOULLARD + * \date March 2026 + *********************************************************************/ +#ifndef BIN2CPP_GENERATED_TEMPLATE_HPP +#define BIN2CPP_GENERATED_TEMPLATE_HPP +#include + +namespace Bin2CPP +{ +constexpr std::string_view g_generatedTemplate = R"(/** + * Auto-generated header from: {{FILENAME}} + * Generated by Bin2CPP + * + * DO NOT TOUCH + */ +#ifndef {{GUARD_NAME}} +#define {{GUARD_NAME}} +#include {{ARRAY_TYPE_INCLUDE}} +#include + +namespace {{NAMESPACE}} +{ + inline constexpr {{ARRAY_TYPE}} {{ARRAY_NAME}} = { + {{DATA}} + }; + +} // namespace {{NAMESPACE}} + +#endif // {{GUARD_NAME}} +)"; +} // namespace Bin2CPP + +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Generator.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Generator.hpp new file mode 100644 index 0000000..a18b646 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/Generator.hpp @@ -0,0 +1,157 @@ +/********************************************************************* + * \file Generator.hpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#ifndef BIN2CPP_GENERATOR_HPP +#define BIN2CPP_GENERATOR_HPP +#include + +#include +#include +#include + +namespace Bin2CPP +{ +enum class MappingKey +{ + FILENAME, + GUARD_NAME, + NAMESPACE, + ARRAY_TYPE_INCLUDE, + ARRAY_TYPE, + ARRAY_SIZE, + ARRAY_NAME, + DATA +}; + +class Generator +{ + public: + /** + * Constructor + * + * \param p_inputFile the Input file + */ + Generator(const std::string_view p_inputFile); + + Generator(const Generator& p_generator) = default; + Generator(Generator&& p_generator) = default; + + /** + * Set a mapping + * + */ + void SetMapping(const MappingKey p_key, const std::string_view p_value); + + /** + * Generate + * + * \return True if successful, false otherwise + */ + [[nodiscard]] + bool Generate(); + + /** + * Get + * + */ + [[nodiscard]] + std::string_view Get() const; + + ~Generator() = default; + + Generator& operator=(const Generator& p_generator) = default; + Generator& operator=(Generator&& p_generator) = default; + + private: + /** + * Compute the mappings + * + * \return True if all mappings have valid values, false otherwise + */ + [[nodiscard]] + bool ComputeMappings(); + + /** + * Compute the filename mapping + * + * \return True if success, false otherwise + */ + [[nodiscard]] + bool ComputeFilename(); + + /** + * Compute the guardName mapping + * + * \return True if success, false otherwise + */ + [[nodiscard]] + bool ComputeGuardName(); + + /** + * Compute the arrayTypeInclude mapping + * + * \return True if success, false otherwise + */ + [[nodiscard]] + bool ComputeArrayTypeInclude(); + + /** + * Compute the arrayType mapping + * + * \return True if success, false otherwise + */ + [[nodiscard]] + bool ComputeArrayType(); + + /** + * Compute the arrayName mapping + * + * \return True if success, false otherwise + */ + [[nodiscard]] + bool ComputeArrayName(); + + /** + * Compute the arraySize mapping + * + * \return True if success, false otherwise + */ + [[nodiscard]] + bool ComputeArraySize(const std::span p_data); + + /** + * Compute the data mapping + * + * \return True if success, false otherwise + */ + [[nodiscard]] + bool ComputeData(const std::span p_data); + + /** + * Validate generated is correct (no remaining tags) + * + * \return True if valid, false otherwise + */ + [[nodiscard]] + bool Validate(); + + /** + * The mapping table + */ + std::array()> m_mappingTable; + + /** + * The input file + */ + std::string m_inputFile; + + /** + * The result + */ + std::string m_result; +}; +} // namespace Bin2CPP +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Log.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Log.hpp new file mode 100644 index 0000000..d9a3ab2 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/Log.hpp @@ -0,0 +1,127 @@ +/********************************************************************* + * \file Log.hpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#ifndef BIN2CPP_LOG_HPP +#define BIN2CPP_LOG_HPP +#include + +#include + +#ifdef BIN2CPP_WINDOWS +#pragma warning(disable: 4702) +#endif +#include +#include +#include +#include +#include +#if defined BIN2CPP_WINDOWS +#pragma warning(default: 4702) +#endif + +namespace Bin2CPP +{ +class Log +{ + public: + Log(); + + Log(const Log& p_logger) = delete; + Log(Log&& p_logger) = delete; + + /** + * Register a logger. + * + * \return The logger, nullptr if it does not exist + */ + [[nodiscard]] + quill::Logger* GetLogger(); + + /* + * Flush all the loggers + * + */ + void Flush(); + + ~Log(); + + Log& operator=(const Log& p_logger) = delete; + Log& operator=(Log&& p_logger) = delete; + + private: + /* + * The sinks + */ + std::array, 1> m_sinks; +}; +} // namespace Bin2CPP + +#define BIN2CPP_LOG_DEBUG(fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_DEBUG(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIN2CPP_LOG_TRACE(fmt, ...) \ + do \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_TRACE_L3(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } while (0) + +#define BIN2CPP_LOG_INFO(fmt, ...) \ + do \ + { \ + if (Bin2CPP::Singleton::HasInstance()) \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_INFO(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } \ + } while (0) + +#define BIN2CPP_LOG_WARN(fmt, ...) \ + do \ + { \ + if (Bin2CPP::Singleton::HasInstance()) \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_WARNING(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } \ + } while (0) + +#define BIN2CPP_LOG_ERROR(fmt, ...) \ + do \ + { \ + if (Bin2CPP::Singleton::HasInstance()) \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_ERROR(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } \ + } while (0) + +#define BIN2CPP_LOG_FATAL(fmt, ...) \ + do \ + { \ + if (Bin2CPP::Singleton::HasInstance()) \ + { \ + if (quill::Logger* logger = Bin2CPP::Singleton::Instance().GetLogger()) \ + { \ + QUILL_LOG_CRITICAL(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \ + } \ + } \ + } while (0) +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Include/Singleton.hpp b/Bin2CPP/Sources/Bin2CPPLib/Include/Singleton.hpp new file mode 100644 index 0000000..6eb4780 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Include/Singleton.hpp @@ -0,0 +1,104 @@ +/********************************************************************* + * \file Singleton.hpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#ifndef BIN2CPP_SINGLETON_HPP +#define BIN2CPP_SINGLETON_HPP +#include + +namespace Bin2CPP +{ +template +class Singleton +{ + public: + Singleton() = delete; + + Singleton(const Singleton& p_singleton) = delete; + Singleton(Singleton&& p_singleton) = delete; + + ~Singleton() = delete; + + /** + * Get the instance. + * + * \return The instance + */ + static TYPE& Instance() + { + return ms_instance.value(); + } + + /** + * Is the instance initialized + * + * \return True if initialized, false otherwise + */ + static bool HasInstance() + { + return ms_instance.has_value(); + } + + class Lifetime + { + public: + /** + * Constructor. + * + * \param p_args Arguments for the singleton + */ + template + explicit Lifetime(ARGS&&... p_args) + { + Initialize(std::forward(p_args)...); + } + + Lifetime(const Lifetime& p_lifetime) = delete; + Lifetime(Lifetime&& p_lifetime) = delete; + + ~Lifetime() + { + Finalize(); + } + + [[nodiscard]] + Lifetime& operator=(const Lifetime& p_lifetime) = delete; + [[nodiscard]] + Lifetime& operator=(Lifetime&& p_lifetime) = delete; + }; + + [[nodiscard]] + Singleton& operator=(const Singleton& p_singleton) = delete; + [[nodiscard]] + Singleton& operator=(Singleton&& p_singleton) = delete; + + private: + /** + * Initialize the singleton. + * + * \param p_args Arguments for the singleton + */ + template + static void Initialize(ARGS&&... p_args) + { + ms_instance.emplace(std::forward(p_args)...); + } + + /** + * Finalize the singleton. + * + */ + static void Finalize() + { + ms_instance.reset(); + } + + /** + * The singleton. + */ + inline static std::optional ms_instance; +}; +} // namespace Bin2CPP +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/Log.cpp b/Bin2CPP/Sources/Bin2CPPLib/Log.cpp new file mode 100644 index 0000000..525a093 --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/Log.cpp @@ -0,0 +1,49 @@ +/******************************************************************* + * \file Log.cpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#include + +namespace Bin2CPP +{ +Log::Log() +{ + quill::Backend::start(); + + m_sinks[0] = quill::Frontend::create_or_get_sink("ConsoleSink"); + + quill::Logger* logger = quill::Frontend::create_or_get_logger("Bin2CPP", m_sinks[0]); + logger->set_log_level(quill::LogLevel::TraceL3); +} + +/****************************************************************************************/ + +quill::Logger* Log::GetLogger() +{ + return quill::Frontend::get_logger("Bin2CPP"); +} + +/****************************************************************************************/ + +void Log::Flush() +{ + for (quill::Logger* logger: quill::Frontend::get_all_loggers()) + { + logger->flush_log(); + } +} + +/****************************************************************************************/ + +Log::~Log() +{ + for (quill::Logger* logger: quill::Frontend::get_all_loggers()) + { + quill::Frontend::remove_logger(logger); + } + + quill::Backend::stop(); +} +} // namespace Bin2CPP diff --git a/Bin2CPP/Sources/Bin2CPPLib/MimallocImpl.cpp b/Bin2CPP/Sources/Bin2CPPLib/MimallocImpl.cpp new file mode 100644 index 0000000..bdb5e6a --- /dev/null +++ b/Bin2CPP/Sources/Bin2CPPLib/MimallocImpl.cpp @@ -0,0 +1,96 @@ +/********************************************************************* + * \file MimallocImpl.cpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#if defined BIN2CPP_WINDOWS +#pragma comment(linker, "/include:mi_version") +#pragma warning(disable: 4100 4559) +#elif defined BIN2CPP_LINUX +#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" +#endif +#endif + +// Taken from mimalloc-new-delete.h + +// clang-format off + +// ---------------------------------------------------------------------------- +// This header provides convenient overrides for the new and +// delete operations in C++. +// +// This header should be included in only one source file! +// +// On Windows, or when linking dynamically with mimalloc, these +// can be more performant than the standard new-delete operations. +// See +// --------------------------------------------------------------------------- +#if defined(__cplusplus) + #include + #include + + #if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_) + // stay consistent with VCRT definitions + #define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n) + #define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n) + #else + #define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict + #define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict + #endif + + void operator delete(void* p) noexcept { mi_free(p); }; + void operator delete[](void* p) noexcept { mi_free(p); }; + + void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); } + void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); } + + mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { return mi_new(n); } + mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); } + + mi_decl_new_nothrow(n) void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } + mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } + + // Not from mimalloc-new-delete.h, but necessary for EASTL + void* operator new[](size_t size, const char* name, int flags, unsigned debugFlags, const char* file, int line) noexcept(false) { return mi_new(size); } + + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) + void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); }; + void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); }; + #endif + + #if (__cplusplus > 201402L || defined(__cpp_aligned_new)) + void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; + void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; + void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast(al)); } + + void* operator new (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } + void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } + + // Not from mimalloc-new-delete.h, but necessary for EASTL + void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName, int flags, unsigned debugFlags, const char* file, int line) noexcept(false) { return mi_new_aligned(size, alignment); } + #endif + +#endif + +// clang-format on + +#if defined BIN2CPP_WINDOWS +#pragma warning(default: 4100 4559) +#elif defined BIN2CPP_LINUX +#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER) +#pragma GCC diagnostic pop +#else +#pragma clang diagnostic pop +#endif +#endif diff --git a/Bin2CPP/Sources/Bin2CPPLib/touch.cpp b/Bin2CPP/Sources/Bin2CPPLib/touch.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/Bin2CPP/Sources/CMakeLists.txt b/Bin2CPP/Sources/CMakeLists.txt index 81727b5..96c48ae 100644 --- a/Bin2CPP/Sources/CMakeLists.txt +++ b/Bin2CPP/Sources/CMakeLists.txt @@ -1,2 +1,2 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPPLib) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPPExe) \ No newline at end of file +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPP) \ No newline at end of file diff --git a/Bin2CPP/Tests/Bin2CPPLib/CMakeLists.txt b/Bin2CPP/Tests/Bin2CPPLib/CMakeLists.txt index 046f1ca..4f283e1 100644 --- a/Bin2CPP/Tests/Bin2CPPLib/CMakeLists.txt +++ b/Bin2CPP/Tests/Bin2CPPLib/CMakeLists.txt @@ -2,52 +2,64 @@ get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME) project(${PackageName}Tests) add_executable(${PROJECT_NAME}) -set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20) -target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Include) +file(GLOB_RECURSE BIN2CPPLIBTESTS_SOURCES + CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp +) -file(GLOB_RECURSE TEST_SOURCES +file(GLOB_RECURSE BIN2CPPLIBTESTS_HEADERS CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) target_sources(${PROJECT_NAME} PRIVATE - ${TEST_SOURCES} + ${BIN2CPPLIBTESTS_SOURCES} + PRIVATE + FILE_SET HEADERS + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/Include + FILES + ${BIN2CPPLIBTESTS_HEADERS} ) -target_link_libraries(${PROJECT_NAME} PRIVATE gtest::gtest Bin2CPPLib) +target_link_libraries(${PROJECT_NAME} + PRIVATE + Bin2CPPCompileAndLinkFlags + Bin2CPPLib + gtest::gtest) include(GoogleTest) gtest_discover_tests(${PROJECT_NAME} XML_OUTPUT_DIR ${CMAKE_BINARY_DIR}/TestResults/) -source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src/ FILES ${TEST_SOURCES}) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX Src/ FILES ${BIN2CPPLIBTESTS_SOURCES} ${BIN2CPPLIBTESTS_HEADERS}) set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER Tests/Bin2CPP/${ParentFolder}) +##################ASAN SETUP################### + +if(${ASAN}) + if (MSVC) + get_filename_component(MSVC_BIN_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY) + set(ASAN_DLL "${MSVC_BIN_DIR}/clang_rt.asan_dynamic-x86_64.dll") + + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "Copying ASan DLL: ${ASAN_DLL} to $" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ASAN_DLL}" "$" + ) + endif() +endif() + ##################COPY FIXTURE FOLDER################### if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/Fixture) file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Fixture) endif() -# Track all fixture files -file(GLOB_RECURSE FIXTURE_FILES - CONFIGURE_DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/Fixture/* -) - -add_custom_target(${PROJECT_NAME}Fixture - COMMAND ${CMAKE_COMMAND} -E remove_directory $/Fixture - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/Fixture $/Fixture - DEPENDS ${FIXTURE_FILES} - COMMENT "Copying Fixture folder for ${PROJECT_NAME}" -) - -add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}Fixture) - -set_target_properties(${PROJECT_NAME}Fixture PROPERTIES FOLDER UtilityTargets/Tests/Bin2CPP/${ParentFolder}) - -bin2cpp_setup_dependencies("Tests/Bin2CPP") \ No newline at end of file +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_CURRENT_SOURCE_DIR}/Fixture $/Fixture + COMMENT "Copying Fixture folder ${CMAKE_CURRENT_SOURCE_DIR}/Fixture to $/Fixture" +) \ No newline at end of file diff --git a/Bin2CPP/Tests/Bin2CPPLib/Fixture/toto.txt b/Bin2CPP/Tests/Bin2CPPLib/Fixture/toto.txt index e69de29..5e1c309 100644 --- a/Bin2CPP/Tests/Bin2CPPLib/Fixture/toto.txt +++ b/Bin2CPP/Tests/Bin2CPPLib/Fixture/toto.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/Bin2CPP/Tests/Bin2CPPLib/Generator.cpp b/Bin2CPP/Tests/Bin2CPPLib/Generator.cpp new file mode 100644 index 0000000..9823fc3 --- /dev/null +++ b/Bin2CPP/Tests/Bin2CPPLib/Generator.cpp @@ -0,0 +1,139 @@ +/********************************************************************* + * \file Generator.cpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#include + +#include + +#include + +namespace Bin2CPP +{ +class GeneratorFixture: public ::testing::Test +{ + protected: + Singleton::Lifetime m_lifetime; +}; + +/****************************************************************************************/ + +TEST_F(GeneratorFixture, GenerateDefault) +{ + Generator generator("Fixture/toto.txt"); + EXPECT_TRUE(generator.Generate()); + + constexpr std::string_view expectedResult = R"(/** + * Auto-generated header from: toto.txt + * Generated by Bin2CPP + * + * DO NOT TOUCH + */ +#ifndef TOTO_TXT_HPP +#define TOTO_TXT_HPP +#include +#include + +namespace +{ + inline constexpr std::array g_toto_txt = { + std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F}, + std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C}, + std::byte{0x64} + }; + +} // namespace + +#endif // TOTO_TXT_HPP +)"; + EXPECT_STREQ(expectedResult.data(), generator.Get().data()); +} + +/****************************************************************************************/ + +TEST_F(GeneratorFixture, GenerateNamespace) +{ + Generator generator("Fixture/toto.txt"); + generator.SetMapping(MappingKey::NAMESPACE, "Test"); + EXPECT_TRUE(generator.Generate()); + + constexpr std::string_view expectedResult = R"(/** + * Auto-generated header from: toto.txt + * Generated by Bin2CPP + * + * DO NOT TOUCH + */ +#ifndef TOTO_TXT_HPP +#define TOTO_TXT_HPP +#include +#include + +namespace Test +{ + inline constexpr std::array g_toto_txt = { + std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F}, + std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C}, + std::byte{0x64} + }; + +} // namespace Test + +#endif // TOTO_TXT_HPP +)"; + EXPECT_STREQ(expectedResult.data(), generator.Get().data()); +} + +/****************************************************************************************/ + +TEST_F(GeneratorFixture, GenerateCustomArray) +{ + Generator generator("Fixture/toto.txt"); + generator.SetMapping(MappingKey::ARRAY_TYPE, "eastl::array"); + generator.SetMapping(MappingKey::ARRAY_TYPE_INCLUDE, ""); + generator.SetMapping(MappingKey::ARRAY_NAME, "g_myArray"); + EXPECT_TRUE(generator.Generate()); + + constexpr std::string_view expectedResult = R"(/** + * Auto-generated header from: toto.txt + * Generated by Bin2CPP + * + * DO NOT TOUCH + */ +#ifndef TOTO_TXT_HPP +#define TOTO_TXT_HPP +#include +#include + +namespace +{ + inline constexpr eastl::array g_myArray = { + std::byte{0x48}, std::byte{0x65}, std::byte{0x6C}, std::byte{0x6C}, std::byte{0x6F}, + std::byte{0x20}, std::byte{0x57}, std::byte{0x6F}, std::byte{0x72}, std::byte{0x6C}, + std::byte{0x64} + }; + +} // namespace + +#endif // TOTO_TXT_HPP +)"; + EXPECT_STREQ(expectedResult.data(), generator.Get().data()); +} + +/****************************************************************************************/ + +TEST_F(GeneratorFixture, NonExistentFile) +{ + Generator generator("Fixture/tata.txt"); + EXPECT_FALSE(generator.Generate()); +} + +/****************************************************************************************/ + +TEST_F(GeneratorFixture, Directory) +{ + Generator generator("Fixture/"); + EXPECT_FALSE(generator.Generate()); +} +} // namespace Bin2CPP diff --git a/Bin2CPP/Tests/Bin2CPPLib/Log.cpp b/Bin2CPP/Tests/Bin2CPPLib/Log.cpp new file mode 100644 index 0000000..c6177f1 --- /dev/null +++ b/Bin2CPP/Tests/Bin2CPPLib/Log.cpp @@ -0,0 +1,76 @@ +/********************************************************************* + * \file Log.cpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#include + +#include + +#include + +namespace Bin2CPP +{ +class LogFixture: public ::testing::Test +{ + protected: + Log m_log; +}; + +/****************************************************************************************/ + +TEST_F(LogFixture, GetLogger_ShouldReturnTheLogger) +{ + EXPECT_TRUE(m_log.GetLogger()); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogDebug) +{ + Singleton::Lifetime singletonLifetime; + BIN2CPP_LOG_DEBUG("Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogTrace) +{ + Singleton::Lifetime singletonLifetime; + + BIN2CPP_LOG_TRACE("Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogInfo) +{ + Singleton::Lifetime singletonLifetime; + BIN2CPP_LOG_INFO("Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogWarn) +{ + Singleton::Lifetime singletonLifetime; + BIN2CPP_LOG_WARN("Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogError) +{ + Singleton::Lifetime singletonLifetime; + BIN2CPP_LOG_ERROR("Hello"); +} + +/****************************************************************************************/ + +TEST_F(LogFixture, LogFatal) +{ + Singleton::Lifetime singletonLifetime; + BIN2CPP_LOG_FATAL("Hello"); +} +} // namespace Bin2CPP diff --git a/Bin2CPP/Tests/Bin2CPPLib/Singleton.cpp b/Bin2CPP/Tests/Bin2CPPLib/Singleton.cpp new file mode 100644 index 0000000..490d7b5 --- /dev/null +++ b/Bin2CPP/Tests/Bin2CPPLib/Singleton.cpp @@ -0,0 +1,39 @@ +/********************************************************************* + * \file Singleton.cpp + * + * \author Romain BOULLARD + * \date February 2026 + *********************************************************************/ +#include + +#include + +namespace Bin2CPP +{ +class SingletonFixture: public ::testing::Test +{ + protected: + Singleton::Lifetime m_lifetime {8}; +}; + +/****************************************************************************************/ + +TEST_F(SingletonFixture, HasInstance_ShouldReturnTrueIfSingletonIsInitialized) +{ + EXPECT_TRUE(Singleton::HasInstance()); +} + +/****************************************************************************************/ + +TEST_F(SingletonFixture, HasInstance_ShouldReturnFaleIfSingletonIsNotInitialized) +{ + EXPECT_FALSE(Singleton::HasInstance()); +} + +/****************************************************************************************/ + +TEST_F(SingletonFixture, Instance_ShouldReturnTheInstance) +{ + EXPECT_EQ(Singleton::Instance(), 8); +} +} // namespace Bin2CPP diff --git a/Bin2CPP/Tests/Bin2CPPLib/touch.cpp b/Bin2CPP/Tests/Bin2CPPLib/touch.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/CMake/Bin2CPPTargets.cmake b/CMake/Bin2CPPTargets.cmake new file mode 100644 index 0000000..9dfd8e6 --- /dev/null +++ b/CMake/Bin2CPPTargets.cmake @@ -0,0 +1,23 @@ +if(NOT TARGET Bin2CPP) + if(CMAKE_CROSSCOMPILING) + find_program(BIN2CPP_EXECUTABLE + NAMES Bin2CPP + PATHS ENV PATH + NO_DEFAULT_PATH + ) + else() + find_program(BIN2CPP_EXECUTABLE + NAMES Bin2CPP + PATHS "${CMAKE_CURRENT_LIST_DIR}" + NO_DEFAULT_PATH + ) + endif() + + if(BIN2CPP_EXECUTABLE) + get_filename_component(BIN2CPP_EXECUTABLE "${BIN2CPP_EXECUTABLE}" ABSOLUTE) + add_executable(Bin2CPP IMPORTED) + set_property(TARGET Bin2CPP PROPERTY IMPORTED_LOCATION ${BIN2CPP_EXECUTABLE}) + else() + message(WARNING "Bin2CPP executable not found in ${CMAKE_CURRENT_LIST_DIR}") + endif() +endif() diff --git a/CMake/CustomTargets.cmake b/CMake/CustomTargets.cmake new file mode 100644 index 0000000..2f6a29c --- /dev/null +++ b/CMake/CustomTargets.cmake @@ -0,0 +1,32 @@ +foreach(CONFIG DEBUG RELWITHDEBINFO) + if("${CMAKE_EXE_LINKER_FLAGS_${CONFIG}}" MATCHES "/INCREMENTAL:NO") + string(REGEX REPLACE "/INCREMENTAL([^:]|$)" "" + CMAKE_EXE_LINKER_FLAGS_${CONFIG} + "${CMAKE_EXE_LINKER_FLAGS_${CONFIG}}") + endif() + if("${CMAKE_SHARED_LINKER_FLAGS_${CONFIG}}" MATCHES "/INCREMENTAL:NO") + string(REGEX REPLACE "/INCREMENTAL([^:]|$)" "" + CMAKE_SHARED_LINKER_FLAGS_${CONFIG} + "${CMAKE_SHARED_LINKER_FLAGS_${CONFIG}}") + endif() +endforeach() + +add_library(Bin2CPPCompileAndLinkFlags INTERFACE) + +target_compile_options(Bin2CPPCompileAndLinkFlags INTERFACE + $<$:/W4 /WX> + $<$:-Wall -Wextra -Wpedantic -Werror> + $<$,$>:-fprofile-instr-generate -fcoverage-mapping> +) + +target_link_options(Bin2CPPCompileAndLinkFlags INTERFACE + $<$,$>:-fprofile-instr-generate> +) + +target_compile_definitions(Bin2CPPCompileAndLinkFlags INTERFACE + $<$:BIN2CPP_OPTIMIZED> + $<$:BIN2CPP_NOT_OPTIMIZED> + $<$:BIN2CPP_WINDOWS> + $<$:BIN2CPP_LINUX> + $<$:NOMINMAX> + $<$:WIN32_LEAN_AND_MEAN>) \ No newline at end of file diff --git a/CMake/FindDependencies.cmake b/CMake/FindDependencies.cmake index 3c42c1c..d4c47b6 100644 --- a/CMake/FindDependencies.cmake +++ b/CMake/FindDependencies.cmake @@ -5,18 +5,18 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") find_package(Threads REQUIRED) endif() -find_package(EASTL REQUIRED) -find_package(mimalloc REQUIRED) +find_package(magic_enum REQUIRED) find_package(CLI11 REQUIRED) -find_package(rapidhash REQUIRED) find_package(quill REQUIRED) -if(${IS_MULTI_CONFIG}) - find_package(cpptrace REQUIRED) -elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug" OR ${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") - find_package(cpptrace REQUIRED) +if(${ASAN}) + find_package(mimalloc-asan REQUIRED) +else() + find_package(mimalloc REQUIRED) endif() +find_package(cpptrace REQUIRED) + if(BUILD_TESTS) find_package(GTest REQUIRED) endif() \ No newline at end of file diff --git a/CMake/Utils.cmake b/CMake/Utils.cmake deleted file mode 100644 index 915a12f..0000000 --- a/CMake/Utils.cmake +++ /dev/null @@ -1,58 +0,0 @@ -function(bin2cpp_setup_dependencies ParentFolder) - set(CONAN_DEPLOYER_DIR "${CMAKE_SOURCE_DIR}/build/full_deploy/host") - - if(EXISTS ${CONAN_DEPLOYER_DIR}) - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - file(GLOB_RECURSE SHARED_BINARIES ${CONAN_DEPLOYER_DIR}/*mimalloc*.dll) - elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - file(GLOB_RECURSE SHARED_BINARIES ${CONAN_DEPLOYER_DIR}/*mimalloc*.so*) - endif() - - if(${IS_MULTI_CONFIG}) - foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES}) - foreach(file ${SHARED_BINARIES}) - if(file MATCHES "/${CONFIG}/") - list(APPEND SHARED_BINARIES_${CONFIG} ${file}) - endif() - endforeach() - endforeach() - - add_custom_target(${PROJECT_NAME}CopySharedBinaries - ALL DEPENDS SHARED_BINARIES - COMMAND ${CMAKE_COMMAND} -E make_directory $ - COMMAND ${CMAKE_COMMAND} -E $,copy_if_different,true> ${SHARED_BINARIES_Debug} $ - COMMAND ${CMAKE_COMMAND} -E $,copy_if_different,true> ${SHARED_BINARIES_Release} $ - COMMAND ${CMAKE_COMMAND} -E $,copy_if_different,true> ${SHARED_BINARIES_RelWithDebInfo} $ - COMMENT "Copy shared binaries for ${PROJECT_NAME}" - ) - add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}CopySharedBinaries) - set_target_properties(${PROJECT_NAME}CopySharedBinaries PROPERTIES FOLDER UtilityTargets/${ParentFolder}) - - else() - foreach(file ${SHARED_BINARIES}) - if(file MATCHES "/${CMAKE_BUILD_TYPE}/") - list(APPEND SHARED_BINARIES_${CMAKE_BUILD_TYPE} ${file}) - endif() - endforeach() - - add_custom_target(${PROJECT_NAME}CopySharedBinaries ALL - DEPENDS ${SHARED_BINARIES_${CMAKE_BUILD_TYPE}} - COMMAND ${CMAKE_COMMAND} -E make_directory $ - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SHARED_BINARIES_${CMAKE_BUILD_TYPE}} $ - COMMENT "Copy shared binaries for ${PROJECT_NAME}" - ) - add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}CopySharedBinaries) - set_target_properties(${PROJECT_NAME}CopySharedBinaries PROPERTIES FOLDER UtilityTargets/${ParentFolder}) - endif() - endif() - - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - add_custom_target(${PROJECT_NAME}PatchMinject ALL - COMMAND ${MINJECT_EXECUTABLE} -i -f $ - COMMENT "Patching ${PROJECT_NAME} to ensure mimalloc dynamic override" - ) - add_dependencies(${PROJECT_NAME}PatchMinject ${PROJECT_NAME}) - set_target_properties(${PROJECT_NAME}PatchMinject PROPERTIES FOLDER "UtilityTargets/${ParentFolder}") - endif() - -endfunction() \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b1e9505..0fd5e87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,31 +1,25 @@ -cmake_minimum_required(VERSION 3.24) +cmake_minimum_required(VERSION 3.26) project(Bin2CPP VERSION 0.1.0 DESCRIPTION "Bin2CPP" LANGUAGES CXX) -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED True) - set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + +include(${CMAKE_SOURCE_DIR}/CMake/CustomTargets.cmake) +include(${CMAKE_SOURCE_DIR}/CMake/FindDependencies.cmake) + set(CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug" CACHE STRING "" FORCE) option(BUILD_TESTS OFF) - -include(${CMAKE_SOURCE_DIR}/CMake/FindDependencies.cmake) -include(${CMAKE_SOURCE_DIR}/CMake/Utils.cmake) - -find_program(MINJECT_EXECUTABLE NAMES minject) +option(ASAN OFF) +option(COVERAGE OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_OPTIMIZE_DEPENDENCIES 1) -add_compile_definitions( - $<$:NOMINMAX> - $<$:WIN32_LEAN_AND_MEAN>) - if(BUILD_TESTS) enable_testing() endif() @@ -39,7 +33,4 @@ SET(CMAKE_INSTALL_RPATH "\${ORIGIN}") add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPP/Sources) if(${BUILD_TESTS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Bin2CPP/Tests) -endif() - -add_custom_target(NatVis SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/Vendor/NatVis/EASTL/EASTL.natvis) \ No newline at end of file +endif() \ No newline at end of file diff --git a/ConanProfiles/clang b/ConanProfiles/clang new file mode 100644 index 0000000..86ec4bf --- /dev/null +++ b/ConanProfiles/clang @@ -0,0 +1,32 @@ +[settings] +os=Linux +arch=x86_64 +compiler=clang +compiler.version=20 +compiler.libcxx=libstdc++11 +compiler.cppstd=20 +compiler.cstd=17 +compiler.runtime=static +build_type=Release + +[conf] +tools.cmake.cmaketoolchain:extra_variables={'CMAKE_CXX_COMPILER_LAUNCHER': 'ccache', 'CMAKE_C_COMPILER_LAUNCHER': 'ccache'} + +tools.system.package_manager:mode=install +tools.system.package_manager:sudo=True + +tools.build:exelinkflags=["-fuse-ld=mold", "-flto"] +tools.build:sharedlinkflags=["-fuse-ld=mold", "-flto"] + +tools.build:cflags=["-flto"] +tools.build:cxxflags=["-flto"] + +tools.build:compiler_executables={"c": "clang", "cpp": "clang++"} + +tools.cmake.cmaketoolchain:generator=Ninja + +[tool_requires] +!cmake/*: cmake/[>=4.2] + +[options] +Bin2CPP/*:build_tests=True \ No newline at end of file diff --git a/ConanProfiles/clang_coverage b/ConanProfiles/clang_coverage new file mode 100644 index 0000000..f536fd9 --- /dev/null +++ b/ConanProfiles/clang_coverage @@ -0,0 +1,30 @@ +[settings] +os=Linux +arch=x86_64 +compiler=clang +compiler.version=20 +compiler.libcxx=libstdc++11 +compiler.cppstd=20 +compiler.cstd=17 +compiler.runtime=static +build_type=Debug + +[conf] +tools.cmake.cmaketoolchain:extra_variables={'CMAKE_CXX_COMPILER_LAUNCHER': 'ccache', 'CMAKE_C_COMPILER_LAUNCHER': 'ccache'} + +tools.system.package_manager:mode=install +tools.system.package_manager:sudo=True + +tools.build:exelinkflags=["-fuse-ld=mold"] +tools.build:sharedlinkflags=["-fuse-ld=mold"] + +tools.cmake.cmaketoolchain:generator=Ninja + +tools.build:compiler_executables={"c": "clang", "cpp": "clang++"} + +[tool_requires] +!cmake/*: cmake/[>=4.2] + +[options] +Bin2CPP/*:build_tests=True +Bin2CPP/*:coverage=True diff --git a/ConanProfiles/clangd b/ConanProfiles/clangd new file mode 100644 index 0000000..0fa3339 --- /dev/null +++ b/ConanProfiles/clangd @@ -0,0 +1,29 @@ +[settings] +os=Linux +arch=x86_64 +compiler=clang +compiler.version=20 +compiler.libcxx=libstdc++11 +compiler.cppstd=20 +compiler.cstd=17 +compiler.runtime=static +build_type=Debug + +[conf] +tools.cmake.cmaketoolchain:extra_variables={'CMAKE_CXX_COMPILER_LAUNCHER': 'ccache', 'CMAKE_C_COMPILER_LAUNCHER': 'ccache'} + +tools.system.package_manager:mode=install +tools.system.package_manager:sudo=True + +tools.build:exelinkflags=["-fuse-ld=mold"] +tools.build:sharedlinkflags=["-fuse-ld=mold"] + +tools.cmake.cmaketoolchain:generator=Ninja + +tools.build:compiler_executables={"c": "clang", "cpp": "clang++"} + +[tool_requires] +!cmake/*: cmake/[>=4.2] + +[options] +Bin2CPP/*:build_tests=True \ No newline at end of file diff --git a/ConanProfiles/clangd_asan b/ConanProfiles/clangd_asan new file mode 100644 index 0000000..9a8fc1e --- /dev/null +++ b/ConanProfiles/clangd_asan @@ -0,0 +1,33 @@ +[settings] +os=Linux +arch=x86_64 +compiler=clang +compiler.version=20 +compiler.libcxx=libstdc++11 +compiler.cppstd=20 +compiler.cstd=17 +compiler.runtime=static +build_type=Debug + +[conf] +tools.cmake.cmaketoolchain:extra_variables={'CMAKE_CXX_COMPILER_LAUNCHER': 'ccache', 'CMAKE_C_COMPILER_LAUNCHER': 'ccache'} + +tools.system.package_manager:mode=install +tools.system.package_manager:sudo=True + +tools.build:exelinkflags=["-fuse-ld=mold", "-fsanitize=address,undefined,leak"] +tools.build:sharedlinkflags=["-fuse-ld=mold", "-fsanitize=address,undefined,leak"] + +tools.build:cflags=["-fsanitize=address,undefined,leak", "-fno-sanitize-recover=all"] +tools.build:cxxflags=["-fsanitize=address,undefined,leak", "-fno-sanitize-recover=all"] + +tools.cmake.cmaketoolchain:generator=Ninja + +tools.build:compiler_executables={"c": "clang", "cpp": "clang++"} + +[tool_requires] +!cmake/*: cmake/[>=4.2] + +[options] +Bin2CPP/*:asan=True +Bin2CPP/*:build_tests=True \ No newline at end of file diff --git a/ConanProfiles/msvc b/ConanProfiles/msvc new file mode 100644 index 0000000..0aafee5 --- /dev/null +++ b/ConanProfiles/msvc @@ -0,0 +1,24 @@ +[settings] +os=Windows +arch=x86_64 +compiler=msvc +compiler.version=195 +compiler.cppstd=20 +compiler.cstd=17 +compiler.runtime=static +build_type=Release + +[conf] +tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/msvc_ccache.cmake + +tools.build:exelinkflags=["/LTCG", "/INCREMENTAL:NO"] +tools.build:sharedlinkflags=["/LTCG", "/INCREMENTAL:NO"] + +tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1", "/GL"] +tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"] + +[tool_requires] +!cmake/*: cmake/[>=4.2] + +[options] +Bin2CPP/*:build_tests=True \ No newline at end of file diff --git a/ConanProfiles/msvc_ccache.cmake b/ConanProfiles/msvc_ccache.cmake new file mode 100644 index 0000000..2818eec --- /dev/null +++ b/ConanProfiles/msvc_ccache.cmake @@ -0,0 +1,19 @@ +# https://github.com/ccache/ccache/wiki/MS-Visual-Studio#usage-with-cmake + +find_program(ccache_exe ccache) +if(ccache_exe) + file(COPY_FILE + ${ccache_exe} ${CMAKE_BINARY_DIR}/cl.exe + ONLY_IF_DIFFERENT) + + # By default Visual Studio generators will use /Zi which is not compatible + # with ccache, so tell Visual Studio to use /Z7 instead. + message(STATUS "Setting MSVC debug information format to 'Embedded'") + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$:Embedded>") + + set(CMAKE_VS_GLOBALS + "CLToolExe=cl.exe" + "CLToolPath=${CMAKE_BINARY_DIR}" + "UseMultiToolTask=true" + ) +endif() \ No newline at end of file diff --git a/ConanProfiles/msvcd b/ConanProfiles/msvcd new file mode 100644 index 0000000..9bdcd07 --- /dev/null +++ b/ConanProfiles/msvcd @@ -0,0 +1,20 @@ +[settings] +os=Windows +arch=x86_64 +compiler=msvc +compiler.version=195 +compiler.cppstd=20 +compiler.cstd=17 +compiler.runtime=static +build_type=Debug + +[conf] +tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/msvc_ccache.cmake + +tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1"] +tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"] +[tool_requires] +!cmake/*: cmake/[>=4.2] + +[options] +Bin2CPP/*:build_tests=True diff --git a/ConanProfiles/msvcd_asan b/ConanProfiles/msvcd_asan new file mode 100644 index 0000000..d9bb8af --- /dev/null +++ b/ConanProfiles/msvcd_asan @@ -0,0 +1,25 @@ +[settings] +os=Windows +arch=x86_64 +compiler=msvc +compiler.version=195 +compiler.cppstd=20 +compiler.cstd=17 +compiler.runtime=static +build_type=Debug + +[conf] +tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/msvc_ccache.cmake + +tools.build:exelinkflags=["/INCREMENTAL:NO"] +tools.build:sharedlinkflags=["/INCREMENTAL:NO"] + +tools.build:cflags=["/Zc:preprocessor", "/Zc:__STDC__", "/D_CRT_DECLARE_NONSTDC_NAMES=1"] +tools.build:cxxflags=["/Zc:preprocessor", "/permissive-", "/Zc:__cplusplus", "/Zc:enumTypes", "/Zc:templateScope", "/Zc:throwingNew"] + +[tool_requires] +!cmake/*: cmake/[>=4.2] + +[options] +Bin2CPP/*:asan=True +Bin2CPP/*:build_tests=True diff --git a/Vendor/NatVis/EASTL/EASTL.natvis b/Vendor/NatVis/EASTL/EASTL.natvis deleted file mode 100644 index e1ec96d..0000000 --- a/Vendor/NatVis/EASTL/EASTL.natvis +++ /dev/null @@ -1,761 +0,0 @@ - - - - - - - - ({(void*)mPair.mFirst} = {*mPair.mFirst}) - ({nullptr}) - - (void*)mPair.mFirst - *mPair.mFirst - - - - - ({(void*)mpValue} = {*mpValue}) - ({nullptr}) - - (void*)mpValue - *mpValue - mpRefCount->mRefCount - mpRefCount->mWeakRefCount - - - - - {((mpRefCount && mpRefCount->mRefCount) ? mpValue : nullptr)} - - mpRefCount && mpRefCount->mRefCount ? mpValue : nullptr - - - - - [{$T2}] {{}} - [{$T2}] {{ {*mValue} }} - [{$T2}] {{ {*mValue}, {*(mValue+1)} }} - [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)} }} - [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)} }} - [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)} }} - [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)}, {*(mValue+5)} }} - [{$T2}] {{ {*mValue}, {*(mValue+1)}, {*(mValue+2)}, {*(mValue+3)}, {*(mValue+4)}, {*(mValue+5)}, ... }} - - $T2 - - $T2 - mValue - - - - - - "{mPair.mFirst.heap.mpBegin,sb}" - "{mPair.mFirst.sso.mData,sb}" - - mPair.mFirst.heap.mnSize - (mPair.mFirst.heap.mnCapacity & ~kHeapMask) - mPair.mFirst.heap.mpBegin,sb - - (SSOLayout::SSO_CAPACITY - mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize) - SSOLayout::SSO_CAPACITY - mPair.mFirst.sso.mData,sb - - !!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask) - - - - - - {mPair.mFirst.heap.mpBegin,su} - {mPair.mFirst.sso.mData,su} - - mPair.mFirst.heap.mnSize - (mPair.mFirst.heap.mnCapacity & ~kHeapMask) - mPair.mFirst.heap.mpBegin,su - - (SSOLayout::SSO_CAPACITY - mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize) - SSOLayout::SSO_CAPACITY - mPair.mFirst.sso.mData,su - - !!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask) - - - - - ({first}, {second}) - - first - second - - - - - [{mnSize}] {{}} - [{mnSize}] {{ {*mpData} }} - [{mnSize}] {{ {*mpData}, {*(mpData+1)} }} - [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)} }} - [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)} }} - [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)} }} - [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)}, {*(mpData+5)} }} - [{mnSize}] {{ {*mpData}, {*(mpData+1)}, {*(mpData+2)}, {*(mpData+3)}, {*(mpData+4)}, {*(mpData+5)}, ... }} - - mnSize - - mnSize - mpData - - - - - - [{mpEnd - mpBegin}] {{}} - [{mpEnd - mpBegin}] {{ {*mpBegin} }} - [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)} }} - [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)} }} - [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)} }} - [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)} }} - [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)}, {*(mpBegin+5)} }} - [{mpEnd - mpBegin}] {{ {*mpBegin}, {*(mpBegin+1)}, {*(mpBegin+2)}, {*(mpBegin+3)}, {*(mpBegin+4)}, {*(mpBegin+5)}, ... }} - - mpEnd - mpBegin - mCapacityAllocator.mFirst - mpBegin - - mpEnd - mpBegin - mpBegin - - - - - - - [0] {{}} - - - [1] {{ {*mItBegin.mpCurrent} }} - - - [{(mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin)}] - {{ - {*mItBegin.mpCurrent}, - ... - }} - - - (mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin) - - (mItEnd.mpCurrentArrayPtr - mItBegin.mpCurrentArrayPtr) * $T3 + (mItEnd.mpCurrent-mItEnd.mpBegin) - (mItBegin.mpCurrent-mItBegin.mpBegin) - mItBegin.mpCurrentArrayPtr[(mItBegin.mpCurrent-mItBegin.mpBegin + $i) / $T3][(mItBegin.mpCurrent-mItBegin.mpBegin + $i) % $T3] - - - - - - {*mpCurrent} - - *mpCurrent - *(*(mpCurrentArrayPtr-1) + (mpEnd-mpBegin) - 1) - *(mpCurrent-1) - **(mpCurrentArrayPtr+1) - *(mpCurrent+1) - mpCurrent == mpBegin - mpCurrent+1 == mpEnd - - - - - - - {c} - - c - - - - - - [0] {{}} - - - [1] {{ {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue} }} - - - [2] - {{ - {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue}, - {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext->mpNext)->mValue} - }} - - - [?] - {{ - {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext)->mValue}, - {((eastl::ListNode<$T1>*)mNodeAllocator.mFirst.mpNext->mpNext)->mValue}, - ... - }} - - - - Content of lists will repeat indefinitely. Keep that in mind! - - - mNodeAllocator.mFirst.mpNext - mpNext - ((eastl::ListNode<$T1>*)this)->mValue - - - - - - {mValue} - - mValue - *(eastl::ListNode<$T1>*)mpNext - *(eastl::ListNode<$T1>*)mpPrev - - Content of lists will repeat indefinitely. Keep that in mind! - - - The rest of the list follows: - - - (eastl::ListNode<$T1>*)mpNext->mpNext - (eastl::ListNode<$T1>*)mpNext - mValue - - - - - - {*mpNode} - - *(eastl::ListNode<$T1>*)mpNode - - - - - - [0] {{}} - - - [1] - {{ - {((eastl::SListNode<$T1>*)mNode.mpNext)->mValue} - }} - - - [2] - {{ - {((eastl::SListNode<$T1>*)mNode.mpNext)->mValue}, - {((eastl::SListNode<$T1>*)mNode.mpNext->mpNext)->mValue} - }} - - - [?] - {{ - {((eastl::SListNode<$T1>*)mNode.mpNext)->mValue}, - {((eastl::SListNode<$T1>*)mNode.mpNext->mpNext)->mValue}, - ... - }} - - - - mNode.mpNext - mpNext - ((eastl::SListNode<$T1>*)this)->mValue - - - - - - {mValue} - - mValue - *(eastl::SListNode<$T1>*)mpNext - - The rest of the list follows: - - - mpNext == nullptr ? nullptr : (eastl::SListNode<$T1>*)mpNext->mpNext - (eastl::SListNode<$T1>*)mpNext - mValue - - - - - - {*mpNode} - - *(eastl::SListNode<$T1>*)mpNode - - - - - [0] {{}} - [1] {{ {mAnchor.mpNext} }} - [?] {{ {mAnchor.mpNext}, ... }} - - - Content of intrusive lists will repeat indefinitely. Keep that in mind! - - - mAnchor.mpNext - mpNext - *this - - - - - - {*($T1*)mpNode} - - *($T1*)mpNode - - - - - - - [0] {{}} - - - [1] - {{ - {((eastl::rbtree_node<$T1>*)mAnchor.mpNodeLeft)->mValue} - }} - - - [{mnSize}] - {{ - {((eastl::rbtree_node<$T1>*)mAnchor.mpNodeLeft)->mValue}, - ... - }} - - - mnSize - - mnSize - mAnchor.mpNodeParent - mpNodeLeft - mpNodeRight - ((eastl::rbtree_node<$T1>*)this)->mValue - - - - - - - [0] {{}} - - - [1] - {{ - {((eastl::rbtree_node<$T2>*)mAnchor.mpNodeLeft)->mValue} - }} - - - [{mnSize}] - {{ - {((eastl::rbtree_node<$T2>*)mAnchor.mpNodeLeft)->mValue}, - ... - }} - - - mnSize - - mnSize - mAnchor.mpNodeParent - mpNodeLeft - mpNodeRight - ((eastl::rbtree_node<$T2>*)this)->mValue - - - - - - {mValue} - - mValue - - It is possible to expand parents that do not exist. - - *(eastl::rbtree_node<$T1>*)mpNodeParent - *(eastl::rbtree_node<$T1>*)mpNodeLeft - *(eastl::rbtree_node<$T1>*)mpNodeRight - - - - - {*(eastl::rbtree_node<$T1>*)mpNode} - - *(eastl::rbtree_node<$T1>*)mpNode - - - - - - [{mnElementCount}] {{}} - [{mnElementCount}] {{ ... }} - - - mnBucketCount - mpBucketArray - - - - - - entry->mValue - - entry = entry->mpNext - - - bucketIndex++ - - entry = mpBucketArray[bucketIndex] - - - - - - - - - [{mnElementCount}] {{}} - [{mnElementCount}] {{ ... }} - - - - - - entry->mValue.second - - entry = entry->mpNext - - - bucketIndex++ - - entry = mpBucketArray[bucketIndex] - - - - - - - - {mValue}, {*mpNext} - {mValue} - - - - this - mpNext - mValue - - - - - - {mpNode->mValue} - - mpNode->mValue - - - - - {*(mIterator-1)} - - mIterator-1 - - - - - {{count = {kSize}}} - - kSize - - - - - - kSize - - - bBitValue = ((mWord[iWord] >> iBitInWord) % 2) != 0 ? true : false - bBitValue - iBitInWord++ - - iWord++ - iBitInWord = 0 - - - - - - - - {c} - - c - - - - - {mpBegin,[mnCount]} - mpBegin,[mnCount] - - - - ({mFirst}, {mSecond}) - ({mSecond}) - ({mFirst}) - (empty) - (empty) - ({mFirst}, {mSecond}) - - - - - nullopt - {value()} - - value() - - - - - {$T1} to {$T2}} - - - - - {mRep} nanoseconds - - - - {mRep} microseconds - - - - {mRep} milliseconds - - - - {mRep} seconds - - - - {mRep} minutes - - - - {mRep} hours - - - - {mRep} duration with ratio = [{$T2} : {$T3}] - - - - - - empty - {mInvokeFuncPtr} - - - - - {*val} - - - - - empty - {m_storage.external_storage} - - - - - {mAtomic} - - mAtomic - - - - - {mFlag.mAtomic} - - - - - [valueless_by_exception] - {{ index=0, value={($T1*)mStorage.mBuffer.mCharData}} - {{ index=1, value={($T2*)mStorage.mBuffer.mCharData}} - {{ index=2, value={($T3*)mStorage.mBuffer.mCharData}} - {{ index=3, value={($T4*)mStorage.mBuffer.mCharData}} - {{ index=4, value={($T5*)mStorage.mBuffer.mCharData}} - {{ index=5, value={($T6*)mStorage.mBuffer.mCharData}} - {{ index=6, value={($T7*)mStorage.mBuffer.mCharData}} - {{ index=7, value={($T8*)mStorage.mBuffer.mCharData}} - {{ index=8, value={($T9*)mStorage.mBuffer.mCharData}} - {{ index=9, value={($T10*)mStorage.mBuffer.mCharData}} - {{ index=10, value={($T11*)mStorage.mBuffer.mCharData}} - {{ index=11, value={($T12*)mStorage.mBuffer.mCharData}} - {{ index=12, value={($T13*)mStorage.mBuffer.mCharData}} - {{ index=13, value={($T14*)mStorage.mBuffer.mCharData}} - {{ index=14, value={($T15*)mStorage.mBuffer.mCharData}} - {{ index=15, value={($T16*)mStorage.mBuffer.mCharData}} - {{ index=16, value={($T17*)mStorage.mBuffer.mCharData}} - {{ index=17, value={($T18*)mStorage.mBuffer.mCharData}} - {{ index=18, value={($T19*)mStorage.mBuffer.mCharData}} - {{ index=19, value={($T20*)mStorage.mBuffer.mCharData}} - {{ index=20, value={($T21*)mStorage.mBuffer.mCharData}} - {{ index=21, value={($T22*)mStorage.mBuffer.mCharData}} - {{ index=22, value={($T23*)mStorage.mBuffer.mCharData}} - {{ index=23, value={($T24*)mStorage.mBuffer.mCharData}} - {{ index=24, value={($T25*)mStorage.mBuffer.mCharData}} - {{ index=25, value={($T26*)mStorage.mBuffer.mCharData}} - {{ index=26, value={($T27*)mStorage.mBuffer.mCharData}} - {{ index=27, value={($T28*)mStorage.mBuffer.mCharData}} - {{ index=28, value={($T29*)mStorage.mBuffer.mCharData}} - {{ index=29, value={($T30*)mStorage.mBuffer.mCharData}} - {{ index=30, value={($T31*)mStorage.mBuffer.mCharData}} - - index() - ($T1*)mStorage.mBuffer.mCharData - ($T2*)mStorage.mBuffer.mCharData - ($T3*)mStorage.mBuffer.mCharData - ($T4*)mStorage.mBuffer.mCharData - ($T5*)mStorage.mBuffer.mCharData - ($T6*)mStorage.mBuffer.mCharData - ($T7*)mStorage.mBuffer.mCharData - ($T8*)mStorage.mBuffer.mCharData - ($T9*)mStorage.mBuffer.mCharData - ($T10*)mStorage.mBuffer.mCharData - ($T11*)mStorage.mBuffer.mCharData - ($T12*)mStorage.mBuffer.mCharData - ($T13*)mStorage.mBuffer.mCharData - ($T14*)mStorage.mBuffer.mCharData - ($T15*)mStorage.mBuffer.mCharData - ($T16*)mStorage.mBuffer.mCharData - ($T17*)mStorage.mBuffer.mCharData - ($T18*)mStorage.mBuffer.mCharData - ($T19*)mStorage.mBuffer.mCharData - ($T20*)mStorage.mBuffer.mCharData - ($T21*)mStorage.mBuffer.mCharData - ($T22*)mStorage.mBuffer.mCharData - ($T23*)mStorage.mBuffer.mCharData - ($T24*)mStorage.mBuffer.mCharData - ($T25*)mStorage.mBuffer.mCharData - ($T26*)mStorage.mBuffer.mCharData - ($T27*)mStorage.mBuffer.mCharData - ($T28*)mStorage.mBuffer.mCharData - ($T29*)mStorage.mBuffer.mCharData - ($T30*)mStorage.mBuffer.mCharData - ($T31*)mStorage.mBuffer.mCharData - - - - - - - ({*this,view(noparens)}) - - - - - {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue} - ({*this,view(noparens)}) - - (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue - - - - - {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue} - ({*this,view(noparens)}) - - (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue - - - - - {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue} - ({*this,view(noparens)}) - - (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue - - - - - {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue} - ({*this,view(noparens)}) - - (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue - - - - - {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue} - ({*this,view(noparens)}) - - (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue - - - - - {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue} - ({*this,view(noparens)}) - - (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue - - - - - {(*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue}, {(*((eastl::Internal::TupleLeaf<6,$T7,0>*)&mImpl)).mValue} - ({*this,view(noparens)}) - - (*((eastl::Internal::TupleLeaf<0,$T1,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<1,$T2,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<2,$T3,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<3,$T4,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<4,$T5,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<5,$T6,0>*)&mImpl)).mValue - (*((eastl::Internal::TupleLeaf<6,$T7,0>*)&mImpl)).mValue - - - - - diff --git a/conanfile.py b/conanfile.py index 21e306c..84bc3a1 100644 --- a/conanfile.py +++ b/conanfile.py @@ -5,13 +5,14 @@ import os required_conan_version = ">=1.33.0" -class Bigfoot(ConanFile): +class Bin2CPP(ConanFile): name = "bin2cpp" homepage = "https://git.romainboullard.com/rboullard/Bin2CPP" description = "A utility that converts files to CPP headers" topics = ("utility") license = "MIT" - version = "0.1.0" + version = "1.0.0" + package_type = "application" # Binary configuration settings = "os", "compiler", "build_type", "arch" @@ -19,15 +20,24 @@ class Bigfoot(ConanFile): "shared": [True, False], "fPIC": [True, False], "build_tests": [True, False], + "asan": [True, False], + "coverage": [True, False] } default_options = { "shared": False, "fPIC": True, "build_tests": False, + "asan": False, + "coverage": False } generators = "CMakeDeps" + def export_sources(self): + copy(self, "CMakeLists.txt", self.recipe_folder, self.export_sources_folder) + copy(self, os.path.join("Bin2CPP", "*"), self.recipe_folder, self.export_sources_folder) + copy(self, os.path.join("CMake", "*"), self.recipe_folder, self.export_sources_folder) + def layout(self): cmake_layout(self) @@ -35,32 +45,46 @@ class Bigfoot(ConanFile): if self.settings.os == "Windows": del self.options.fPIC - self.options['mimalloc'].override = True - self.options['mimalloc'].shared = True - if(self.settings.os == "Windows"): - self.options["mimalloc"].win_redirect = True + if(self.options.asan): + self.options["mimalloc"].asan = True def requirements(self): self.requires("quill/11.0.2", transitive_headers=True) - self.requires("eastl/3.27.01@bigfootdev/main", transitive_headers=True) + self.requires("magic_enum/0.9.7", transitive_headers=True) self.requires("mimalloc/3.2.8@bigfootdev/main", transitive_headers=True) self.requires("cli11/2.6.1@bigfootdev/main") - self.requires("rapidhash/3.0@bigfootdev/main", transitive_headers=True) - if(self.settings.build_type == "RelWithDebInfo" or self.settings.build_type == "Debug"): - self.requires("cpptrace/1.0.4", transitive_headers=True) + self.requires("cpptrace/1.0.4", transitive_headers=True) if(self.options.build_tests): self.test_requires("gtest/1.17.0") def generate(self): tc = CMakeToolchain(self) - + tc.variables["BUILD_TESTS"] = self.options.build_tests + tc.variables["ASAN"] = self.options.asan + tc.variables["COVERAGE"] = self.options.coverage tc.generate() def build(self): cmake = CMake(self) cmake.configure() - cmake.build() \ No newline at end of file + cmake.build() + + def package(self): + copy(self, pattern="LICENSE", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder) + cmake = CMake(self) + cmake.install() + + copy(self, "Bin2CPPTargets.cmake", + src=os.path.join(self.source_folder, "CMake"), + dst=os.path.join(self.package_folder, "bin")) + + @property + def _module_path(self): + return os.path.join("bin", "Bin2CPPTargets.cmake") + + def package_info(self): + self.cpp_info.set_property("cmake_build_modules", [self._module_path]) \ No newline at end of file diff --git a/format.sh b/format.sh old mode 100644 new mode 100755 diff --git a/generate_bin2cpp.sh b/generate_bin2cpp.sh old mode 100644 new mode 100755 diff --git a/generate_dependencies.bat b/generate_dependencies.bat index 9ef984c..a585f44 100644 --- a/generate_dependencies.bat +++ b/generate_dependencies.bat @@ -22,12 +22,9 @@ if "%~1"=="force" ( REM Add the remote conan remote add bigfootpackages https://conan.romainboullard.com/artifactory/api/conan/BigfootPackages -REM Install the conan configuration -conan config install https://git.romainboullard.com/BigfootDev/ConanProfiles.git - REM Install dependencies with the specified build option -conan install . --deployer=full_deploy --remote=bigfootpackages %build_option% -of build -s build_type=Release -o bin2cpp/*:build_tests=True -conan install . --deployer=full_deploy --remote=bigfootpackages %build_option% -of build -s build_type=RelWithDebInfo -o bin2cpp/*:build_tests=True -conan install . --deployer=full_deploy --remote=bigfootpackages %build_option% -of build -s build_type=Debug -o bin2cpp/*:build_tests=True +conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/msvc -pr:b=./ConanProfiles/msvc %build_option% -of build -s build_type=Release +conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/msvcd -pr:b=./ConanProfiles/msvcd %build_option% -of build -s build_type=RelWithDebInfo +conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/msvcd -pr:b=./ConanProfiles/msvcd %build_option% -of build -s build_type=Debug endlocal diff --git a/generate_dependencies.sh b/generate_dependencies.sh old mode 100644 new mode 100755 index aed8021..e4d8952 --- a/generate_dependencies.sh +++ b/generate_dependencies.sh @@ -9,18 +9,16 @@ fi # Add the remote conan remote add bigfootpackages https://conan.romainboullard.com/artifactory/api/conan/BigfootPackages -# Install the conan configuration -conan config install https://git.romainboullard.com/BigfootDev/ConanProfiles.git - # Set the build option based on the argument if [ "$1" == "force" ]; then - conan install . --deployer=full_deploy --remote=bigfootpackages --build='*' -of build -s build_type=Release -o bin2cpp/*:build_tests=True - conan install . --deployer=full_deploy --remote=bigfootpackages --build='*' -of build -s build_type=RelWithDebInfo -o bin2cpp/*:build_tests=True - conan install . --deployer=full_deploy --remote=bigfootpackages --build='*' -of build -s build_type=Debug -o bin2cpp/*:build_tests=True + conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/clang -pr:b=./ConanProfiles/clang --build='*' -of build -s build_type=Release + conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/clangd -pr:b=./ConanProfiles/clangd --build='*' -of build -s build_type=RelWithDebInfo + conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/clangd -pr:b=./ConanProfiles/clangd --build='*' -of build -s build_type=Debug elif [ "$1" == "missing" ]; then - conan install . --deployer=full_deploy --remote=bigfootpackages --build=missing -of build -s build_type=Release -o bin2cpp/*:build_tests=True - conan install . --deployer=full_deploy --remote=bigfootpackages --build=missing -of build -s build_type=RelWithDebInfo -o bin2cpp/*:build_tests=True - conan install . --deployer=full_deploy --remote=bigfootpackages --build=missing -of build -s build_type=Debug -o bin2cpp/*:build_tests=True + conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/clang -pr:b=./ConanProfiles/clang --build=missing -of build -s build_type=Release + conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/clangd -pr:b=./ConanProfiles/clangd --build=missing -of build -s build_type=RelWithDebInfo + conan install . --remote=bigfootpackages -pr:h=./ConanProfiles/clangd -pr:b=./ConanProfiles/clangd --build=missing -of build -s build_type=Debug +else echo "Invalid argument: $1" echo "Usage: $0 [force|missing]" exit 1 diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt new file mode 100644 index 0000000..20ef5be --- /dev/null +++ b/test_package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package LANGUAGES C) + +find_package(Bin2CPP REQUIRED CONFIG) + +find_program(BIN2CPP_EXECUTABLE NAMES Bin2CPP) +execute_process(COMMAND ${BIN2CPP_EXECUTABLE} -h) diff --git a/test_package/conanfile.py b/test_package/conanfile.py new file mode 100644 index 0000000..c1dcff9 --- /dev/null +++ b/test_package/conanfile.py @@ -0,0 +1,18 @@ +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import CMake, cmake_layout +import os + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires(self.tested_reference_str) + + def test(self): + self.run("Bin2CPP --help", env="conanrun")