From 7cdf36f317f3490c9f184ecc26ce581c885d628b Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Sun, 2 May 2021 23:53:12 +0200 Subject: [PATCH] Initial support for conditional arguments --- CMakeLists.txt | 18 ++- README.md | 1 - src/cmkrlib/cmake.cpp | 33 ++++++ src/cmkrlib/cmake.hpp | 41 ++++--- src/cmkrlib/gen.cpp | 203 +++++++++++++++++++++++---------- tests/.gitignore | 2 + tests/CMakeLists.txt | 13 ++- tests/basic/CMakeLists.txt | 41 ------- tests/cmake.toml | 6 + tests/conditions/cmake.toml | 17 +++ tests/conditions/src/main.cpp | 1 + tests/conditions/src/win32.cpp | 3 + 12 files changed, 257 insertions(+), 122 deletions(-) create mode 100644 tests/.gitignore delete mode 100644 tests/basic/CMakeLists.txt create mode 100644 tests/conditions/cmake.toml create mode 100644 tests/conditions/src/main.cpp create mode 100644 tests/conditions/src/win32.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 66818e5..0f1b0c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ -# This file was generated automatically by cmkr. +# This file is automatically generated from cmake.toml - DO NOT EDIT +# See https://github.com/MoAlyousef/cmkr for more information cmake_minimum_required(VERSION 2.8...3.8) @@ -26,7 +27,6 @@ endif() if(CMAKE_BUILD_TYPE) endif() - project(cmkr LANGUAGES CXX @@ -58,7 +58,9 @@ set(CMAKE_FOLDER ${CMKR_CMAKE_FOLDER}) # Target cmkrlib -set(cmkrlib_SOURCES +unset(cmkrlib_SOURCES) + +list(APPEND cmkrlib_SOURCES "src/cmkrlib/args.cpp" "src/cmkrlib/build.cpp" "src/cmkrlib/cmake.cpp" @@ -74,6 +76,9 @@ set(cmkrlib_SOURCES "include/gen.h" "include/help.h" "include/literals.h" +) + +list(APPEND cmkrlib_SOURCES cmake.toml ) @@ -97,8 +102,13 @@ target_link_libraries(cmkrlib PUBLIC ) # Target cmkr -set(cmkr_SOURCES +unset(cmkr_SOURCES) + +list(APPEND cmkr_SOURCES "src/main.cpp" +) + +list(APPEND cmkr_SOURCES cmake.toml ) diff --git a/README.md b/README.md index 3e0f992..f8e233e 100644 --- a/README.md +++ b/README.md @@ -79,4 +79,3 @@ Header-only library. Equivalent to [add_library(name INTERFACE)](https://cmake.o ## Roadmap - Support more cmake fields. -- Support conditional cmake args somehow! diff --git a/src/cmkrlib/cmake.cpp b/src/cmkrlib/cmake.cpp index e1e040b..51c1468 100644 --- a/src/cmkrlib/cmake.cpp +++ b/src/cmkrlib/cmake.cpp @@ -33,6 +33,26 @@ static EnumType to_enum(const std::string &str, const std::string &help_name) { return value; } +template +static void get_optional(const TomlBasicValue &v, const toml::key &ky, T &destination); + +template +static void get_optional(const TomlBasicValue &v, const toml::key &ky, Condition &destination) { + // TODO: this algorithm in O(n) over the amount of keys, kinda bad + const auto &table = v.as_table(); + for (const auto &itr : table) { + const auto &key = itr.first; + const auto &value = itr.second; + if (value.is_table()) { + if (value.contains(ky)) { + destination[key] = toml::find(value, ky); + } + } else if (key == ky) { + destination[""] = toml::find(v, ky); + } + } +} + template static void get_optional(const TomlBasicValue &v, const toml::key &ky, T &destination) { if (v.contains(ky)) { @@ -237,6 +257,19 @@ CMake::CMake(const std::string &path, bool build) { contents["pmm"]["SOURCE_SUBDIR"] = "pmm"; } } + + // Reasonable default conditions (you can override these if you desire) + conditions["win32"] = conditions["windows"] = conditions["win"] = "WIN32"; + conditions["macos"] = conditions["macosx"] = conditions["osx"] = conditions["mac"] = R"cond("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")cond"; + conditions["unix"] = "UNIX"; + conditions["linux"] = R"cond("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")cond"; + + if (toml.contains("conditions")) { + auto conds = toml::find(toml, "conditions"); + for (const auto &cond : conds) { + conditions[cond.first] = cond.second; + } + } } } } // namespace cmake diff --git a/src/cmkrlib/cmake.hpp b/src/cmkrlib/cmake.hpp index 29d480b..dd22da0 100644 --- a/src/cmkrlib/cmake.hpp +++ b/src/cmkrlib/cmake.hpp @@ -46,28 +46,33 @@ enum TargetType { target_custom, }; +template +using Condition = tsl::ordered_map; + +using ConditionVector = Condition>; + struct Target { std::string name; TargetType type = {}; // https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html#project-commands - std::vector compile_definitions; - std::vector compile_features; - std::vector compile_options; - std::vector include_directories; - std::vector link_directories; - std::vector link_libraries; - std::vector link_options; - std::vector precompile_headers; - std::vector sources; + ConditionVector compile_definitions; + ConditionVector compile_features; + ConditionVector compile_options; + ConditionVector include_directories; + ConditionVector link_directories; + ConditionVector link_libraries; + ConditionVector link_options; + ConditionVector precompile_headers; + ConditionVector sources; std::string alias; tsl::ordered_map properties; - std::string cmake_before; - std::string cmake_after; - std::vector include_before; - std::vector include_after; + Condition cmake_before; + Condition cmake_after; + ConditionVector include_before; + ConditionVector include_after; }; struct Test { @@ -103,10 +108,10 @@ struct CMake { std::string project_version; std::string project_description; std::vector project_languages; - std::string cmake_before; - std::string cmake_after; - std::vector include_before; - std::vector include_after; + Condition cmake_before; + Condition cmake_after; + ConditionVector include_before; + ConditionVector include_after; std::vector settings; std::vector