mirror of
https://github.com/build-cpp/cmkr
synced 2026-06-08 13:22:55 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fc74a5e802 | |||
| e48d402e21 | |||
| f6a245618e | |||
| c713606fd4 | |||
| fe9b6587a9 |
Generated
+1
-1
@@ -25,7 +25,7 @@ project(cmkr
|
||||
LANGUAGES
|
||||
CXX
|
||||
VERSION
|
||||
0.2.9
|
||||
0.2.10
|
||||
DESCRIPTION
|
||||
"CMakeLists generator from TOML"
|
||||
)
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ cmkr-include = false
|
||||
|
||||
[project]
|
||||
name = "cmkr"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
description = "CMakeLists generator from TOML"
|
||||
languages = ["CXX"]
|
||||
subdirs = ["third_party", "tests"]
|
||||
|
||||
@@ -12,6 +12,14 @@ if(NOT EXISTS "${CMAKE_SOURCE_DIR}/cmake/cmkr.cmake")
|
||||
message(FATAL_ERROR "Cannot find cmkr.cmake")
|
||||
endif()
|
||||
|
||||
# Validate branch
|
||||
find_package(Git REQUIRED)
|
||||
execute_process(COMMAND "${GIT_EXECUTABLE}" branch --show-current OUTPUT_VARIABLE GIT_BRANCH)
|
||||
string(STRIP "${GIT_BRANCH}" GIT_BRANCH)
|
||||
if(NOT GIT_BRANCH STREQUAL "main")
|
||||
message(FATAL_ERROR "You need to be on the main branch, you are on: ${GIT_BRANCH}")
|
||||
endif()
|
||||
|
||||
file(READ "${CMAKE_SOURCE_DIR}/cmake.toml" CMAKE_TOML)
|
||||
string(FIND "${CMAKE_TOML}" "[project]" PROJECT_INDEX)
|
||||
string(SUBSTRING "${CMAKE_TOML}" ${PROJECT_INDEX} -1 CMAKE_TOML_PROJECT)
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ include_guard()
|
||||
|
||||
# Change these defaults to point to your infrastructure if desired
|
||||
set(CMKR_REPO "https://github.com/build-cpp/cmkr" CACHE STRING "cmkr git repository" FORCE)
|
||||
set(CMKR_TAG "v0.2.9" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
|
||||
set(CMKR_TAG "v0.2.10" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
|
||||
|
||||
# To bootstrap/generate a cmkr project: cmake -P cmkr.cmake
|
||||
if(CMAKE_SCRIPT_MODE_FILE)
|
||||
|
||||
+37
-20
@@ -143,14 +143,21 @@ class TomlChecker {
|
||||
};
|
||||
|
||||
class TomlCheckerRoot {
|
||||
const TomlBasicValue &m_root;
|
||||
std::deque<TomlChecker> m_checkers;
|
||||
tsl::ordered_map<toml::key, bool> m_visisted;
|
||||
bool m_checked = false;
|
||||
|
||||
public:
|
||||
TomlCheckerRoot() = default;
|
||||
TomlCheckerRoot(const TomlBasicValue &root) : m_root(root) {}
|
||||
TomlCheckerRoot(const TomlCheckerRoot &) = delete;
|
||||
TomlCheckerRoot(TomlCheckerRoot &&) = delete;
|
||||
|
||||
bool contains(const toml::key &ky) {
|
||||
m_visisted[ky] = true;
|
||||
return m_root.contains(ky);
|
||||
}
|
||||
|
||||
TomlChecker &create(const TomlBasicValue &v) {
|
||||
m_checkers.emplace_back(v);
|
||||
return m_checkers.back();
|
||||
@@ -161,7 +168,14 @@ class TomlCheckerRoot {
|
||||
return m_checkers.back();
|
||||
}
|
||||
|
||||
void check(const tsl::ordered_map<std::string, std::string> &conditions) {
|
||||
void check(const tsl::ordered_map<std::string, std::string> &conditions, bool check_root) {
|
||||
if (check_root) {
|
||||
for (const auto &itr : m_root.as_table()) {
|
||||
if (!m_visisted.contains(itr.first)) {
|
||||
throw std::runtime_error(format_key_error("Unknown key '" + itr.first + "'", itr.first, itr.second));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto &checker : m_checkers) {
|
||||
checker.check(conditions);
|
||||
}
|
||||
@@ -171,13 +185,16 @@ class TomlCheckerRoot {
|
||||
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!");
|
||||
throw std::runtime_error("File not found '" + toml_path.string() + "'");
|
||||
}
|
||||
const auto toml = toml::parse<toml::discard_comments, tsl::ordered_map, std::vector>(toml_path.string());
|
||||
if (toml.size() == 0) {
|
||||
throw std::runtime_error("Empty TOML '" + toml_path.string() + "'");
|
||||
}
|
||||
|
||||
TomlCheckerRoot checker;
|
||||
TomlCheckerRoot checker(toml);
|
||||
|
||||
if (toml.contains("cmake")) {
|
||||
if (checker.contains("cmake")) {
|
||||
auto &cmake = checker.create(toml, "cmake");
|
||||
|
||||
cmake.required("version", cmake_version);
|
||||
@@ -209,7 +226,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
|
||||
// Skip the rest of the parsing when building
|
||||
if (build) {
|
||||
checker.check(conditions);
|
||||
checker.check(conditions, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -231,14 +248,14 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
templates = parent->templates;
|
||||
}
|
||||
|
||||
if (toml.contains("conditions")) {
|
||||
if (checker.contains("conditions")) {
|
||||
auto conds = toml::find<decltype(conditions)>(toml, "conditions");
|
||||
for (const auto &cond : conds) {
|
||||
conditions[cond.first] = cond.second;
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("project")) {
|
||||
if (checker.contains("project")) {
|
||||
auto &project = checker.create(toml, "project");
|
||||
project.required("name", project_name);
|
||||
project.optional("version", project_version);
|
||||
@@ -251,7 +268,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
project.optional("subdirs", project_subdirs);
|
||||
}
|
||||
|
||||
if (toml.contains("subdir")) {
|
||||
if (checker.contains("subdir")) {
|
||||
const auto &subs = toml::find(toml, "subdir").as_table();
|
||||
for (const auto &itr : subs) {
|
||||
Subdir subdir;
|
||||
@@ -268,7 +285,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("settings")) {
|
||||
if (checker.contains("settings")) {
|
||||
using set_map = tsl::ordered_map<std::string, TomlBasicValue>;
|
||||
const auto &sets = toml::find<set_map>(toml, "settings");
|
||||
for (const auto &itr : sets) {
|
||||
@@ -297,7 +314,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("options")) {
|
||||
if (checker.contains("options")) {
|
||||
using opts_map = tsl::ordered_map<std::string, TomlBasicValue>;
|
||||
const auto &opts = toml::find<opts_map>(toml, "options");
|
||||
for (const auto &itr : opts) {
|
||||
@@ -315,7 +332,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("find-package")) {
|
||||
if (checker.contains("find-package")) {
|
||||
using pkg_map = tsl::ordered_map<std::string, TomlBasicValue>;
|
||||
const auto &pkgs = toml::find<pkg_map>(toml, "find-package");
|
||||
for (const auto &itr : pkgs) {
|
||||
@@ -337,7 +354,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
|
||||
// TODO: perform checking here
|
||||
if (toml.contains("fetch-content")) {
|
||||
if (checker.contains("fetch-content")) {
|
||||
const auto &fc = toml::find(toml, "fetch-content").as_table();
|
||||
for (const auto &itr : fc) {
|
||||
Content content;
|
||||
@@ -370,7 +387,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("bin")) {
|
||||
if (checker.contains("bin")) {
|
||||
throw std::runtime_error("[[bin]] has been renamed to [[target]]");
|
||||
}
|
||||
|
||||
@@ -489,7 +506,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
return target;
|
||||
};
|
||||
|
||||
if (toml.contains("template")) {
|
||||
if (checker.contains("template")) {
|
||||
const auto &ts = toml::find(toml, "template").as_table();
|
||||
for (const auto &itr : ts) {
|
||||
auto &t = checker.create(itr.second);
|
||||
@@ -517,7 +534,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("target")) {
|
||||
if (checker.contains("target")) {
|
||||
const auto &ts = toml::find(toml, "target").as_table();
|
||||
for (const auto &itr : ts) {
|
||||
auto &t = checker.create(itr.second);
|
||||
@@ -525,7 +542,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("test")) {
|
||||
if (checker.contains("test")) {
|
||||
const auto &ts = toml::find(toml, "test").as_array();
|
||||
for (const auto &value : ts) {
|
||||
auto &t = checker.create(value);
|
||||
@@ -540,7 +557,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("install")) {
|
||||
if (checker.contains("install")) {
|
||||
const auto &is = toml::find(toml, "install").as_array();
|
||||
for (const auto &value : is) {
|
||||
auto &i = checker.create(value);
|
||||
@@ -556,7 +573,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
if (toml.contains("vcpkg")) {
|
||||
if (checker.contains("vcpkg")) {
|
||||
auto &v = checker.create(toml, "vcpkg");
|
||||
v.optional("url", vcpkg.url);
|
||||
v.optional("version", vcpkg.version);
|
||||
@@ -582,7 +599,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
}
|
||||
}
|
||||
|
||||
checker.check(conditions);
|
||||
checker.check(conditions, true);
|
||||
}
|
||||
|
||||
bool is_root_path(const std::string &path) {
|
||||
|
||||
Reference in New Issue
Block a user