mirror of
https://github.com/build-cpp/cmkr
synced 2026-06-08 13:22:55 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bdaf5c94e6 | |||
| fa3b7a346c | |||
| df1dbf7953 | |||
| 5951f6930e | |||
| a6d5f1c99b | |||
| dc852b9a2f | |||
| 66621a9818 | |||
| 2cd8ad0f18 | |||
| 084cbd6159 | |||
| b4b0f533a9 | |||
| 0acc9b4e5a | |||
| 61dfb0eb60 | |||
| 3201fd052e |
Generated
+1
-1
@@ -25,7 +25,7 @@ project(cmkr
|
||||
LANGUAGES
|
||||
CXX
|
||||
VERSION
|
||||
0.2.0
|
||||
0.2.2
|
||||
DESCRIPTION
|
||||
"CMakeLists generator from TOML"
|
||||
)
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ cmkr-include = false
|
||||
|
||||
[project]
|
||||
name = "cmkr"
|
||||
version = "0.2.0"
|
||||
version = "0.2.2"
|
||||
description = "CMakeLists generator from TOML"
|
||||
languages = ["CXX"]
|
||||
subdirs = ["third_party", "tests"]
|
||||
|
||||
+4
-4
@@ -1,5 +1,9 @@
|
||||
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.2" 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)
|
||||
set(CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}/build")
|
||||
@@ -7,10 +11,6 @@ if(CMAKE_SCRIPT_MODE_FILE)
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
# 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.0" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
|
||||
|
||||
# Set these from the command line to customize for development/debugging purposes
|
||||
set(CMKR_EXECUTABLE "" CACHE FILEPATH "cmkr executable")
|
||||
set(CMKR_SKIP_GENERATION OFF CACHE BOOL "skip automatic cmkr generation")
|
||||
|
||||
@@ -46,14 +46,14 @@ function(generate_documentation)
|
||||
string(REGEX MATCH "^(\n*(#[^\n]+\n)+\n*)" EXAMPLE_HEADER "${test_contents}")
|
||||
string(LENGTH "${EXAMPLE_HEADER}" header_length)
|
||||
string(STRIP "${EXAMPLE_HEADER}" EXAMPLE_HEADER)
|
||||
string(REGEX REPLACE "\n# ?" "\n" EXAMPLE_HEADER "\n${EXAMPLE_HEADER}")
|
||||
string(REGEX REPLACE "\n# ?" "\n\n" EXAMPLE_HEADER "\n${EXAMPLE_HEADER}")
|
||||
string(STRIP "${EXAMPLE_HEADER}" EXAMPLE_HEADER)
|
||||
|
||||
# Extract footer text
|
||||
string(REGEX MATCH "(((#[^\n]+)(\n+|$))+)$" EXAMPLE_FOOTER "${test_contents}")
|
||||
string(LENGTH "${EXAMPLE_FOOTER}" footer_length)
|
||||
string(STRIP "${EXAMPLE_FOOTER}" EXAMPLE_FOOTER)
|
||||
string(REGEX REPLACE "\n# ?" "\n" EXAMPLE_FOOTER "\n${EXAMPLE_FOOTER}")
|
||||
string(REGEX REPLACE "\n# ?" "\n\n" EXAMPLE_FOOTER "\n${EXAMPLE_FOOTER}")
|
||||
string(STRIP "${EXAMPLE_FOOTER}" EXAMPLE_FOOTER)
|
||||
|
||||
# Extract toml body
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
_site/
|
||||
.jekyll-metadata
|
||||
assets/
|
||||
|
||||
@@ -96,6 +96,8 @@ packages = ["fmt", "zlib"]
|
||||
|
||||
The vcpkg `version` will automatically generate the `url` from the [official repository](https://github.com/microsoft/vcpkg/releases). For a custom registry you can specify your own `url` (and omit the `version`). You can browse available packages on [vcpkg.io](https://vcpkg.io/en/packages.html).
|
||||
|
||||
To specify package features you can use the following syntax: `imgui[docking-experimental,freetype,sdl2-binding,opengl3-binding]`.
|
||||
|
||||
## Packages
|
||||
|
||||
```toml
|
||||
|
||||
@@ -33,4 +33,6 @@ link-libraries = ["fmt::fmt"]
|
||||
|
||||
The bootstrapping of vcpkg is fully automated and no user interaction is necessary. You can disable vcpkg by setting `CMKR_DISABLE_VCPKG=ON`.
|
||||
|
||||
To specify package features you can use the following syntax: `imgui[docking-experimental,freetype,sdl2-binding,opengl3-binding]`.
|
||||
|
||||
<sup><sub>This page was automatically generated from [tests/vcpkg/cmake.toml](https://github.com/build-cpp/cmkr/tree/main/tests/vcpkg/cmake.toml).</sub></sup>
|
||||
|
||||
@@ -33,7 +33,13 @@ struct Package {
|
||||
struct Vcpkg {
|
||||
std::string version;
|
||||
std::string url;
|
||||
std::vector<std::string> packages;
|
||||
|
||||
struct Package {
|
||||
std::string name;
|
||||
std::vector<std::string> features;
|
||||
};
|
||||
|
||||
std::vector<Package> packages;
|
||||
};
|
||||
|
||||
enum TargetType {
|
||||
|
||||
+55
-34
@@ -541,6 +541,35 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
ss << "\")\n\n";
|
||||
}
|
||||
|
||||
if (!project.options.empty()) {
|
||||
comment("Options");
|
||||
for (const auto &opt : project.options) {
|
||||
cmd("option")(opt.name, opt.comment, opt.val ? "ON" : "OFF");
|
||||
}
|
||||
endl();
|
||||
}
|
||||
|
||||
if (!project.settings.empty()) {
|
||||
comment("Settings");
|
||||
for (const auto &set : project.settings) {
|
||||
std::string set_val;
|
||||
if (set.val.index() == 1) {
|
||||
set_val = mpark::get<1>(set.val);
|
||||
} else {
|
||||
set_val = mpark::get<0>(set.val) ? "ON" : "OFF";
|
||||
}
|
||||
|
||||
if (set.cache) {
|
||||
auto typ = set.val.index() == 1 ? "STRING" : "BOOL";
|
||||
auto force = set.force ? "FORCE" : "";
|
||||
cmd("set")(set.name, set_val, typ, set.comment, force);
|
||||
} else {
|
||||
cmd("set")(set.name, set_val);
|
||||
}
|
||||
}
|
||||
endl();
|
||||
}
|
||||
|
||||
gen.handle_condition(project.include_before, [&](const std::string &, const std::vector<std::string> &includes) { inject_includes(includes); });
|
||||
gen.handle_condition(project.cmake_before, [&](const std::string &, const std::string &cmake) { inject_cmake(cmake); });
|
||||
|
||||
@@ -579,8 +608,8 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
|
||||
// Show a nicer error than vcpkg when specifying an invalid package name
|
||||
for (const auto &package : project.vcpkg.packages) {
|
||||
if (!vcpkg_valid_identifier(package)) {
|
||||
throw std::runtime_error("Invalid [vcpkg].packages name '" + package + "' (needs to be lowercase alphanumeric)");
|
||||
if (!vcpkg_valid_identifier(package.name)) {
|
||||
throw std::runtime_error("Invalid [vcpkg].packages name '" + package.name + "' (needs to be lowercase alphanumeric)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,10 +640,31 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
const auto &packages = project.vcpkg.packages;
|
||||
for (size_t i = 0; i < packages.size(); i++) {
|
||||
const auto &package = packages[i];
|
||||
if (!vcpkg_valid_identifier(package)) {
|
||||
throw std::runtime_error("Invalid vcpkg package name '" + package + "'");
|
||||
const auto &features = package.features;
|
||||
if (!vcpkg_valid_identifier(package.name)) {
|
||||
throw std::runtime_error("Invalid vcpkg package name '" + package.name + "'");
|
||||
}
|
||||
for (const auto &feature : features) {
|
||||
if (!vcpkg_valid_identifier(feature)) {
|
||||
throw std::runtime_error("Invalid vcpkg package feature '" + feature + "'");
|
||||
}
|
||||
}
|
||||
if (features.empty()) {
|
||||
ofs << " \"" << package.name << '\"';
|
||||
} else {
|
||||
ofs << " {\n";
|
||||
ofs << " \"name\": \"" << package.name << "\",\n";
|
||||
ofs << " \"features\": [";
|
||||
for (size_t j = 0; j < features.size(); j++) {
|
||||
const auto &feature = features[j];
|
||||
ofs << '\"' << feature << '\"';
|
||||
if (j + 1 < features.size()) {
|
||||
ofs << ',';
|
||||
}
|
||||
}
|
||||
ofs << "]\n";
|
||||
ofs << " }";
|
||||
}
|
||||
ofs << " \"" << package << '\"';
|
||||
if (i + 1 < packages.size()) {
|
||||
ofs << ',';
|
||||
}
|
||||
@@ -652,35 +702,6 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!project.options.empty()) {
|
||||
comment("Options");
|
||||
for (const auto &opt : project.options) {
|
||||
cmd("option")(opt.name, opt.comment, opt.val ? "ON" : "OFF");
|
||||
}
|
||||
endl();
|
||||
}
|
||||
|
||||
if (!project.settings.empty()) {
|
||||
comment("Settings");
|
||||
for (const auto &set : project.settings) {
|
||||
std::string set_val;
|
||||
if (set.val.index() == 1) {
|
||||
set_val = mpark::get<1>(set.val);
|
||||
} else {
|
||||
set_val = mpark::get<0>(set.val) ? "ON" : "OFF";
|
||||
}
|
||||
|
||||
if (set.cache) {
|
||||
auto typ = set.val.index() == 1 ? "STRING" : "BOOL";
|
||||
auto force = set.force ? "FORCE" : "";
|
||||
cmd("set")(set.name, set_val, typ, set.comment, force);
|
||||
} else {
|
||||
cmd("set")(set.name, set_val);
|
||||
}
|
||||
}
|
||||
endl();
|
||||
}
|
||||
|
||||
auto add_subdir = [&](const std::string &dir) {
|
||||
// clang-format off
|
||||
comment(dir);
|
||||
|
||||
+20
-1
@@ -495,7 +495,26 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
||||
auto &v = checker.create(toml, "vcpkg");
|
||||
v.optional("url", vcpkg.url);
|
||||
v.optional("version", vcpkg.version);
|
||||
v.required("packages", vcpkg.packages);
|
||||
for (const auto &p : v.find("packages").as_array()) {
|
||||
Vcpkg::Package package;
|
||||
const auto &package_str = p.as_string().str;
|
||||
const auto open_bracket = package_str.find('[');
|
||||
const auto close_bracket = package_str.find(']', open_bracket);
|
||||
if (open_bracket == std::string::npos && close_bracket == std::string::npos) {
|
||||
package.name = package_str;
|
||||
} else if (close_bracket != std::string::npos) {
|
||||
package.name = package_str.substr(0, open_bracket);
|
||||
const auto features = package_str.substr(open_bracket + 1, close_bracket - open_bracket - 1);
|
||||
std::istringstream feature_stream{features};
|
||||
std::string feature;
|
||||
while (std::getline(feature_stream, feature, ',')) {
|
||||
package.features.emplace_back(feature);
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error("Invalid vcpkg package '" + package_str + "'");
|
||||
}
|
||||
vcpkg.packages.emplace_back(std::move(package));
|
||||
}
|
||||
}
|
||||
|
||||
checker.check(conditions);
|
||||
|
||||
@@ -18,4 +18,5 @@ type = "executable"
|
||||
sources = ["src/main.cpp"]
|
||||
link-libraries = ["fmt::fmt"]
|
||||
|
||||
# The bootstrapping of vcpkg is fully automated and no user interaction is necessary. You can disable vcpkg by setting `CMKR_DISABLE_VCPKG=ON`.
|
||||
# The bootstrapping of vcpkg is fully automated and no user interaction is necessary. You can disable vcpkg by setting `CMKR_DISABLE_VCPKG=ON`.
|
||||
# To specify package features you can use the following syntax: `imgui[docking-experimental,freetype,sdl2-binding,opengl3-binding]`.
|
||||
Reference in New Issue
Block a user