Rename things to try to make the code more readable

toml-checker
Duncan Ogilvie 3 years ago
parent 82f2a11311
commit 1b37dd76a5

@ -8,7 +8,7 @@
#include <vector> #include <vector>
namespace cmkr { namespace cmkr {
namespace cmake { namespace parser {
struct Setting { struct Setting {
std::string name; std::string name;
@ -110,7 +110,7 @@ struct Install {
std::string destination; std::string destination;
}; };
struct CMake { struct Project {
// This is the CMake version required to use all cmkr versions. // This is the CMake version required to use all cmkr versions.
std::string cmake_version = "3.15"; std::string cmake_version = "3.15";
std::string cmkr_include = "cmkr.cmake"; std::string cmkr_include = "cmkr.cmake";
@ -141,8 +141,8 @@ struct CMake {
std::vector<Install> installs; std::vector<Install> installs;
tsl::ordered_map<std::string, std::string> conditions; tsl::ordered_map<std::string, std::string> conditions;
CMake(const std::string &path, bool build); Project(const std::string &path, bool build);
}; };
} // namespace cmake } // namespace parser
} // namespace cmkr } // namespace cmkr

@ -14,10 +14,10 @@ namespace cmkr {
namespace build { namespace build {
int run(int argc, char **argv) { int run(int argc, char **argv) {
cmake::CMake cmake(".", true); parser::Project project(".", true);
if (argc > 2) { if (argc > 2) {
for (int i = 2; i < argc; ++i) { for (int i = 2; i < argc; ++i) {
cmake.build_args.push_back(argv[i]); project.build_args.push_back(argv[i]);
} }
} }
std::stringstream ss; std::stringstream ss;
@ -25,22 +25,22 @@ int run(int argc, char **argv) {
if (gen::generate_cmake(fs::current_path().string().c_str())) if (gen::generate_cmake(fs::current_path().string().c_str()))
throw std::runtime_error("CMake generation failure!"); throw std::runtime_error("CMake generation failure!");
ss << "cmake -S. -B" << cmake.build_dir << " "; ss << "cmake -S. -B" << project.build_dir << " ";
if (!cmake.generator.empty()) { if (!project.generator.empty()) {
ss << "-G \"" << cmake.generator << "\" "; ss << "-G \"" << project.generator << "\" ";
} }
if (!cmake.config.empty()) { if (!project.config.empty()) {
ss << "-DCMAKE_BUILD_TYPE=" << cmake.config << " "; ss << "-DCMAKE_BUILD_TYPE=" << project.config << " ";
} }
if (!cmake.gen_args.empty()) { if (!project.gen_args.empty()) {
for (const auto &arg : cmake.gen_args) { for (const auto &arg : project.gen_args) {
ss << "-D" << arg << " "; ss << "-D" << arg << " ";
} }
} }
ss << "&& cmake --build " << cmake.build_dir << " --parallel"; ss << "&& cmake --build " << project.build_dir << " --parallel";
if (argc > 2) { if (argc > 2) {
for (const auto &arg : cmake.build_args) { for (const auto &arg : project.build_args) {
ss << " " << arg; ss << " " << arg;
} }
} }
@ -50,17 +50,17 @@ int run(int argc, char **argv) {
int clean() { int clean() {
bool ret = false; bool ret = false;
cmake::CMake cmake(".", true); parser::Project project(".", true);
if (fs::exists(cmake.build_dir)) { if (fs::exists(project.build_dir)) {
ret = fs::remove_all(cmake.build_dir); ret = fs::remove_all(project.build_dir);
fs::create_directory(cmake.build_dir); fs::create_directory(project.build_dir);
} }
return !ret; return !ret;
} }
int install() { int install() {
cmake::CMake cmake(".", false); parser::Project project(".", false);
auto cmd = "cmake --install " + cmake.build_dir; auto cmd = "cmake --install " + project.build_dir;
return ::system(cmd.c_str()); return ::system(cmd.c_str());
} }
} // namespace build } // namespace build

@ -7,10 +7,10 @@
#include <tsl/ordered_map.h> #include <tsl/ordered_map.h>
template <> template <>
const char *enumStrings<cmkr::cmake::TargetType>::data[] = {"executable", "library", "shared", "static", "interface", "custom"}; const char *enumStrings<cmkr::parser::TargetType>::data[] = {"executable", "library", "shared", "static", "interface", "custom"};
namespace cmkr { namespace cmkr {
namespace cmake { namespace parser {
using TomlBasicValue = toml::basic_value<toml::preserve_comments, tsl::ordered_map, std::vector>; using TomlBasicValue = toml::basic_value<toml::preserve_comments, tsl::ordered_map, std::vector>;
@ -61,7 +61,7 @@ static void get_optional(const TomlBasicValue &v, const toml::key &ky, T &destin
} }
} }
CMake::CMake(const std::string &path, bool build) { Project::Project(const std::string &path, bool build) {
if (!fs::exists(fs::path(path) / "cmake.toml")) { if (!fs::exists(fs::path(path) / "cmake.toml")) {
throw std::runtime_error("No cmake.toml was found!"); throw std::runtime_error("No cmake.toml was found!");
} }
@ -311,5 +311,5 @@ CMake::CMake(const std::string &path, bool build) {
} }
} }
} }
} // namespace cmake } // namespace parser
} // namespace cmkr } // namespace cmkr

@ -325,10 +325,10 @@ static std::string tolf(const std::string &str) {
}; };
struct Generator { struct Generator {
Generator(cmake::CMake &cmake) : cmake(cmake) {} Generator(parser::Project &project) : project(project) {}
Generator(const Generator &) = delete; Generator(const Generator &) = delete;
cmake::CMake &cmake; parser::Project &project;
std::stringstream ss; std::stringstream ss;
int indent = 0; int indent = 0;
@ -387,16 +387,16 @@ struct Generator {
} }
template <typename T, typename Lambda> template <typename T, typename Lambda>
void handle_condition(const cmake::Condition<T> &value, const Lambda &fn) { void handle_condition(const parser::Condition<T> &value, const Lambda &fn) {
if (!value.empty()) { if (!value.empty()) {
for (const auto &itr : value) { for (const auto &itr : value) {
const auto &condition = itr.first; const auto &condition = itr.first;
if (!condition.empty()) { if (!condition.empty()) {
if (cmake.conditions.count(condition) == 0) { if (project.conditions.count(condition) == 0) {
// TODO: somehow print line number information here? // TODO: somehow print line number information here?
throw std::runtime_error("Unknown condition '" + condition + "'"); throw std::runtime_error("Unknown condition '" + condition + "'");
} }
cmd("if", condition)(RawArg(cmake.conditions[condition])); cmd("if", condition)(RawArg(project.conditions[condition]));
} }
if (!itr.second.empty()) { if (!itr.second.empty()) {
@ -442,8 +442,8 @@ int generate_cmake(const char *path, bool root) {
throw std::runtime_error("No cmake.toml found!"); throw std::runtime_error("No cmake.toml found!");
} }
cmake::CMake cmake(path, false); parser::Project project(path, false);
Generator gen(cmake); Generator gen(project);
// Helper lambdas for more convenient CMake generation // Helper lambdas for more convenient CMake generation
auto &ss = gen.ss; auto &ss = gen.ss;
@ -459,7 +459,7 @@ int generate_cmake(const char *path, bool root) {
endl(); endl();
if (root) { if (root) {
cmd("cmake_minimum_required")("VERSION", cmake.cmake_version).endl(); cmd("cmake_minimum_required")("VERSION", project.cmake_version).endl();
comment("Regenerate CMakeLists.txt automatically in the root project"); comment("Regenerate CMakeLists.txt automatically in the root project");
cmd("set")("CMKR_ROOT_PROJECT", "OFF"); cmd("set")("CMKR_ROOT_PROJECT", "OFF");
@ -468,7 +468,7 @@ int generate_cmake(const char *path, bool root) {
cmd("set")("CMKR_ROOT_PROJECT", "ON").endl(); cmd("set")("CMKR_ROOT_PROJECT", "ON").endl();
comment("Bootstrap cmkr"); comment("Bootstrap cmkr");
cmd("include")(cmake.cmkr_include, "OPTIONAL", "RESULT_VARIABLE", "CMKR_INCLUDE_RESULT"); cmd("include")(project.cmkr_include, "OPTIONAL", "RESULT_VARIABLE", "CMKR_INCLUDE_RESULT");
cmd("if")("CMKR_INCLUDE_RESULT"); cmd("if")("CMKR_INCLUDE_RESULT");
cmd("cmkr")(); cmd("cmkr")();
cmd("endif")().endl(); cmd("endif")().endl();
@ -487,48 +487,48 @@ int generate_cmake(const char *path, bool root) {
// clang-format on // clang-format on
// TODO: remove support and replace with global compile-features // TODO: remove support and replace with global compile-features
if (!cmake.cppflags.empty()) { if (!project.cppflags.empty()) {
ss << "set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} \""; ss << "set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} \"";
for (const auto &flag : cmake.cppflags) { for (const auto &flag : project.cppflags) {
ss << flag << " "; ss << flag << " ";
} }
ss << "\")\n\n"; ss << "\")\n\n";
} }
// TODO: remove support and replace with global compile-features // TODO: remove support and replace with global compile-features
if (!cmake.cflags.empty()) { if (!project.cflags.empty()) {
ss << "set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} \""; ss << "set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} \"";
for (const auto &flag : cmake.cflags) { for (const auto &flag : project.cflags) {
ss << flag << " "; ss << flag << " ";
} }
ss << "\")\n\n"; ss << "\")\n\n";
} }
// TODO: remove support and replace with global linker-flags // TODO: remove support and replace with global linker-flags
if (!cmake.linkflags.empty()) { if (!project.linkflags.empty()) {
ss << "set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} \""; ss << "set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} \"";
for (const auto &flag : cmake.linkflags) { for (const auto &flag : project.linkflags) {
ss << flag << " "; ss << flag << " ";
} }
ss << "\")\n\n"; ss << "\")\n\n";
} }
gen.handle_condition(cmake.include_before, [&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); }); gen.handle_condition(project.include_before, [&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); });
gen.handle_condition(cmake.cmake_before, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); }); gen.handle_condition(project.cmake_before, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); });
if (!cmake.project_name.empty()) { if (!project.project_name.empty()) {
auto languages = std::make_pair("LANGUAGES", cmake.project_languages); auto languages = std::make_pair("LANGUAGES", project.project_languages);
auto version = std::make_pair("VERSION", cmake.project_version); auto version = std::make_pair("VERSION", project.project_version);
auto description = std::make_pair("DESCRIPTION", cmake.project_description); auto description = std::make_pair("DESCRIPTION", project.project_description);
cmd("project")(cmake.project_name, languages, version, description).endl(); cmd("project")(project.project_name, languages, version, description).endl();
} }
gen.handle_condition(cmake.include_after, [&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); }); gen.handle_condition(project.include_after, [&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); });
gen.handle_condition(cmake.cmake_after, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); }); gen.handle_condition(project.cmake_after, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); });
if (!cmake.contents.empty()) { if (!project.contents.empty()) {
cmd("include")("FetchContent").endl(); cmd("include")("FetchContent").endl();
for (const auto &dep : cmake.contents) { for (const auto &dep : project.contents) {
cmd("message")("STATUS", "Fetching " + dep.first + "..."); cmd("message")("STATUS", "Fetching " + dep.first + "...");
ss << "FetchContent_Declare(\n\t" << dep.first << "\n"; ss << "FetchContent_Declare(\n\t" << dep.first << "\n";
for (const auto &arg : dep.second) { for (const auto &arg : dep.second) {
@ -555,14 +555,14 @@ int generate_cmake(const char *path, bool root) {
} }
} }
if (!cmake.vcpkg.packages.empty()) { if (!project.vcpkg.packages.empty()) {
// Allow the user to specify a url or derive it from the version // Allow the user to specify a url or derive it from the version
auto url = cmake.vcpkg.url; auto url = project.vcpkg.url;
if (url.empty()) { if (url.empty()) {
if (cmake.vcpkg.version.empty()) { if (project.vcpkg.version.empty()) {
throw std::runtime_error("You need either [vcpkg].version or [vcpkg].url"); throw std::runtime_error("You need either [vcpkg].version or [vcpkg].url");
} }
url = "https://github.com/microsoft/vcpkg/archive/refs/tags/" + cmake.vcpkg.version + ".tar.gz"; url = "https://github.com/microsoft/vcpkg/archive/refs/tags/" + project.vcpkg.version + ".tar.gz";
} }
// CMake to bootstrap vcpkg and download the packages // CMake to bootstrap vcpkg and download the packages
@ -583,11 +583,11 @@ int generate_cmake(const char *path, bool root) {
j["$cmkr"] = "This file is automatically generated from cmake.toml - DO NOT EDIT"; j["$cmkr"] = "This file is automatically generated from cmake.toml - DO NOT EDIT";
j["$cmkr-url"] = cmkr_url; j["$cmkr-url"] = cmkr_url;
j["$schema"] = "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json"; j["$schema"] = "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json";
j["name"] = vcpkg_escape_identifier(cmake.project_name); j["name"] = vcpkg_escape_identifier(project.project_name);
j["version-string"] = cmake.project_version; j["version-string"] = project.project_version;
j["dependencies"] = cmake.vcpkg.packages; j["dependencies"] = project.vcpkg.packages;
if (!cmake.project_description.empty()) { if (!project.project_description.empty()) {
j["description"] = cmake.project_description; j["description"] = project.project_description;
} }
std::ofstream ofs("vcpkg.json"); std::ofstream ofs("vcpkg.json");
@ -597,9 +597,9 @@ int generate_cmake(const char *path, bool root) {
ofs << std::setw(2) << j << std::endl; ofs << std::setw(2) << j << std::endl;
} }
if (!cmake.packages.empty()) { if (!project.packages.empty()) {
comment("Packages"); comment("Packages");
for (const auto &dep : cmake.packages) { for (const auto &dep : project.packages) {
auto version = dep.version; auto version = dep.version;
if (version == "*") if (version == "*")
version.clear(); version.clear();
@ -610,17 +610,17 @@ int generate_cmake(const char *path, bool root) {
} }
} }
if (!cmake.options.empty()) { if (!project.options.empty()) {
comment("Options"); comment("Options");
for (const auto &opt : cmake.options) { for (const auto &opt : project.options) {
cmd("option")(opt.name, opt.comment, opt.val ? "ON" : "OFF"); cmd("option")(opt.name, opt.comment, opt.val ? "ON" : "OFF");
} }
endl(); endl();
} }
if (!cmake.settings.empty()) { if (!project.settings.empty()) {
comment("Settings"); comment("Settings");
for (const auto &set : cmake.settings) { for (const auto &set : project.settings) {
std::string set_val; std::string set_val;
if (set.val.index() == 1) { if (set.val.index() == 1) {
set_val = mpark::get<1>(set.val); set_val = mpark::get<1>(set.val);
@ -640,8 +640,8 @@ int generate_cmake(const char *path, bool root) {
} }
// generate_cmake is called on the subdirectories recursively later // generate_cmake is called on the subdirectories recursively later
if (!cmake.subdirs.empty()) { if (!project.subdirs.empty()) {
gen.handle_condition(cmake.subdirs, [&](const std::string &, const std::vector<std::string> &subdirs) { gen.handle_condition(project.subdirs, [&](const std::string &, const std::vector<std::string> &subdirs) {
for (const auto &dir : subdirs) { for (const auto &dir : subdirs) {
// clang-format off // clang-format off
comment(dir); comment(dir);
@ -660,16 +660,16 @@ int generate_cmake(const char *path, bool root) {
endl(); endl();
} }
if (!cmake.targets.empty()) { if (!project.targets.empty()) {
for (const auto &target : cmake.targets) { for (const auto &target : project.targets) {
comment("Target " + target.name); comment("Target " + target.name);
if (!target.condition.empty()) { if (!target.condition.empty()) {
const auto &condition = target.condition; const auto &condition = target.condition;
if (cmake.conditions.count(condition) == 0) { if (project.conditions.count(condition) == 0) {
throw std::runtime_error("Unknown condition '" + condition + "' for [target." + target.name + "]"); throw std::runtime_error("Unknown condition '" + condition + "' for [target." + target.name + "]");
} }
gen.cmd("if", condition)(RawArg(cmake.conditions[condition])); gen.cmd("if", condition)(RawArg(project.conditions[condition]));
} }
cmd("set")("CMKR_TARGET", target.name); cmd("set")("CMKR_TARGET", target.name);
@ -695,7 +695,7 @@ int generate_cmake(const char *path, bool root) {
cmd("list")("APPEND", sources_var, sources); cmd("list")("APPEND", sources_var, sources);
}); });
if (!added_toml && target.type != cmake::target_interface) { if (!added_toml && target.type != parser::target_interface) {
cmd("list")("APPEND", sources_var, std::vector<std::string>{"cmake.toml"}).endl(); cmd("list")("APPEND", sources_var, std::vector<std::string>{"cmake.toml"}).endl();
} }
cmd("set")("CMKR_SOURCES", "${" + sources_var + "}"); cmd("set")("CMKR_SOURCES", "${" + sources_var + "}");
@ -704,32 +704,32 @@ int generate_cmake(const char *path, bool root) {
std::string target_type; std::string target_type;
std::string target_scope; std::string target_scope;
switch (target.type) { switch (target.type) {
case cmake::target_executable: case parser::target_executable:
add_command = "add_executable"; add_command = "add_executable";
target_type = ""; target_type = "";
target_scope = "PRIVATE"; target_scope = "PRIVATE";
break; break;
case cmake::target_library: case parser::target_library:
add_command = "add_library"; add_command = "add_library";
target_type = ""; target_type = "";
target_scope = "PUBLIC"; target_scope = "PUBLIC";
break; break;
case cmake::target_shared: case parser::target_shared:
add_command = "add_library"; add_command = "add_library";
target_type = "SHARED"; target_type = "SHARED";
target_scope = "PUBLIC"; target_scope = "PUBLIC";
break; break;
case cmake::target_static: case parser::target_static:
add_command = "add_library"; add_command = "add_library";
target_type = "STATIC"; target_type = "STATIC";
target_scope = "PUBLIC"; target_scope = "PUBLIC";
break; break;
case cmake::target_interface: case parser::target_interface:
add_command = "add_library"; add_command = "add_library";
target_type = "INTERFACE"; target_type = "INTERFACE";
target_scope = "INTERFACE"; target_scope = "INTERFACE";
break; break;
case cmake::target_custom: case parser::target_custom:
// TODO: add proper support, this is hacky // TODO: add proper support, this is hacky
add_command = "add_custom_target"; add_command = "add_custom_target";
target_type = "SOURCES"; target_type = "SOURCES";
@ -743,12 +743,12 @@ int generate_cmake(const char *path, bool root) {
// clang-format off // clang-format off
cmd("if")(sources_var); cmd("if")(sources_var);
cmd("target_sources")(target.name, target.type == cmake::target_interface ? "INTERFACE" : "PRIVATE", "${" + sources_var + "}"); cmd("target_sources")(target.name, target.type == parser::target_interface ? "INTERFACE" : "PRIVATE", "${" + sources_var + "}");
cmd("endif")().endl(); cmd("endif")().endl();
// clang-format on // clang-format on
// The first executable target will become the Visual Studio startup project // The first executable target will become the Visual Studio startup project
if (target.type == cmake::target_executable) { if (target.type == parser::target_executable) {
cmd("get_directory_property")("CMKR_VS_STARTUP_PROJECT", "DIRECTORY", "${PROJECT_SOURCE_DIR}", "DEFINITION", "VS_STARTUP_PROJECT"); cmd("get_directory_property")("CMKR_VS_STARTUP_PROJECT", "DIRECTORY", "${PROJECT_SOURCE_DIR}", "DEFINITION", "VS_STARTUP_PROJECT");
// clang-format off // clang-format off
cmd("if")("NOT", "CMKR_VS_STARTUP_PROJECT"); cmd("if")("NOT", "CMKR_VS_STARTUP_PROJECT");
@ -765,7 +765,7 @@ int generate_cmake(const char *path, bool root) {
cmd("add_library")(target.alias, "ALIAS", target.name); cmd("add_library")(target.alias, "ALIAS", target.name);
} }
auto target_cmd = [&](const char *command, const cmake::ConditionVector &cargs, const std::string &scope) { auto target_cmd = [&](const char *command, const parser::ConditionVector &cargs, const std::string &scope) {
gen.handle_condition(cargs, gen.handle_condition(cargs,
[&](const std::string &, const std::vector<std::string> &args) { cmd(command)(target.name, scope, args); }); [&](const std::string &, const std::vector<std::string> &args) { cmd(command)(target.name, scope, args); });
}; };
@ -815,9 +815,9 @@ int generate_cmake(const char *path, bool root) {
} }
} }
if (!cmake.tests.empty()) { if (!project.tests.empty()) {
cmd("enable_testing")().endl(); cmd("enable_testing")().endl();
for (const auto &test : cmake.tests) { for (const auto &test : project.tests) {
auto name = std::make_pair("NAME", test.name); auto name = std::make_pair("NAME", test.name);
auto configurations = std::make_pair("CONFIGURATIONS", test.configurations); auto configurations = std::make_pair("CONFIGURATIONS", test.configurations);
auto dir = test.working_directory; auto dir = test.working_directory;
@ -831,8 +831,8 @@ int generate_cmake(const char *path, bool root) {
} }
} }
if (!cmake.installs.empty()) { if (!project.installs.empty()) {
for (const auto &inst : cmake.installs) { for (const auto &inst : project.installs) {
auto targets = std::make_pair("TARGETS", inst.targets); auto targets = std::make_pair("TARGETS", inst.targets);
auto dirs = std::make_pair("DIRS", inst.dirs); auto dirs = std::make_pair("DIRS", inst.dirs);
std::vector<std::string> files_data; std::vector<std::string> files_data;
@ -875,7 +875,7 @@ int generate_cmake(const char *path, bool root) {
} }
} }
for (const auto &itr : cmake.subdirs) { for (const auto &itr : project.subdirs) {
for (const auto &sub : itr.second) { for (const auto &sub : itr.second) {
auto subpath = fs::path(path) / fs::path(sub); auto subpath = fs::path(path) / fs::path(sub);
if (fs::exists(subpath / "cmake.toml")) if (fs::exists(subpath / "cmake.toml"))

Loading…
Cancel
Save