From eaf03eb7856e969f8c71e5e20d2b549a2047bd1b Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Tue, 15 Jun 2021 02:15:06 +0200 Subject: [PATCH] Add support for target condition --- include/cmake.hpp | 1 + src/cmake.cpp | 4 ++++ src/gen.cpp | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/include/cmake.hpp b/include/cmake.hpp index 025488f..d8a44f3 100644 --- a/include/cmake.hpp +++ b/include/cmake.hpp @@ -84,6 +84,7 @@ struct Target { ConditionVector precompile_headers; ConditionVector private_precompile_headers; + std::string condition; std::string alias; Condition> properties; diff --git a/src/cmake.cpp b/src/cmake.cpp index afbe9fd..38b7cda 100644 --- a/src/cmake.cpp +++ b/src/cmake.cpp @@ -214,6 +214,10 @@ CMake::CMake(const std::string &path, bool build) { sources.insert(sources.end(), headers.begin(), headers.end()); } + if (t.contains("condition")) { + target.condition = toml::find(t, "condition").as_string(); + } + if (t.contains("alias")) { target.alias = toml::find(t, "alias").as_string(); } diff --git a/src/gen.cpp b/src/gen.cpp index 01e25b8..9591f46 100644 --- a/src/gen.cpp +++ b/src/gen.cpp @@ -158,8 +158,10 @@ struct Command { bool first_arg = true; bool had_newline = false; bool generated = false; + std::string post_comment; - Command(std::stringstream &ss, int depth, const std::string &command) : ss(ss), depth(depth), command(command) {} + Command(std::stringstream &ss, int depth, std::string command, std::string post_comment) + : ss(ss), depth(depth), command(std::move(command)), post_comment(std::move(post_comment)) {} ~Command() { if (!generated) { @@ -303,7 +305,11 @@ struct Command { (void)std::initializer_list{print_arg(values)...}; if (had_newline) ss << '\n' << indent(depth); - ss << ")\n"; + ss << ")"; + if (!post_comment.empty()) { + ss << " # " << post_comment; + } + ss << "\n"; return CommandEndl(ss); } }; @@ -326,18 +332,18 @@ struct Generator { std::stringstream ss; int indent = 0; - Command cmd(const std::string &command) { + Command cmd(const std::string &command, const std::string &post_comment = "") { if (command.empty()) throw std::invalid_argument("command cannot be empty"); if (command == "if") { indent++; - return Command(ss, indent - 1, command); + return Command(ss, indent - 1, command, post_comment); } else if (command == "else" || command == "elseif") { - return Command(ss, indent - 1, command); + return Command(ss, indent - 1, command, post_comment); } else if (command == "endif") { indent--; } - return Command(ss, indent, command); + return Command(ss, indent, command, post_comment); } CommandEndl comment(const std::string &comment) { @@ -390,7 +396,7 @@ struct Generator { // TODO: somehow print line number information here? throw std::runtime_error("Unknown condition '" + condition + "'"); } - cmd("if")(RawArg(cmake.conditions[condition])); + cmd("if", condition)(RawArg(cmake.conditions[condition])); } if (!itr.second.empty()) { @@ -441,7 +447,7 @@ int generate_cmake(const char *path, bool root) { // Helper lambdas for more convenient CMake generation auto &ss = gen.ss; - auto cmd = [&gen](const std::string &comment) { return gen.cmd(comment); }; + auto cmd = [&gen](const std::string &command) { return gen.cmd(command); }; auto comment = [&gen](const std::string &comment) { return gen.comment(comment); }; auto endl = [&gen]() { gen.endl(); }; auto inject_includes = [&gen](const std::vector &includes) { gen.inject_includes(includes); }; @@ -657,6 +663,15 @@ int generate_cmake(const char *path, bool root) { if (!cmake.targets.empty()) { for (const auto &target : cmake.targets) { comment("Target " + target.name); + + if (!target.condition.empty()) { + const auto &condition = target.condition; + if (cmake.conditions.count(condition) == 0) { + throw std::runtime_error("Unknown condition '" + condition + "' for [target." + target.name + "]"); + } + gen.cmd("if", condition)(RawArg(cmake.conditions[condition])); + } + cmd("set")("CMKR_TARGET", target.name); gen.handle_condition(target.include_before, @@ -791,6 +806,11 @@ int generate_cmake(const char *path, bool root) { cmd("unset")("CMKR_TARGET"); cmd("unset")("CMKR_SOURCES"); + + if (!target.condition.empty()) { + cmd("endif")(); + } + endl(); } }