Improve compilation times

Compilation with make went from 13 -> 10 seconds.
CMAKE_UNITY_BUILD went even lower to 6 seconds.

Closes #11
main
Duncan Ogilvie 3 years ago
parent 91dbf2986e
commit bb7874a6df

@ -1,8 +1,6 @@
#pragma once #pragma once
#include <map>
#include <mpark/variant.hpp> #include <mpark/variant.hpp>
#include <stdexcept>
#include <string> #include <string>
#include <tsl/ordered_map.h> #include <tsl/ordered_map.h>
#include <vector> #include <vector>

@ -4,16 +4,10 @@
#include <resources/cmkr.hpp> #include <resources/cmkr.hpp>
#include "fs.hpp" #include "fs.hpp"
#include <cassert>
#include <cstdio> #include <cstdio>
#include <cstring>
#include <fstream> #include <fstream>
#include <iomanip>
#include <new>
#include <regex>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string>
namespace cmkr { namespace cmkr {
namespace gen { namespace gen {
@ -157,9 +151,9 @@ struct Command {
Command(std::stringstream &ss, int depth, std::string command, std::string post_comment) 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)) {} : ss(ss), depth(depth), command(std::move(command)), post_comment(std::move(post_comment)) {}
~Command() { ~Command() noexcept(false) {
if (!generated) { 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) { 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"); // prn|aux|nul|con|lpt[1-9]|com[1-9]|core|default
const std::regex ok("[a-z0-9]+(-[a-z0-9]+)*"); auto is_reserved = [](const std::string &s) {
std::cmatch m; if (s == "prn" || s == "aux" || s == "nul" || s == "con" || s == "core" || s == "default") {
return !std::regex_match(name.c_str(), m, reserved) && std::regex_match(name.c_str(), m, ok); 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) { 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"; target_scope = "PUBLIC";
break; break;
default: default:
assert("Unimplemented enum value" && false); throw std::runtime_error("Unimplemented enum value");
} }
cmd(add_command)(target.name, target_type).endl(); cmd(add_command)(target.name, target_type).endl();

@ -6,7 +6,6 @@
#include <stdexcept> #include <stdexcept>
#include <toml.hpp> #include <toml.hpp>
#include <tsl/ordered_map.h> #include <tsl/ordered_map.h>
#include <tsl/ordered_set.h>
template <> template <>
const char *enumStrings<cmkr::parser::TargetType>::data[] = {"executable", "library", "shared", "static", "interface", "custom", "object"}; const char *enumStrings<cmkr::parser::TargetType>::data[] = {"executable", "library", "shared", "static", "interface", "custom", "object"};
@ -14,7 +13,7 @@ const char *enumStrings<cmkr::parser::TargetType>::data[] = {"executable", "libr
namespace cmkr { namespace cmkr {
namespace parser { namespace parser {
using TomlBasicValue = toml::basic_value<toml::preserve_comments, tsl::ordered_map, std::vector>; using TomlBasicValue = toml::basic_value<toml::discard_comments, tsl::ordered_map, std::vector>;
template <typename EnumType> template <typename EnumType>
static EnumType to_enum(const std::string &str, const std::string &help_name) { 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 { class TomlChecker {
const TomlBasicValue &m_v; const TomlBasicValue &m_v;
tsl::ordered_set<toml::key> m_visited; tsl::ordered_map<toml::key, bool> m_visited;
tsl::ordered_set<toml::key> m_conditionVisited; tsl::ordered_map<toml::key, bool> m_conditionVisited;
public: public:
TomlChecker(const TomlBasicValue &v, const toml::key &ky) : m_v(toml::find(v, ky)) {} TomlChecker(const TomlBasicValue &v, const toml::key &ky) : m_v(toml::find(v, ky)) {}
@ -91,7 +90,7 @@ class TomlChecker {
// Handle visiting logic // Handle visiting logic
for (const auto &itr : destination) { for (const auto &itr : destination) {
if (!itr.first.empty()) { if (!itr.first.empty()) {
m_conditionVisited.emplace(itr.first); m_conditionVisited.emplace(itr.first, true);
} }
} }
visit(ky); visit(ky);
@ -122,7 +121,7 @@ class TomlChecker {
return toml::find(m_v, ky); 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<std::string, std::string> &conditions) const { void check(const tsl::ordered_map<std::string, std::string> &conditions) const {
for (const auto &itr : m_v.as_table()) { 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)) { if (!fs::exists(toml_path)) {
throw std::runtime_error("No cmake.toml was found!"); throw std::runtime_error("No cmake.toml was found!");
} }
const auto toml = toml::parse<toml::preserve_comments, tsl::ordered_map, std::vector>(toml_path.string()); const auto toml = toml::parse<toml::discard_comments, tsl::ordered_map, std::vector>(toml_path.string());
TomlCheckerRoot checker; TomlCheckerRoot checker;
@ -274,7 +273,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
} }
if (toml.contains("settings")) { if (toml.contains("settings")) {
using set_map = std::map<std::string, TomlBasicValue>; using set_map = tsl::ordered_map<std::string, TomlBasicValue>;
const auto &sets = toml::find<set_map>(toml, "settings"); const auto &sets = toml::find<set_map>(toml, "settings");
for (const auto &itr : sets) { for (const auto &itr : sets) {
Setting s; Setting s;
@ -507,7 +506,7 @@ bool is_root_path(const std::string &path) {
if (!fs::exists(toml_path)) { if (!fs::exists(toml_path)) {
return false; return false;
} }
const auto toml = toml::parse<toml::preserve_comments, tsl::ordered_map, std::vector>(toml_path.string()); const auto toml = toml::parse<toml::discard_comments, tsl::ordered_map, std::vector>(toml_path.string());
return toml.contains("project"); return toml.contains("project");
} }

Loading…
Cancel
Save