mirror of
https://github.com/build-cpp/cmkr
synced 2026-06-08 13:22:55 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b1d33395e | |||
| 240fafc102 | |||
| 7a7ddf2699 | |||
| 605a04e72d | |||
| fd7f078127 | |||
| ee0e0d71d9 | |||
| 9d6897b572 | |||
| f8c34e5545 | |||
| e6d783ea20 | |||
| ee7fe38a7b | |||
| 66b2aad843 | |||
| d2e376080a | |||
| 634908c651 | |||
| 33911f3f1b | |||
| e650073bef | |||
| 96e44f7771 | |||
| cb9ad5cdb3 | |||
| c785b540d3 | |||
| 275b73eefa |
+1
-1
@@ -72,7 +72,7 @@ PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
|
||||
@@ -10,13 +10,20 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2019, macos-10.15, ubuntu-20.04]
|
||||
os: [windows-2022, macos-11, ubuntu-20.04]
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
BUILD_TYPE: 'Release'
|
||||
CMAKE_GENERATOR: 'Ninja'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@6263846cf3c17009dfc81604efabae16044fc074 # master
|
||||
|
||||
- name: Visual Studio Development Environment
|
||||
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
|
||||
|
||||
- name: Tag cmkr.cmake
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
run: cmake -P "cmake/replace_tag.cmake"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
name: lint
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: clang-format
|
||||
id: clang-format
|
||||
uses: DoozyX/clang-format-lint-action@c3b2c943e924028b93a707a5b1b017976ab8d50c # v0.15
|
||||
with:
|
||||
exclude: './third_party'
|
||||
extensions: 'c,h,cpp,hpp'
|
||||
clangFormatVersion: 15
|
||||
style: file
|
||||
|
||||
- name: clang-format instructions
|
||||
if: ${{ failure() && steps.clang-format.outcome == 'failure' }}
|
||||
run: |
|
||||
# Instructions for fixing the formatting errors
|
||||
echo -e "\n\033[0;31mTo fix the formatting, run:\nclang-format -style=file -i \$(git ls-files \"*.c\" \"*.h\" \"*.cpp\" \"*.hpp\")\033[0m\n"
|
||||
exit 1
|
||||
+2
-1
@@ -9,4 +9,5 @@ build*/
|
||||
.idea/
|
||||
cmake-build*/
|
||||
CMakeLists.txt.user
|
||||
.vscode/
|
||||
.vscode/
|
||||
.DS_Store
|
||||
Generated
+1
-3
@@ -22,7 +22,7 @@ project(cmkr
|
||||
LANGUAGES
|
||||
CXX
|
||||
VERSION
|
||||
0.2.20
|
||||
0.2.23
|
||||
DESCRIPTION
|
||||
"CMakeLists generator from TOML"
|
||||
)
|
||||
@@ -61,14 +61,12 @@ set(cmkr_SOURCES
|
||||
"src/arguments.cpp"
|
||||
"src/build.cpp"
|
||||
"src/cmake_generator.cpp"
|
||||
"src/error.cpp"
|
||||
"src/help.cpp"
|
||||
"src/main.cpp"
|
||||
"src/project_parser.cpp"
|
||||
"include/arguments.hpp"
|
||||
"include/build.hpp"
|
||||
"include/cmake_generator.hpp"
|
||||
"include/error.hpp"
|
||||
"include/fs.hpp"
|
||||
"include/help.hpp"
|
||||
"include/literals.hpp"
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ cmkr-include = false
|
||||
|
||||
[project]
|
||||
name = "cmkr"
|
||||
version = "0.2.20"
|
||||
version = "0.2.23"
|
||||
description = "CMakeLists generator from TOML"
|
||||
languages = ["CXX"]
|
||||
include-after = [
|
||||
|
||||
+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.20" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
|
||||
set(CMKR_TAG "v0.2.23" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
|
||||
set(CMKR_COMMIT_HASH "" CACHE STRING "cmkr git commit hash (optional)" FORCE)
|
||||
|
||||
# To bootstrap/generate a cmkr project: cmake -P cmkr.cmake
|
||||
|
||||
@@ -212,6 +212,29 @@ CXX_STANDARD_REQUIRED = true
|
||||
FOLDER = "MyFolder"
|
||||
```
|
||||
|
||||
## Templates
|
||||
|
||||
To avoid repeating yourself you can create your own target type and use it in your targets:
|
||||
|
||||
```toml
|
||||
[template.example]
|
||||
condition = "MYPROJECT_BUILD_EXAMPLES"
|
||||
type = "executable"
|
||||
link-libraries = ["myproject::mylib"]
|
||||
add-function = ""
|
||||
pass-sources = false
|
||||
|
||||
# Properties from the template are merged with the ones here
|
||||
[target.myexample]
|
||||
type = "example"
|
||||
sources = ["src/myexample.cpp"]
|
||||
```
|
||||
|
||||
The properties declared on a `template` are the same as the ones you use for targets. The only exceptions are:
|
||||
|
||||
- `add-function`: Specifies a custom add function. Projects like [pybind11](https://pybind11.readthedocs.io/en/stable/cmake/index.html#new-findpython-mode) have their own `add_xxx` function, which you can specify here.
|
||||
- `pass-sources`: Pass sources directly to the add function instead of using `target_sources`.
|
||||
|
||||
## Tests and installation (unfinished)
|
||||
|
||||
**Note**: The `[[test]]` and `[[install]]` are unfinished features and will likely change in a future release.
|
||||
|
||||
@@ -11,9 +11,3 @@ int install();
|
||||
|
||||
} // namespace build
|
||||
} // namespace cmkr
|
||||
|
||||
int cmkr_build_run(int argc, char **argv);
|
||||
|
||||
int cmkr_build_clean();
|
||||
|
||||
int cmkr_build_install();
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace cmkr {
|
||||
namespace error {
|
||||
|
||||
struct Status {
|
||||
enum class Code {
|
||||
Success = 0,
|
||||
RuntimeError,
|
||||
InitError,
|
||||
GenerationError,
|
||||
BuildError,
|
||||
CleanError,
|
||||
InstallError,
|
||||
};
|
||||
Status(Code ec) noexcept;
|
||||
operator int() const noexcept;
|
||||
Code code() const noexcept;
|
||||
|
||||
private:
|
||||
Code ec_ = Code::Success;
|
||||
};
|
||||
|
||||
} // namespace error
|
||||
} // namespace cmkr
|
||||
|
||||
const char *cmkr_error_status_string(int);
|
||||
+1
-3
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || \
|
||||
(defined(__cplusplus) && __cplusplus >= 201703L)) && \
|
||||
defined(__has_include)
|
||||
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
|
||||
@@ -9,7 +9,3 @@ const char *message() noexcept;
|
||||
|
||||
} // namespace help
|
||||
} // namespace cmkr
|
||||
|
||||
const char *cmkr_help_version(void);
|
||||
|
||||
const char *cmkr_help_message(void);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <mpark/variant.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <mpark/variant.hpp>
|
||||
#include <tsl/ordered_map.h>
|
||||
#include <tsl/ordered_set.h>
|
||||
#include <vector>
|
||||
|
||||
namespace cmkr {
|
||||
namespace parser {
|
||||
@@ -47,6 +48,10 @@ struct Vcpkg {
|
||||
};
|
||||
|
||||
std::vector<Package> packages;
|
||||
|
||||
bool enabled() const {
|
||||
return !packages.empty();
|
||||
}
|
||||
};
|
||||
|
||||
enum TargetType {
|
||||
|
||||
+1
-3
@@ -2,10 +2,8 @@
|
||||
#include "build.hpp"
|
||||
#include "cmake_generator.hpp"
|
||||
#include "help.hpp"
|
||||
|
||||
#include "fs.hpp"
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
+4
-38
@@ -1,14 +1,10 @@
|
||||
#include "build.hpp"
|
||||
#include "cmake_generator.hpp"
|
||||
#include "error.hpp"
|
||||
#include "project_parser.hpp"
|
||||
|
||||
#include "fs.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <system_error>
|
||||
|
||||
namespace cmkr {
|
||||
namespace build {
|
||||
@@ -17,7 +13,7 @@ int run(int argc, char **argv) {
|
||||
parser::Project project(nullptr, ".", true);
|
||||
if (argc > 2) {
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
project.build_args.push_back(argv[i]);
|
||||
project.build_args.emplace_back(argv[i]);
|
||||
}
|
||||
}
|
||||
std::stringstream ss;
|
||||
@@ -48,13 +44,13 @@ int run(int argc, char **argv) {
|
||||
}
|
||||
|
||||
int clean() {
|
||||
bool ret = false;
|
||||
bool success = false;
|
||||
parser::Project project(nullptr, ".", true);
|
||||
if (fs::exists(project.build_dir)) {
|
||||
ret = fs::remove_all(project.build_dir);
|
||||
success = fs::remove_all(project.build_dir);
|
||||
fs::create_directory(project.build_dir);
|
||||
}
|
||||
return !ret;
|
||||
return success ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int install() {
|
||||
@@ -64,33 +60,3 @@ int install() {
|
||||
}
|
||||
} // namespace build
|
||||
} // namespace cmkr
|
||||
|
||||
int cmkr_build_run(int argc, char **argv) {
|
||||
try {
|
||||
return cmkr::build::run(argc, argv);
|
||||
} catch (const std::system_error &e) {
|
||||
return e.code().value();
|
||||
} catch (...) {
|
||||
return cmkr::error::Status(cmkr::error::Status::Code::BuildError);
|
||||
}
|
||||
}
|
||||
|
||||
int cmkr_build_clean(void) {
|
||||
try {
|
||||
return cmkr::build::clean();
|
||||
} catch (const std::system_error &e) {
|
||||
return e.code().value();
|
||||
} catch (...) {
|
||||
return cmkr::error::Status(cmkr::error::Status::Code::CleanError);
|
||||
}
|
||||
}
|
||||
|
||||
int cmkr_build_install(void) {
|
||||
try {
|
||||
return cmkr::build::install();
|
||||
} catch (const std::system_error &e) {
|
||||
return e.code().value();
|
||||
} catch (...) {
|
||||
return cmkr::error::Status(cmkr::error::Status::Code::InstallError);
|
||||
}
|
||||
}
|
||||
|
||||
+72
-31
@@ -1,15 +1,14 @@
|
||||
#include "cmake_generator.hpp"
|
||||
#include "error.hpp"
|
||||
#include "literals.hpp"
|
||||
#include <resources/cmkr.hpp>
|
||||
|
||||
#include "fs.hpp"
|
||||
#include "project_parser.hpp"
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
|
||||
namespace cmkr {
|
||||
namespace gen {
|
||||
@@ -43,7 +42,7 @@ static tsl::ordered_map<std::string, std::vector<std::string>> known_languages =
|
||||
{"Swift", {".swift"}},
|
||||
};
|
||||
|
||||
static std::string format(const char *format, tsl::ordered_map<std::string, std::string> variables) {
|
||||
static std::string format(const char *format, const tsl::ordered_map<std::string, std::string> &variables) {
|
||||
std::string s = format;
|
||||
for (const auto &itr : variables) {
|
||||
size_t start_pos = 0;
|
||||
@@ -170,7 +169,6 @@ static void generate_gitfile(const char *gitfile, const std::vector<std::string>
|
||||
auto flush_line = [&line, &lines]() {
|
||||
auto itr = std::find(lines.begin(), lines.end(), line);
|
||||
if (itr != lines.end()) {
|
||||
printf("erase:%s\n", line.c_str());
|
||||
lines.erase(itr);
|
||||
}
|
||||
line.clear();
|
||||
@@ -210,6 +208,9 @@ void generate_project(const std::string &type) {
|
||||
throw std::runtime_error("Cannot initialize a project when cmake.toml already exists!");
|
||||
}
|
||||
|
||||
// Check if the folder is empty before creating any files
|
||||
auto is_empty = fs::is_empty(fs::current_path());
|
||||
|
||||
// Automatically generate .gitattributes to not skew the statistics of the repo
|
||||
generate_gitfile(".gitattributes", {"/**/CMakeLists.txt linguist-generated", "/**/cmkr.cmake linguist-vendored"});
|
||||
|
||||
@@ -221,7 +222,7 @@ void generate_project(const std::string &type) {
|
||||
{"@type", type},
|
||||
};
|
||||
|
||||
if (!fs::is_empty(fs::current_path())) {
|
||||
if (!is_empty) {
|
||||
// Make a backup of an existing CMakeLists.txt if it exists
|
||||
std::error_code ec;
|
||||
fs::rename("CMakeLists.txt", "CMakeLists.txt.bak", ec);
|
||||
@@ -247,7 +248,7 @@ void generate_project(const std::string &type) {
|
||||
|
||||
struct CommandEndl {
|
||||
std::stringstream &ss;
|
||||
CommandEndl(std::stringstream &ss) : ss(ss) {
|
||||
explicit CommandEndl(std::stringstream &ss) : ss(ss) {
|
||||
}
|
||||
void endl() {
|
||||
ss << '\n';
|
||||
@@ -256,7 +257,7 @@ struct CommandEndl {
|
||||
|
||||
struct RawArg {
|
||||
RawArg() = default;
|
||||
RawArg(std::string arg) : arg(std::move(arg)) {
|
||||
explicit RawArg(std::string arg) : arg(std::move(arg)) {
|
||||
}
|
||||
|
||||
std::string arg;
|
||||
@@ -291,7 +292,7 @@ struct Command {
|
||||
// https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#unquoted-argument
|
||||
// NOTE: Normally '/' does not require quoting according to the documentation but this has been the case here
|
||||
// previously, so for backwards compatibility its still here.
|
||||
if (str.find_first_of("()#\"\\'> |/;") == str.npos)
|
||||
if (str.find_first_of("()#\"\\'> |/;") == std::string::npos)
|
||||
return str;
|
||||
std::string result;
|
||||
result += "\"";
|
||||
@@ -440,14 +441,15 @@ static std::string tolf(const std::string &str) {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
struct Generator {
|
||||
Generator(const parser::Project &project) : project(project) {
|
||||
Generator(const parser::Project &project, fs::path path) : project(project), path(std::move(path)) {
|
||||
}
|
||||
Generator(const Generator &) = delete;
|
||||
|
||||
const parser::Project &project;
|
||||
fs::path path;
|
||||
std::stringstream ss;
|
||||
int indent = 0;
|
||||
|
||||
@@ -477,8 +479,8 @@ struct Generator {
|
||||
void inject_includes(const std::vector<std::string> &includes) {
|
||||
if (!includes.empty()) {
|
||||
for (const auto &file : includes) {
|
||||
if (!fs::is_regular_file(file)) {
|
||||
throw std::runtime_error("Include '" + file + "' does not exist");
|
||||
if (!fs::exists(path / file)) {
|
||||
throw std::runtime_error("Include not found: " + file);
|
||||
}
|
||||
cmd("include")(file);
|
||||
}
|
||||
@@ -618,14 +620,14 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
for (auto const &lang : project.project_languages) {
|
||||
if (known_languages.find(lang) == known_languages.end()) {
|
||||
if (project.project_allow_unknown_languages) {
|
||||
printf("Unknown language '%s' specified\n", lang.c_str());
|
||||
printf("[warning] Unknown language '%s' specified\n", lang.c_str());
|
||||
} else {
|
||||
throw std::runtime_error("Unknown language '" + lang + "' specified");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generator gen(project);
|
||||
Generator gen(project, path);
|
||||
|
||||
// Helper lambdas for more convenient CMake generation
|
||||
auto &ss = gen.ss;
|
||||
@@ -783,7 +785,11 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
gen.conditional_includes(project.include_after);
|
||||
gen.conditional_cmake(project.cmake_after);
|
||||
|
||||
if (!project.vcpkg.packages.empty()) {
|
||||
if (project.vcpkg.enabled()) {
|
||||
if (!is_root_project) {
|
||||
throw std::runtime_error("[vcpkg] is only supported in the root project");
|
||||
}
|
||||
|
||||
// Allow the user to specify a url or derive it from the version
|
||||
auto url = project.vcpkg.url;
|
||||
auto version_name = url;
|
||||
@@ -796,7 +802,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) {
|
||||
const auto &packages = project.vcpkg.packages;
|
||||
for (const auto &package : packages) {
|
||||
if (!vcpkg_valid_identifier(package.name)) {
|
||||
throw std::runtime_error("Invalid [vcpkg].packages name '" + package.name + "' (needs to be lowercase alphanumeric)");
|
||||
}
|
||||
@@ -806,14 +813,20 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
// clang-format off
|
||||
cmd("if")("CMKR_ROOT_PROJECT", "AND", "NOT", "CMKR_DISABLE_VCPKG");
|
||||
cmd("include")("FetchContent");
|
||||
cmd("message")("STATUS", "Fetching vcpkg (" + version_name + ")...");
|
||||
cmd("FetchContent_Declare")("vcpkg", "URL", url);
|
||||
// Not using FetchContent_MakeAvailable here in case vcpkg adds CMakeLists.txt
|
||||
cmd("FetchContent_GetProperties")("vcpkg");
|
||||
cmd("if")("NOT", "vcpkg_POPULATED");
|
||||
cmd("FetchContent_Populate")("vcpkg");
|
||||
cmd("include")("${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake");
|
||||
comment("Fix warnings about DOWNLOAD_EXTRACT_TIMESTAMP");
|
||||
// clang-format off
|
||||
cmd("if")("POLICY", "CMP0135");
|
||||
cmd("cmake_policy")("SET", "CMP0135", "NEW");
|
||||
cmd("endif")();
|
||||
// clang-format on
|
||||
cmd("message")("STATUS", "Fetching vcpkg (" + version_name + ")...");
|
||||
cmd("FetchContent_Declare")("vcpkg", "URL", url);
|
||||
// Not using FetchContent_MakeAvailable here in case vcpkg adds CMakeLists.txt
|
||||
cmd("FetchContent_GetProperties")("vcpkg");
|
||||
cmd("if")("NOT", "vcpkg_POPULATED");
|
||||
cmd("FetchContent_Populate")("vcpkg");
|
||||
cmd("include")("${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake");
|
||||
cmd("endif")();
|
||||
cmd("endif")();
|
||||
endl();
|
||||
// clang-format on
|
||||
@@ -830,7 +843,6 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
"dependencies": [
|
||||
)";
|
||||
|
||||
const auto &packages = project.vcpkg.packages;
|
||||
for (size_t i = 0; i < packages.size(); i++) {
|
||||
const auto &package = packages[i];
|
||||
const auto &features = package.features;
|
||||
@@ -884,13 +896,21 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
|
||||
if (!project.contents.empty()) {
|
||||
cmd("include")("FetchContent").endl();
|
||||
if (!project.root()->vcpkg.enabled()) {
|
||||
comment("Fix warnings about DOWNLOAD_EXTRACT_TIMESTAMP");
|
||||
// clang-format off
|
||||
cmd("if")("POLICY", "CMP0135");
|
||||
cmd("cmake_policy")("SET", "CMP0135", "NEW");
|
||||
cmd("endif")();
|
||||
// clang-format on
|
||||
}
|
||||
for (const auto &content : project.contents) {
|
||||
ConditionScope cs(gen, content.condition);
|
||||
|
||||
gen.conditional_includes(content.include_before);
|
||||
gen.conditional_cmake(content.cmake_before);
|
||||
|
||||
std::string version_info = "";
|
||||
std::string version_info;
|
||||
if (content.arguments.contains("GIT_TAG")) {
|
||||
version_info = " (" + content.arguments.at("GIT_TAG") + ")";
|
||||
} else if (content.arguments.contains("SVN_REVISION")) {
|
||||
@@ -987,6 +1007,9 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
auto project_root = project.root();
|
||||
for (size_t i = 0; i < project.targets.size(); i++) {
|
||||
const auto &target = project.targets[i];
|
||||
|
||||
auto throw_target_error = [&target](const std::string &message) { throw std::runtime_error("[target." + target.name + "] " + message); };
|
||||
|
||||
const parser::Template *tmplate = nullptr;
|
||||
std::unique_ptr<ConditionScope> tmplate_cs{};
|
||||
|
||||
@@ -1090,7 +1113,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
auto sources = expand_cmake_paths(condition_sources, path, is_root_project);
|
||||
if (sources.empty()) {
|
||||
auto source_key = condition.empty() ? "sources" : (condition + ".sources");
|
||||
throw std::runtime_error(target.name + " " + source_key + " wildcard found 0 files");
|
||||
throw_target_error(source_key + " wildcard found 0 files");
|
||||
}
|
||||
|
||||
// Make sure there are source files for the languages used by the project
|
||||
@@ -1101,7 +1124,25 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
case parser::target_static:
|
||||
case parser::target_object:
|
||||
if (!contains_language_source(sources)) {
|
||||
throw std::runtime_error("There were no source files linked within the target " + target.name);
|
||||
std::string extensions;
|
||||
for (const auto &language : project_extensions) {
|
||||
if (!extensions.empty()) {
|
||||
extensions += " ";
|
||||
}
|
||||
extensions += language;
|
||||
}
|
||||
throw_target_error("No sources found with valid extensions (" + extensions + ")");
|
||||
}
|
||||
|
||||
// Make sure relative source files exist
|
||||
for (const auto &source : sources) {
|
||||
auto var_index = source.find("${");
|
||||
if (var_index != std::string::npos)
|
||||
continue;
|
||||
const auto &source_path = fs::path(path) / source;
|
||||
if (!fs::exists(source_path)) {
|
||||
throw_target_error("Source file not found: " + source);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1111,7 +1152,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
if (sources_with_set) {
|
||||
// This is a sanity check to make sure the unconditional sources are first
|
||||
if (!condition.empty()) {
|
||||
throw std::runtime_error("Unreachable code, make sure unconditional sources are first");
|
||||
throw_target_error("Unreachable code, make sure unconditional sources are first");
|
||||
}
|
||||
cmd("set")(sources_var, sources);
|
||||
sources_with_set = false;
|
||||
@@ -1124,7 +1165,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
|
||||
if (tmplate != nullptr) {
|
||||
if (target_type != parser::target_template) {
|
||||
throw std::runtime_error("Unreachable code, unexpected target type for template");
|
||||
throw_target_error("Unreachable code, unexpected target type for template");
|
||||
}
|
||||
target_type = tmplate->outline.type;
|
||||
}
|
||||
@@ -1172,7 +1213,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
target_scope = "PUBLIC";
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unimplemented enum value");
|
||||
throw_target_error("Unimplemented enum value");
|
||||
}
|
||||
|
||||
// Handle custom add commands from templates.
|
||||
@@ -1253,7 +1294,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
||||
for (const auto &propItr : properties) {
|
||||
if (propItr.first == "MSVC_RUNTIME_LIBRARY") {
|
||||
if (project_root->project_msvc_runtime == parser::msvc_last) {
|
||||
throw std::runtime_error("You cannot set [target].msvc-runtime without setting the root [project].msvc-runtime");
|
||||
throw_target_error("You cannot set msvc-runtime without setting the root [project].msvc-runtime");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "error.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
namespace cmkr {
|
||||
namespace error {
|
||||
|
||||
Status::Status(Code ec) noexcept : ec_(ec) {
|
||||
}
|
||||
|
||||
Status::operator int() const noexcept {
|
||||
return static_cast<int>(ec_);
|
||||
}
|
||||
|
||||
Status::Code Status::code() const noexcept {
|
||||
return ec_;
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace cmkr
|
||||
|
||||
// strings for cmkr::error::Status::Code
|
||||
static const char *err_string[] = {
|
||||
"Success", "Runtime error", "Initialization error", "CMake generation error", "Build error", "Clean error", "Install error",
|
||||
};
|
||||
|
||||
const char *cmkr_error_status(int i) {
|
||||
assert(i >= 0 && static_cast<size_t>(i) < (sizeof(err_string) / sizeof(*(err_string))));
|
||||
return err_string[i];
|
||||
}
|
||||
@@ -23,11 +23,3 @@ arguments:
|
||||
}
|
||||
} // namespace help
|
||||
} // namespace cmkr
|
||||
|
||||
const char *cmkr_help_version(void) {
|
||||
return cmkr::help::version();
|
||||
}
|
||||
|
||||
const char *cmkr_help_message(void) {
|
||||
return cmkr::help::message();
|
||||
}
|
||||
@@ -36,7 +36,7 @@ static std::string format_key_message(const std::string &message, const toml::ke
|
||||
auto loc = value.location();
|
||||
auto line_number_str = std::to_string(loc.line());
|
||||
auto line_width = line_number_str.length();
|
||||
auto line_str = loc.line_str();
|
||||
const auto &line_str = loc.line_str();
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << message << "\n";
|
||||
@@ -73,7 +73,7 @@ class TomlChecker {
|
||||
public:
|
||||
TomlChecker(const TomlBasicValue &v, const toml::key &ky) : m_v(toml::find(v, ky)) {
|
||||
}
|
||||
TomlChecker(const TomlBasicValue &v) : m_v(v) {
|
||||
explicit TomlChecker(const TomlBasicValue &v) : m_v(v) {
|
||||
}
|
||||
TomlChecker(const TomlChecker &) = delete;
|
||||
TomlChecker(TomlChecker &&) = delete;
|
||||
@@ -175,7 +175,7 @@ class TomlCheckerRoot {
|
||||
bool m_checked = false;
|
||||
|
||||
public:
|
||||
TomlCheckerRoot(const TomlBasicValue &root) : m_root(root) {
|
||||
explicit TomlCheckerRoot(const TomlBasicValue &root) : m_root(root) {
|
||||
}
|
||||
TomlCheckerRoot(const TomlCheckerRoot &) = delete;
|
||||
TomlCheckerRoot(TomlCheckerRoot &&) = delete;
|
||||
|
||||
+1
-1
@@ -51,4 +51,4 @@ condition = "msvc"
|
||||
name = "msvc-runtime"
|
||||
working-directory = "msvc-runtime"
|
||||
command = "$<TARGET_FILE:cmkr>"
|
||||
arguments = ["build"]
|
||||
arguments = ["build"]
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
int main() { }
|
||||
int main() {
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <Windows.h>
|
||||
|
||||
void foo() { }
|
||||
void foo() {
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
#include <cstdio>
|
||||
#include <tuple>
|
||||
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
auto tpl = std::make_tuple(1, 2);
|
||||
printf("Hello from C++11 %d\n", std::get<0>(tpl));
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <fmt/core.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
fmt::print("Hello, world!\n");
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mylib
|
||||
{
|
||||
namespace mylib {
|
||||
std::string message();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <mylib/mylib.hpp>
|
||||
|
||||
std::string mylib::message()
|
||||
{
|
||||
std::string mylib::message() {
|
||||
return "cmkr is awesome!";
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
namespace mylib
|
||||
{
|
||||
static const char* version() { return "v1.0"; }
|
||||
namespace mylib {
|
||||
static const char *version() {
|
||||
return "v1.0";
|
||||
}
|
||||
} // namespace mylib
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "mylib/mylib.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
printf("mylib version: %s\n", mylib::version());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <fmt/core.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
fmt::print("Hello, world!\n");
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
# Disable clang-format in this folder
|
||||
DisableFormat: true
|
||||
SortIncludes: Never
|
||||
Reference in New Issue
Block a user