From bb7874a6df9ca58259783ae2a5675a8e2cf00792 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Thu, 23 Dec 2021 01:54:57 +0100 Subject: [PATCH] Improve compilation times Compilation with make went from 13 -> 10 seconds. CMAKE_UNITY_BUILD went even lower to 6 seconds. Closes #11 --- include/project_parser.hpp | 2 -- src/cmake_generator.cpp | 38 +++++++++++++++++++++++++------------- src/project_parser.cpp | 17 ++++++++--------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/include/project_parser.hpp b/include/project_parser.hpp index 5a19605..fe45cf7 100644 --- a/include/project_parser.hpp +++ b/include/project_parser.hpp @@ -1,8 +1,6 @@ #pragma once -#include #include -#include #include #include #include diff --git a/src/cmake_generator.cpp b/src/cmake_generator.cpp index c70a3a7..e5c917a 100644 --- a/src/cmake_generator.cpp +++ b/src/cmake_generator.cpp @@ -4,16 +4,10 @@ #include #include "fs.hpp" -#include #include -#include #include -#include -#include -#include #include #include -#include namespace cmkr { namespace gen { @@ -157,9 +151,9 @@ struct 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() { + ~Command() noexcept(false) { if (!generated) { - assert(false && "Incorrect usage of cmd(), you probably forgot ()"); + throw std::runtime_error("Incorrect usage of cmd(), you probably forgot ()"); } } @@ -407,10 +401,28 @@ struct Generator { }; static bool vcpkg_valid_identifier(const std::string &name) { - const std::regex reserved("prn|aux|nul|con|lpt[1-9]|com[1-9]|core|default"); - const std::regex ok("[a-z0-9]+(-[a-z0-9]+)*"); - std::cmatch m; - return !std::regex_match(name.c_str(), m, reserved) && std::regex_match(name.c_str(), m, ok); + // prn|aux|nul|con|lpt[1-9]|com[1-9]|core|default + auto is_reserved = [](const std::string &s) { + if (s == "prn" || s == "aux" || s == "nul" || s == "con" || s == "core" || s == "default") { + return true; + } + if (s.length() == 4 && (s.compare(0, 3, "lpt") == 0 || s.compare(0, 3, "com") == 0) && (s[3] >= '1' && s[3] <= '9')) { + return true; + } + return false; + }; + // [a-z0-9]+(-[a-z0-9]+)* + auto is_identifier = [](const std::string &s) { + for (size_t i = 0; i < s.length(); i++) { + auto c = s[i]; + if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (i > 0 && c == '-')) { + continue; + } + return false; + } + return true; + }; + return is_identifier(name) && !is_reserved(name); } static std::string vcpkg_escape_identifier(const std::string &name) { @@ -795,7 +807,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) { target_scope = "PUBLIC"; break; default: - assert("Unimplemented enum value" && false); + throw std::runtime_error("Unimplemented enum value"); } cmd(add_command)(target.name, target_type).endl(); diff --git a/src/project_parser.cpp b/src/project_parser.cpp index b3d7ef7..ad067e4 100644 --- a/src/project_parser.cpp +++ b/src/project_parser.cpp @@ -6,7 +6,6 @@ #include #include #include -#include template <> const char *enumStrings::data[] = {"executable", "library", "shared", "static", "interface", "custom", "object"}; @@ -14,7 +13,7 @@ const char *enumStrings::data[] = {"executable", "libr namespace cmkr { namespace parser { -using TomlBasicValue = toml::basic_value; +using TomlBasicValue = toml::basic_value; template static EnumType to_enum(const std::string &str, const std::string &help_name) { @@ -63,8 +62,8 @@ static std::string format_key_error(const std::string &error, const toml::key &k class TomlChecker { const TomlBasicValue &m_v; - tsl::ordered_set m_visited; - tsl::ordered_set m_conditionVisited; + tsl::ordered_map m_visited; + tsl::ordered_map m_conditionVisited; public: TomlChecker(const TomlBasicValue &v, const toml::key &ky) : m_v(toml::find(v, ky)) {} @@ -91,7 +90,7 @@ class TomlChecker { // Handle visiting logic for (const auto &itr : destination) { if (!itr.first.empty()) { - m_conditionVisited.emplace(itr.first); + m_conditionVisited.emplace(itr.first, true); } } visit(ky); @@ -122,7 +121,7 @@ class TomlChecker { return toml::find(m_v, ky); } - void visit(const toml::key &ky) { m_visited.insert(ky); } + void visit(const toml::key &ky) { m_visited.emplace(ky, true); } void check(const tsl::ordered_map &conditions) const { for (const auto &itr : m_v.as_table()) { @@ -182,7 +181,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) { if (!fs::exists(toml_path)) { throw std::runtime_error("No cmake.toml was found!"); } - const auto toml = toml::parse(toml_path.string()); + const auto toml = toml::parse(toml_path.string()); TomlCheckerRoot checker; @@ -274,7 +273,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) { } if (toml.contains("settings")) { - using set_map = std::map; + using set_map = tsl::ordered_map; const auto &sets = toml::find(toml, "settings"); for (const auto &itr : sets) { Setting s; @@ -507,7 +506,7 @@ bool is_root_path(const std::string &path) { if (!fs::exists(toml_path)) { return false; } - const auto toml = toml::parse(toml_path.string()); + const auto toml = toml::parse(toml_path.string()); return toml.contains("project"); }