diff --git a/include/cmake_generator.hpp b/include/cmake_generator.hpp index 13f1e15..5b34632 100644 --- a/include/cmake_generator.hpp +++ b/include/cmake_generator.hpp @@ -1,11 +1,13 @@ #pragma once +#include "project_parser.hpp" + namespace cmkr { namespace gen { int generate_project(const char *typ); -int generate_cmake(const char *path, bool root = true); +int generate_cmake(const char *path, const parser::Project *parent_project = nullptr); } // namespace gen } // namespace cmkr diff --git a/include/project_parser.hpp b/include/project_parser.hpp index e86cd92..2e4392f 100644 --- a/include/project_parser.hpp +++ b/include/project_parser.hpp @@ -152,7 +152,7 @@ struct Project { tsl::ordered_map conditions; std::vector subdirs; - Project(const std::string &path, bool build); + Project(const Project *parent, const std::string &path, bool build); }; bool is_root_path(const std::string &path); diff --git a/src/build.cpp b/src/build.cpp index b115615..f647746 100644 --- a/src/build.cpp +++ b/src/build.cpp @@ -1,7 +1,7 @@ #include "build.hpp" -#include "project_parser.hpp" -#include "error.hpp" #include "cmake_generator.hpp" +#include "error.hpp" +#include "project_parser.hpp" #include "fs.hpp" #include @@ -14,7 +14,7 @@ namespace cmkr { namespace build { int run(int argc, char **argv) { - parser::Project project(".", true); + parser::Project project(nullptr, ".", true); if (argc > 2) { for (int i = 2; i < argc; ++i) { project.build_args.push_back(argv[i]); @@ -50,7 +50,7 @@ int run(int argc, char **argv) { int clean() { bool ret = false; - parser::Project project(".", true); + parser::Project project(nullptr, ".", true); if (fs::exists(project.build_dir)) { ret = fs::remove_all(project.build_dir); fs::create_directory(project.build_dir); @@ -59,7 +59,7 @@ int clean() { } int install() { - parser::Project project(".", false); + parser::Project project(nullptr, ".", false); auto cmd = "cmake --install " + project.build_dir; return ::system(cmd.c_str()); } diff --git a/src/cmake_generator.cpp b/src/cmake_generator.cpp index b7ff456..470c3c9 100644 --- a/src/cmake_generator.cpp +++ b/src/cmake_generator.cpp @@ -1,7 +1,6 @@ #include "cmake_generator.hpp" #include "error.hpp" #include "literals.hpp" -#include "project_parser.hpp" #include "fs.hpp" #include @@ -440,12 +439,12 @@ static std::string vcpkg_escape_identifier(const std::string &name) { return escaped; } -int generate_cmake(const char *path, bool root) { +int generate_cmake(const char *path, const parser::Project *parent_project) { if (!fs::exists(fs::path(path) / "cmake.toml")) { throw std::runtime_error("No cmake.toml found!"); } - parser::Project project(path, false); + parser::Project project(parent_project, path, false); Generator gen(project); // Helper lambdas for more convenient CMake generation @@ -461,7 +460,8 @@ int generate_cmake(const char *path, bool root) { comment("See " + cmkr_url + " for more information"); endl(); - if (root) { + // Root project doesn't have a parent + if (parent_project == nullptr) { cmd("cmake_minimum_required")("VERSION", project.cmake_version).endl(); if (!project.allow_in_tree) { @@ -919,7 +919,7 @@ int generate_cmake(const char *path, bool root) { } } - auto generate_subdir = [path](const fs::path &sub) { + auto generate_subdir = [path, &project](const fs::path &sub) { // Skip generating for subdirectories that have a cmake.toml with a [project] in it fs::path subpath; for (const auto &p : sub) { @@ -931,7 +931,7 @@ int generate_cmake(const char *path, bool root) { subpath = path / sub; if (fs::exists(subpath / "cmake.toml")) { - generate_cmake(subpath.string().c_str(), false); + generate_cmake(subpath.string().c_str(), &project); } }; for (const auto &itr : project.project_subdirs) { diff --git a/src/project_parser.cpp b/src/project_parser.cpp index 75d4177..bc8d9b6 100644 --- a/src/project_parser.cpp +++ b/src/project_parser.cpp @@ -61,7 +61,7 @@ static void get_optional(const TomlBasicValue &v, const toml::key &ky, T &destin } } -Project::Project(const std::string &path, bool build) { +Project::Project(const Project *parent, const std::string &path, bool build) { const auto toml_path = fs::path(path) / "cmake.toml"; if (!fs::exists(toml_path)) { throw std::runtime_error("No cmake.toml was found!"); @@ -313,14 +313,18 @@ Project::Project(const std::string &path, bool build) { } // Reasonable default conditions (you can override these if you desire) - conditions["windows"] = R"cmake(WIN32)cmake"; - conditions["macos"] = R"cmake(CMAKE_SYSTEM_NAME MATCHES "Darwin")cmake"; - conditions["unix"] = R"cmake(UNIX)cmake"; - conditions["bsd"] = R"cmake(CMAKE_SYSTEM_NAME MATCHES "BSD")cmake"; - conditions["linux"] = conditions["lunix"] = R"cmake(CMAKE_SYSTEM_NAME MATCHES "Linux")cmake"; - conditions["gcc"] = R"cmake(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")cmake"; - conditions["clang"] = R"cmake(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "Clang")cmake"; - conditions["msvc"] = R"cmake(MSVC)cmake"; + if (parent == nullptr) { + conditions["windows"] = R"cmake(WIN32)cmake"; + conditions["macos"] = R"cmake(CMAKE_SYSTEM_NAME MATCHES "Darwin")cmake"; + conditions["unix"] = R"cmake(UNIX)cmake"; + conditions["bsd"] = R"cmake(CMAKE_SYSTEM_NAME MATCHES "BSD")cmake"; + conditions["linux"] = conditions["lunix"] = R"cmake(CMAKE_SYSTEM_NAME MATCHES "Linux")cmake"; + conditions["gcc"] = R"cmake(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")cmake"; + conditions["clang"] = R"cmake(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "Clang")cmake"; + conditions["msvc"] = R"cmake(MSVC)cmake"; + } else { + conditions = parent->conditions; + } if (toml.contains("conditions")) { auto conds = toml::find(toml, "conditions");