mirror of
https://github.com/build-cpp/cmkr
synced 2026-06-08 13:22:55 +00:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 109c4bc99f | |||
| cad85f0bb1 | |||
| 53c88ceafa | |||
| d2aa15b1c7 | |||
| e6ded077cf | |||
| 3615ccab94 | |||
| 73622aa5ba | |||
| 69d844a152 | |||
| af9a117f50 | |||
| 5fe8220728 | |||
| 28f541cd3c | |||
| 2f3fd7b95e | |||
| 07d99c582d | |||
| 5af2385cc3 | |||
| 981c48dbc5 | |||
| 153bdbe591 | |||
| 97f1c5c1cc | |||
| 5b6d9c3826 | |||
| a90988b81a | |||
| 3a1298f4e8 | |||
| 534f955827 | |||
| ef537ce084 | |||
| 9cdd0f7344 | |||
| e69cf4d2b9 | |||
| e98a906231 | |||
| 9a82f8c796 | |||
| 13255c68cf | |||
| 5768460827 | |||
| 50d4a905b6 | |||
| f957cec2dc | |||
| 232e49e087 | |||
| 7408d42160 |
+1
-1
@@ -10,7 +10,7 @@ AlignTrailingComments: true
|
|||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
AllowShortBlocksOnASingleLine: false
|
AllowShortBlocksOnASingleLine: false
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: true
|
AllowShortFunctionsOnASingleLine: false
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
|||||||
Generated
+1
-1
@@ -25,7 +25,7 @@ project(cmkr
|
|||||||
LANGUAGES
|
LANGUAGES
|
||||||
CXX
|
CXX
|
||||||
VERSION
|
VERSION
|
||||||
0.2.12
|
0.2.16
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
"CMakeLists generator from TOML"
|
"CMakeLists generator from TOML"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -70,3 +70,4 @@ arguments:
|
|||||||
- https://github.com/mpark/variant
|
- https://github.com/mpark/variant
|
||||||
- https://www.svgrepo.com/svg/192268/hammer
|
- https://www.svgrepo.com/svg/192268/hammer
|
||||||
- https://github.com/can1357 for buying `cmkr.build` ❤️
|
- https://github.com/can1357 for buying `cmkr.build` ❤️
|
||||||
|
- https://github.com/JustasMasiulis for fixing the dark theme ❤️
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ cmkr-include = false
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "cmkr"
|
name = "cmkr"
|
||||||
version = "0.2.12"
|
version = "0.2.16"
|
||||||
description = "CMakeLists generator from TOML"
|
description = "CMakeLists generator from TOML"
|
||||||
languages = ["CXX"]
|
languages = ["CXX"]
|
||||||
subdirs = ["third_party", "tests"]
|
subdirs = ["third_party", "tests"]
|
||||||
|
|||||||
+22
-5
@@ -2,7 +2,7 @@ include_guard()
|
|||||||
|
|
||||||
# Change these defaults to point to your infrastructure if desired
|
# 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_REPO "https://github.com/build-cpp/cmkr" CACHE STRING "cmkr git repository" FORCE)
|
||||||
set(CMKR_TAG "v0.2.12" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
|
set(CMKR_TAG "v0.2.16" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
|
||||||
set(CMKR_COMMIT_HASH "" CACHE STRING "cmkr git commit hash (optional)" FORCE)
|
set(CMKR_COMMIT_HASH "" CACHE STRING "cmkr git commit hash (optional)" FORCE)
|
||||||
|
|
||||||
# To bootstrap/generate a cmkr project: cmake -P cmkr.cmake
|
# To bootstrap/generate a cmkr project: cmake -P cmkr.cmake
|
||||||
@@ -58,7 +58,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Use cached cmkr if found
|
# Use cached cmkr if found
|
||||||
if(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}")
|
if(DEFINED ENV{CMKR_CACHE})
|
||||||
set(CMKR_DIRECTORY_PREFIX "$ENV{CMKR_CACHE}")
|
set(CMKR_DIRECTORY_PREFIX "$ENV{CMKR_CACHE}")
|
||||||
string(REPLACE "\\" "/" CMKR_DIRECTORY_PREFIX "${CMKR_DIRECTORY_PREFIX}")
|
string(REPLACE "\\" "/" CMKR_DIRECTORY_PREFIX "${CMKR_DIRECTORY_PREFIX}")
|
||||||
if(NOT CMKR_DIRECTORY_PREFIX MATCHES "\\/$")
|
if(NOT CMKR_DIRECTORY_PREFIX MATCHES "\\/$")
|
||||||
@@ -72,10 +72,27 @@ endif()
|
|||||||
set(CMKR_DIRECTORY "${CMKR_DIRECTORY_PREFIX}${CMKR_TAG}")
|
set(CMKR_DIRECTORY "${CMKR_DIRECTORY_PREFIX}${CMKR_TAG}")
|
||||||
set(CMKR_CACHED_EXECUTABLE "${CMKR_DIRECTORY}/bin/${CMKR_EXECUTABLE_NAME}")
|
set(CMKR_CACHED_EXECUTABLE "${CMKR_DIRECTORY}/bin/${CMKR_EXECUTABLE_NAME}")
|
||||||
|
|
||||||
|
# Helper function to check if a string starts with a prefix
|
||||||
|
# Cannot use MATCHES, see: https://github.com/build-cpp/cmkr/issues/61
|
||||||
|
function(cmkr_startswith str prefix result)
|
||||||
|
string(LENGTH "${prefix}" prefix_length)
|
||||||
|
string(LENGTH "${str}" str_length)
|
||||||
|
if(prefix_length LESS_EQUAL str_length)
|
||||||
|
string(SUBSTRING "${str}" 0 ${prefix_length} str_prefix)
|
||||||
|
if(prefix STREQUAL str_prefix)
|
||||||
|
set("${result}" ON PARENT_SCOPE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
set("${result}" OFF PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# Handle upgrading logic
|
# Handle upgrading logic
|
||||||
if(CMKR_EXECUTABLE AND NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE)
|
if(CMKR_EXECUTABLE AND NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE)
|
||||||
if(CMKR_EXECUTABLE MATCHES "^${CMAKE_CURRENT_BINARY_DIR}/_cmkr")
|
cmkr_startswith("${CMKR_EXECUTABLE}" "${CMAKE_CURRENT_BINARY_DIR}/_cmkr" CMKR_STARTSWITH_BUILD)
|
||||||
if(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}")
|
cmkr_startswith("${CMKR_EXECUTABLE}" "${CMKR_DIRECTORY_PREFIX}" CMKR_STARTSWITH_CACHE)
|
||||||
|
if(CMKR_STARTSWITH_BUILD)
|
||||||
|
if(DEFINED ENV{CMKR_CACHE})
|
||||||
message(AUTHOR_WARNING "[cmkr] Switching to cached cmkr: '${CMKR_CACHED_EXECUTABLE}'")
|
message(AUTHOR_WARNING "[cmkr] Switching to cached cmkr: '${CMKR_CACHED_EXECUTABLE}'")
|
||||||
if(EXISTS "${CMKR_CACHED_EXECUTABLE}")
|
if(EXISTS "${CMKR_CACHED_EXECUTABLE}")
|
||||||
set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE)
|
set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE)
|
||||||
@@ -86,7 +103,7 @@ if(CMKR_EXECUTABLE AND NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE)
|
|||||||
message(AUTHOR_WARNING "[cmkr] Upgrading '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'")
|
message(AUTHOR_WARNING "[cmkr] Upgrading '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'")
|
||||||
unset(CMKR_EXECUTABLE CACHE)
|
unset(CMKR_EXECUTABLE CACHE)
|
||||||
endif()
|
endif()
|
||||||
elseif(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}" AND CMKR_EXECUTABLE MATCHES "^${CMKR_DIRECTORY_PREFIX}")
|
elseif(DEFINED ENV{CMKR_CACHE} AND CMKR_STARTSWITH_CACHE)
|
||||||
message(AUTHOR_WARNING "[cmkr] Upgrading cached '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'")
|
message(AUTHOR_WARNING "[cmkr] Upgrading cached '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'")
|
||||||
unset(CMKR_EXECUTABLE CACHE)
|
unset(CMKR_EXECUTABLE CACHE)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
option(CMKR_GENERATE_DOCUMENTATION "Generate cmkr documentation" ${CMKR_ROOT_PROJECT})
|
option(CMKR_GENERATE_DOCUMENTATION "Generate cmkr documentation" ${CMKR_ROOT_PROJECT})
|
||||||
set(CMKR_TESTS "" CACHE INTERNAL "List of test directories in the order declared in tests/cmake.toml")
|
|
||||||
|
|
||||||
if(CMKR_GENERATE_DOCUMENTATION)
|
|
||||||
# Hook the add_test function to capture the tests in the order declared in tests/cmake.toml
|
|
||||||
function(add_test)
|
|
||||||
cmake_parse_arguments(TEST "" "WORKING_DIRECTORY" "" ${ARGN})
|
|
||||||
get_filename_component(TEST_WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}" NAME)
|
|
||||||
list(APPEND CMKR_TESTS "${TEST_WORKING_DIRECTORY}")
|
|
||||||
set(CMKR_TESTS "${CMKR_TESTS}" CACHE INTERNAL "")
|
|
||||||
_add_test(${test} ${ARGN})
|
|
||||||
endfunction()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
function(generate_documentation)
|
function(generate_documentation)
|
||||||
if(CMKR_GENERATE_DOCUMENTATION)
|
if(CMKR_GENERATE_DOCUMENTATION)
|
||||||
message(STATUS "[cmkr] Generating documentation...")
|
message(STATUS "[cmkr] Generating documentation...")
|
||||||
|
|
||||||
|
# Extract the order of the tests
|
||||||
|
set(CMKR_TESTS "")
|
||||||
|
file(READ "${PROJECT_SOURCE_DIR}/tests/cmake.toml" tests_toml NO_HEX_CONVERSION)
|
||||||
|
string(REGEX MATCHALL "working-directory = \"([^\"]+)\"" tests_match "${tests_toml}")
|
||||||
|
foreach(match ${tests_match})
|
||||||
|
if(match MATCHES "working-directory = \"([^\"]+)\"")
|
||||||
|
list(APPEND CMKR_TESTS "${CMAKE_MATCH_1}")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "This should not happen (wrong regex?)")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
# Delete previously generated examples
|
# Delete previously generated examples
|
||||||
set(example_folder "${PROJECT_SOURCE_DIR}/docs/examples")
|
set(example_folder "${PROJECT_SOURCE_DIR}/docs/examples")
|
||||||
|
|||||||
+8
-2
@@ -27,6 +27,7 @@ name = "myproject"
|
|||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
description = "Description of the project"
|
description = "Description of the project"
|
||||||
languages = ["C", "CXX"]
|
languages = ["C", "CXX"]
|
||||||
|
msvc-runtime = "" # dynamic (implicit default), static
|
||||||
cmake-before = """
|
cmake-before = """
|
||||||
message(STATUS "CMake injected before the project() call")
|
message(STATUS "CMake injected before the project() call")
|
||||||
"""
|
"""
|
||||||
@@ -58,6 +59,8 @@ sources = ["src/main.cpp"]
|
|||||||
windows.sources = ["src/windows_specific.cpp"]
|
windows.sources = ["src/windows_specific.cpp"]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Predefined conditions
|
||||||
|
|
||||||
The following conditions are predefined (you can override them if you desire):
|
The following conditions are predefined (you can override them if you desire):
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
@@ -144,6 +147,7 @@ alias = "mytarget::mytarget"
|
|||||||
type = "static" # executable, shared (DLL), static, interface, object, library, custom
|
type = "static" # executable, shared (DLL), static, interface, object, library, custom
|
||||||
headers = ["src/mytarget.h"]
|
headers = ["src/mytarget.h"]
|
||||||
sources = ["src/mytarget.cpp"]
|
sources = ["src/mytarget.cpp"]
|
||||||
|
msvc-runtime = "" # dynamic (implicit default), static
|
||||||
|
|
||||||
# The keys below match the target_xxx CMake commands
|
# The keys below match the target_xxx CMake commands
|
||||||
# Keys prefixed with private- will get PRIVATE visibility
|
# Keys prefixed with private- will get PRIVATE visibility
|
||||||
@@ -200,7 +204,9 @@ working-directory = "mytest-dir"
|
|||||||
condition = "mycondition"
|
condition = "mycondition"
|
||||||
targets = ["mytarget", "mytest"]
|
targets = ["mytarget", "mytest"]
|
||||||
destination = ["bin"]
|
destination = ["bin"]
|
||||||
|
component = "mycomponent"
|
||||||
files = ["content/my.png"]
|
files = ["content/my.png"]
|
||||||
dirs = [""]
|
dirs = ["include"]
|
||||||
configs = [""]
|
configs = ["Release", "Debug"]
|
||||||
|
optional = false
|
||||||
```
|
```
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
# Automatically generated from tests/msvc-runtime/cmake.toml - DO NOT EDIT
|
||||||
|
layout: default
|
||||||
|
title: Static MSVC runtime
|
||||||
|
permalink: /examples/msvc-runtime
|
||||||
|
parent: Examples
|
||||||
|
nav_order: 8
|
||||||
|
---
|
||||||
|
|
||||||
|
# Static MSVC runtime
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[project]
|
||||||
|
name = "msvc-runtime"
|
||||||
|
description = "Static MSVC runtime"
|
||||||
|
msvc-runtime = "static"
|
||||||
|
|
||||||
|
# This target will compile with a static runtime
|
||||||
|
[target.static-runtime]
|
||||||
|
type = "executable"
|
||||||
|
sources = ["src/main.cpp"]
|
||||||
|
|
||||||
|
# This target overrides the [project].msvc-runtime
|
||||||
|
[target.dynamic-runtime]
|
||||||
|
type = "executable"
|
||||||
|
sources = ["src/main.cpp"]
|
||||||
|
msvc-runtime = "dynamic"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<sup><sub>This page was automatically generated from [tests/msvc-runtime/cmake.toml](https://github.com/build-cpp/cmkr/tree/main/tests/msvc-runtime/cmake.toml).</sub></sup>
|
||||||
@@ -67,7 +67,6 @@ struct Target {
|
|||||||
TargetType type = target_last;
|
TargetType type = target_last;
|
||||||
std::string type_name;
|
std::string type_name;
|
||||||
|
|
||||||
ConditionVector headers;
|
|
||||||
ConditionVector sources;
|
ConditionVector sources;
|
||||||
|
|
||||||
// https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html#project-commands
|
// https://cmake.org/cmake/help/latest/manual/cmake-commands.7.html#project-commands
|
||||||
@@ -128,6 +127,7 @@ struct Install {
|
|||||||
std::vector<std::string> configs;
|
std::vector<std::string> configs;
|
||||||
std::string destination;
|
std::string destination;
|
||||||
std::string component;
|
std::string component;
|
||||||
|
bool optional = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Subdir {
|
struct Subdir {
|
||||||
@@ -151,7 +151,17 @@ struct Content {
|
|||||||
ConditionVector include_after;
|
ConditionVector include_after;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MsvcRuntimeType {
|
||||||
|
msvc_dynamic,
|
||||||
|
msvc_static,
|
||||||
|
msvc_last,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const char *msvcRuntimeTypeNames[msvc_last];
|
||||||
|
|
||||||
struct Project {
|
struct Project {
|
||||||
|
const Project *parent;
|
||||||
|
|
||||||
// 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";
|
||||||
@@ -169,6 +179,7 @@ struct Project {
|
|||||||
std::string project_version;
|
std::string project_version;
|
||||||
std::string project_description;
|
std::string project_description;
|
||||||
std::vector<std::string> project_languages;
|
std::vector<std::string> project_languages;
|
||||||
|
MsvcRuntimeType project_msvc_runtime = msvc_last;
|
||||||
Condition<std::string> cmake_before;
|
Condition<std::string> cmake_before;
|
||||||
Condition<std::string> cmake_after;
|
Condition<std::string> cmake_after;
|
||||||
ConditionVector include_before;
|
ConditionVector include_before;
|
||||||
@@ -186,6 +197,7 @@ struct Project {
|
|||||||
std::vector<Subdir> subdirs;
|
std::vector<Subdir> subdirs;
|
||||||
|
|
||||||
Project(const Project *parent, const std::string &path, bool build);
|
Project(const Project *parent, const std::string &path, bool build);
|
||||||
|
const Project *root() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool is_root_path(const std::string &path);
|
bool is_root_path(const std::string &path);
|
||||||
|
|||||||
+66
-13
@@ -89,8 +89,24 @@ static void create_file(const fs::path &path, const std::string &contents) {
|
|||||||
ofs << contents;
|
ofs << contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CMake target name rules: https://cmake.org/cmake/help/latest/policy/CMP0037.html [A-Za-z0-9_.+\-]
|
||||||
|
// TOML bare keys: non-empty strings composed only of [A-Za-z0-9_-]
|
||||||
|
// We replace all non-TOML bare key characters with _
|
||||||
|
static std::string escape_project_name(const std::string &name) {
|
||||||
|
std::string escaped;
|
||||||
|
escaped.reserve(name.length());
|
||||||
|
for (auto ch : name) {
|
||||||
|
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-') {
|
||||||
|
escaped += ch;
|
||||||
|
} else {
|
||||||
|
escaped += '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
|
||||||
void generate_project(const std::string &type) {
|
void generate_project(const std::string &type) {
|
||||||
const auto name = fs::current_path().stem().string();
|
const auto name = escape_project_name(fs::current_path().stem().string());
|
||||||
if (fs::exists(fs::current_path() / "cmake.toml")) {
|
if (fs::exists(fs::current_path() / "cmake.toml")) {
|
||||||
throw std::runtime_error("Cannot initialize a project when cmake.toml already exists!");
|
throw std::runtime_error("Cannot initialize a project when cmake.toml already exists!");
|
||||||
}
|
}
|
||||||
@@ -126,13 +142,17 @@ void generate_project(const std::string &type) {
|
|||||||
|
|
||||||
struct CommandEndl {
|
struct CommandEndl {
|
||||||
std::stringstream &ss;
|
std::stringstream &ss;
|
||||||
CommandEndl(std::stringstream &ss) : ss(ss) {}
|
CommandEndl(std::stringstream &ss) : ss(ss) {
|
||||||
void endl() { ss << '\n'; }
|
}
|
||||||
|
void endl() {
|
||||||
|
ss << '\n';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawArg {
|
struct RawArg {
|
||||||
RawArg() = default;
|
RawArg() = default;
|
||||||
RawArg(std::string arg) : arg(std::move(arg)) {}
|
RawArg(std::string arg) : arg(std::move(arg)) {
|
||||||
|
}
|
||||||
|
|
||||||
std::string arg;
|
std::string arg;
|
||||||
};
|
};
|
||||||
@@ -148,7 +168,8 @@ struct Command {
|
|||||||
std::string post_comment;
|
std::string post_comment;
|
||||||
|
|
||||||
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() noexcept(false) {
|
~Command() noexcept(false) {
|
||||||
if (!generated) {
|
if (!generated) {
|
||||||
@@ -162,10 +183,11 @@ struct Command {
|
|||||||
return "\"\"";
|
return "\"\"";
|
||||||
}
|
}
|
||||||
// Don't quote arguments that don't need quoting
|
// Don't quote arguments that don't need quoting
|
||||||
if (str.find(' ') == std::string::npos && str.find('\"') == std::string::npos && str.find('/') == std::string::npos &&
|
// https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#unquoted-argument
|
||||||
str.find(';') == std::string::npos) {
|
// 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)
|
||||||
return str;
|
return str;
|
||||||
}
|
|
||||||
std::string result;
|
std::string result;
|
||||||
result += "\"";
|
result += "\"";
|
||||||
for (char ch : str) {
|
for (char ch : str) {
|
||||||
@@ -316,7 +338,8 @@ static std::string tolf(const std::string &str) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Generator {
|
struct Generator {
|
||||||
Generator(const parser::Project &project) : project(project) {}
|
Generator(const parser::Project &project) : project(project) {
|
||||||
|
}
|
||||||
Generator(const Generator &) = delete;
|
Generator(const Generator &) = delete;
|
||||||
|
|
||||||
const parser::Project &project;
|
const parser::Project &project;
|
||||||
@@ -342,7 +365,9 @@ struct Generator {
|
|||||||
return CommandEndl(ss);
|
return CommandEndl(ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
void endl() { ss << '\n'; }
|
void endl() {
|
||||||
|
ss << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
void inject_includes(const std::vector<std::string> &includes) {
|
void inject_includes(const std::vector<std::string> &includes) {
|
||||||
if (!includes.empty()) {
|
if (!includes.empty()) {
|
||||||
@@ -499,6 +524,21 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
|||||||
if (root_project) {
|
if (root_project) {
|
||||||
cmd("cmake_minimum_required")("VERSION", project.cmake_version).endl();
|
cmd("cmake_minimum_required")("VERSION", project.cmake_version).endl();
|
||||||
|
|
||||||
|
if (project.project_msvc_runtime != parser::msvc_last) {
|
||||||
|
comment("Enable support for MSVC_RUNTIME_LIBRARY");
|
||||||
|
cmd("cmake_policy")("SET", "CMP0091", "NEW").endl();
|
||||||
|
|
||||||
|
switch (project.project_msvc_runtime) {
|
||||||
|
case parser::msvc_dynamic:
|
||||||
|
cmd("set")("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL");
|
||||||
|
break;
|
||||||
|
case parser::msvc_static:
|
||||||
|
cmd("set")("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreaded$<$<CONFIG:Debug>:Debug>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
if (!project.allow_in_tree) {
|
if (!project.allow_in_tree) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
cmd("if")("CMAKE_SOURCE_DIR", "STREQUAL", "CMAKE_BINARY_DIR");
|
cmd("if")("CMAKE_SOURCE_DIR", "STREQUAL", "CMAKE_BINARY_DIR");
|
||||||
@@ -633,8 +673,12 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
|||||||
cmd("include")("FetchContent");
|
cmd("include")("FetchContent");
|
||||||
cmd("message")("STATUS", "Fetching vcpkg (" + version_name + ")...");
|
cmd("message")("STATUS", "Fetching vcpkg (" + version_name + ")...");
|
||||||
cmd("FetchContent_Declare")("vcpkg", "URL", url);
|
cmd("FetchContent_Declare")("vcpkg", "URL", url);
|
||||||
cmd("FetchContent_MakeAvailable")("vcpkg");
|
// Not using FetchContent_MakeAvailable here in case vcpkg adds CMakeLists.txt
|
||||||
cmd("include")("${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake");
|
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")();
|
cmd("endif")();
|
||||||
endl();
|
endl();
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@@ -777,6 +821,7 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!project.targets.empty()) {
|
if (!project.targets.empty()) {
|
||||||
|
auto root_project = project.root();
|
||||||
for (size_t i = 0; i < project.targets.size(); i++) {
|
for (size_t i = 0; i < project.targets.size(); i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
endl();
|
endl();
|
||||||
@@ -985,6 +1030,13 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gen.handle_condition(props, [&](const std::string &, const tsl::ordered_map<std::string, std::string> &properties) {
|
gen.handle_condition(props, [&](const std::string &, const tsl::ordered_map<std::string, std::string> &properties) {
|
||||||
|
for (const auto &propItr : properties) {
|
||||||
|
if (propItr.first == "MSVC_RUNTIME_LIBRARY") {
|
||||||
|
if (root_project->project_msvc_runtime == parser::msvc_last) {
|
||||||
|
throw std::runtime_error("You cannot set [target].msvc-runtime without setting the root [project].msvc-runtime");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cmd("set_target_properties")(target.name, "PROPERTIES", properties);
|
cmd("set_target_properties")(target.name, "PROPERTIES", properties);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1040,8 +1092,9 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
|
|||||||
component_name = inst.targets.front();
|
component_name = inst.targets.front();
|
||||||
}
|
}
|
||||||
auto component = std::make_pair("COMPONENT", component_name);
|
auto component = std::make_pair("COMPONENT", component_name);
|
||||||
|
auto optional = inst.optional ? "OPTIONAL" : "";
|
||||||
ConditionScope cs(gen, inst.condition);
|
ConditionScope cs(gen, inst.condition);
|
||||||
cmd("install")(targets, dirs, files, configs, destination, component);
|
cmd("install")(targets, dirs, files, configs, destination, component, optional);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-4
@@ -1,15 +1,21 @@
|
|||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace cmkr {
|
namespace cmkr {
|
||||||
namespace error {
|
namespace error {
|
||||||
|
|
||||||
Status::Status(Code ec) noexcept : ec_(ec) {}
|
Status::Status(Code ec) noexcept : ec_(ec) {
|
||||||
|
}
|
||||||
|
|
||||||
Status::operator int() const noexcept { return static_cast<int>(ec_); }
|
Status::operator int() const noexcept {
|
||||||
|
return static_cast<int>(ec_);
|
||||||
|
}
|
||||||
|
|
||||||
Status::Code Status::code() const noexcept { return ec_; }
|
Status::Code Status::code() const noexcept {
|
||||||
|
return ec_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace error
|
} // namespace error
|
||||||
} // namespace cmkr
|
} // namespace cmkr
|
||||||
@@ -20,6 +26,6 @@ static const char *err_string[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char *cmkr_error_status(int i) {
|
const char *cmkr_error_status(int i) {
|
||||||
assert(i >= 0 && i < (sizeof(err_string) / sizeof(*(err_string))));
|
assert(i >= 0 && static_cast<size_t>(i) < (sizeof(err_string) / sizeof(*(err_string))));
|
||||||
return err_string[i];
|
return err_string[i];
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -4,7 +4,9 @@
|
|||||||
namespace cmkr {
|
namespace cmkr {
|
||||||
namespace help {
|
namespace help {
|
||||||
|
|
||||||
const char *version() noexcept { return "cmkr version " CMKR_VERSION; }
|
const char *version() noexcept {
|
||||||
|
return "cmkr version " CMKR_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
const char *message() noexcept {
|
const char *message() noexcept {
|
||||||
return R"lit(
|
return R"lit(
|
||||||
@@ -22,6 +24,10 @@ arguments:
|
|||||||
} // namespace help
|
} // namespace help
|
||||||
} // namespace cmkr
|
} // namespace cmkr
|
||||||
|
|
||||||
const char *cmkr_help_version(void) { return cmkr::help::version(); }
|
const char *cmkr_help_version(void) {
|
||||||
|
return cmkr::help::version();
|
||||||
|
}
|
||||||
|
|
||||||
const char *cmkr_help_message(void) { return cmkr::help::message(); }
|
const char *cmkr_help_message(void) {
|
||||||
|
return cmkr::help::message();
|
||||||
|
}
|
||||||
+84
-11
@@ -21,6 +21,17 @@ static TargetType parse_targetType(const std::string &name) {
|
|||||||
return target_last;
|
return target_last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *msvcRuntimeTypeNames[msvc_last] = {"dynamic", "static"};
|
||||||
|
|
||||||
|
static MsvcRuntimeType parse_msvcRuntimeType(const std::string &name) {
|
||||||
|
for (int i = 0; i < msvc_last; i++) {
|
||||||
|
if (name == msvcRuntimeTypeNames[i]) {
|
||||||
|
return static_cast<MsvcRuntimeType>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msvc_last;
|
||||||
|
}
|
||||||
|
|
||||||
using TomlBasicValue = toml::basic_value<toml::discard_comments, tsl::ordered_map, std::vector>;
|
using TomlBasicValue = toml::basic_value<toml::discard_comments, tsl::ordered_map, std::vector>;
|
||||||
|
|
||||||
static std::string format_key_error(const std::string &error, const toml::key &ky, const TomlBasicValue &value) {
|
static std::string format_key_error(const std::string &error, const toml::key &ky, const TomlBasicValue &value) {
|
||||||
@@ -54,8 +65,10 @@ class TomlChecker {
|
|||||||
tsl::ordered_set<toml::key> m_conditionVisited;
|
tsl::ordered_set<toml::key> 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)) {
|
||||||
TomlChecker(const TomlBasicValue &v) : m_v(v) {}
|
}
|
||||||
|
TomlChecker(const TomlBasicValue &v) : m_v(v) {
|
||||||
|
}
|
||||||
TomlChecker(const TomlChecker &) = delete;
|
TomlChecker(const TomlChecker &) = delete;
|
||||||
TomlChecker(TomlChecker &&) = delete;
|
TomlChecker(TomlChecker &&) = delete;
|
||||||
|
|
||||||
@@ -109,9 +122,13 @@ class TomlChecker {
|
|||||||
return toml::find(m_v, ky);
|
return toml::find(m_v, ky);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(const toml::key &ky) { m_visited.emplace(ky); }
|
void visit(const toml::key &ky) {
|
||||||
|
m_visited.emplace(ky);
|
||||||
|
}
|
||||||
|
|
||||||
bool visisted(const toml::key &ky) const { return m_visited.contains(ky); }
|
bool visisted(const toml::key &ky) const {
|
||||||
|
return m_visited.contains(ky);
|
||||||
|
}
|
||||||
|
|
||||||
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()) {
|
||||||
@@ -152,7 +169,8 @@ class TomlCheckerRoot {
|
|||||||
bool m_checked = false;
|
bool m_checked = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TomlCheckerRoot(const TomlBasicValue &root) : m_root(root) {}
|
TomlCheckerRoot(const TomlBasicValue &root) : m_root(root) {
|
||||||
|
}
|
||||||
TomlCheckerRoot(const TomlCheckerRoot &) = delete;
|
TomlCheckerRoot(const TomlCheckerRoot &) = delete;
|
||||||
TomlCheckerRoot(TomlCheckerRoot &&) = delete;
|
TomlCheckerRoot(TomlCheckerRoot &&) = delete;
|
||||||
|
|
||||||
@@ -185,7 +203,7 @@ class TomlCheckerRoot {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Project::Project(const Project *parent, const std::string &path, bool build) {
|
Project::Project(const Project *parent, const std::string &path, bool build) : parent(parent) {
|
||||||
const auto toml_path = fs::path(path) / "cmake.toml";
|
const auto toml_path = fs::path(path) / "cmake.toml";
|
||||||
if (!fs::exists(toml_path)) {
|
if (!fs::exists(toml_path)) {
|
||||||
throw std::runtime_error("File not found '" + toml_path.string() + "'");
|
throw std::runtime_error("File not found '" + toml_path.string() + "'");
|
||||||
@@ -269,6 +287,21 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
|||||||
project.optional("include-before", include_before);
|
project.optional("include-before", include_before);
|
||||||
project.optional("include-after", include_after);
|
project.optional("include-after", include_after);
|
||||||
project.optional("subdirs", project_subdirs);
|
project.optional("subdirs", project_subdirs);
|
||||||
|
|
||||||
|
std::string msvc_runtime;
|
||||||
|
project.optional("msvc-runtime", msvc_runtime);
|
||||||
|
if (!msvc_runtime.empty()) {
|
||||||
|
project_msvc_runtime = parse_msvcRuntimeType(msvc_runtime);
|
||||||
|
if (project_msvc_runtime == msvc_last) {
|
||||||
|
std::string error = "Unknown runtime '" + msvc_runtime + "'\n";
|
||||||
|
error += "Available types:\n";
|
||||||
|
for (std::string type_name : msvcRuntimeTypeNames) {
|
||||||
|
error += " - " + type_name + "\n";
|
||||||
|
}
|
||||||
|
error.pop_back(); // Remove last newline
|
||||||
|
throw std::runtime_error(format_key_error(error, msvc_runtime, project.find("msvc-runtime")));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checker.contains("subdir")) {
|
if (checker.contains("subdir")) {
|
||||||
@@ -480,9 +513,18 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
|||||||
throw std::runtime_error(format_key_error(error, target.type_name, t.find("type")));
|
throw std::runtime_error(format_key_error(error, target.type_name, t.find("type")));
|
||||||
}
|
}
|
||||||
|
|
||||||
t.optional("headers", target.headers);
|
|
||||||
t.optional("sources", target.sources);
|
t.optional("sources", target.sources);
|
||||||
|
|
||||||
|
// Merge the headers into the sources
|
||||||
|
ConditionVector headers;
|
||||||
|
t.optional("headers", headers);
|
||||||
|
for (const auto &itr : headers) {
|
||||||
|
auto &dest = target.sources[itr.first];
|
||||||
|
for (const auto &jtr : itr.second) {
|
||||||
|
dest.push_back(jtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
t.optional("compile-definitions", target.compile_definitions);
|
t.optional("compile-definitions", target.compile_definitions);
|
||||||
t.optional("private-compile-definitions", target.private_compile_definitions);
|
t.optional("private-compile-definitions", target.private_compile_definitions);
|
||||||
|
|
||||||
@@ -507,10 +549,32 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
|||||||
t.optional("precompile-headers", target.precompile_headers);
|
t.optional("precompile-headers", target.precompile_headers);
|
||||||
t.optional("private-precompile-headers", target.private_precompile_headers);
|
t.optional("private-precompile-headers", target.private_precompile_headers);
|
||||||
|
|
||||||
if (!target.headers.empty()) {
|
Condition<std::string> msvc_runtime;
|
||||||
auto &sources = target.sources.nth(0).value();
|
t.optional("msvc-runtime", msvc_runtime);
|
||||||
const auto &headers = target.headers.nth(0)->second;
|
for (const auto &condItr : msvc_runtime) {
|
||||||
sources.insert(sources.end(), headers.begin(), headers.end());
|
switch (parse_msvcRuntimeType(condItr.second)) {
|
||||||
|
case msvc_dynamic:
|
||||||
|
target.properties[condItr.first]["MSVC_RUNTIME_LIBRARY"] = "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL";
|
||||||
|
break;
|
||||||
|
case msvc_static:
|
||||||
|
target.properties[condItr.first]["MSVC_RUNTIME_LIBRARY"] = "MultiThreaded$<$<CONFIG:Debug>:Debug>";
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
std::string error = "Unknown runtime '" + condItr.second + "'\n";
|
||||||
|
error += "Available types:\n";
|
||||||
|
for (std::string type_name : msvcRuntimeTypeNames) {
|
||||||
|
error += " - " + type_name + "\n";
|
||||||
|
}
|
||||||
|
error.pop_back(); // Remove last newline
|
||||||
|
const TomlBasicValue *report;
|
||||||
|
if (condItr.first.empty()) {
|
||||||
|
report = &t.find("msvc-runtime");
|
||||||
|
} else {
|
||||||
|
report = &t.find(condItr.first).as_table().find("msvc-runtime").value();
|
||||||
|
}
|
||||||
|
throw std::runtime_error(format_key_error(error, condItr.second, *report));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t.optional("condition", target.condition);
|
t.optional("condition", target.condition);
|
||||||
@@ -619,6 +683,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
|||||||
i.optional("configs", inst.configs);
|
i.optional("configs", inst.configs);
|
||||||
i.required("destination", inst.destination);
|
i.required("destination", inst.destination);
|
||||||
i.optional("component", inst.component);
|
i.optional("component", inst.component);
|
||||||
|
i.optional("optional", inst.optional);
|
||||||
installs.push_back(inst);
|
installs.push_back(inst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,6 +692,7 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
|||||||
auto &v = checker.create(toml, "vcpkg");
|
auto &v = checker.create(toml, "vcpkg");
|
||||||
v.optional("url", vcpkg.url);
|
v.optional("url", vcpkg.url);
|
||||||
v.optional("version", vcpkg.version);
|
v.optional("version", vcpkg.version);
|
||||||
|
|
||||||
for (const auto &p : v.find("packages").as_array()) {
|
for (const auto &p : v.find("packages").as_array()) {
|
||||||
Vcpkg::Package package;
|
Vcpkg::Package package;
|
||||||
const auto &package_str = p.as_string().str;
|
const auto &package_str = p.as_string().str;
|
||||||
@@ -652,6 +718,13 @@ Project::Project(const Project *parent, const std::string &path, bool build) {
|
|||||||
checker.check(conditions, true);
|
checker.check(conditions, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Project *Project::root() const {
|
||||||
|
auto root = this;
|
||||||
|
while (root->parent != nullptr)
|
||||||
|
root = root->parent;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_root_path(const std::string &path) {
|
bool is_root_path(const std::string &path) {
|
||||||
const auto toml_path = fs::path(path) / "cmake.toml";
|
const auto toml_path = fs::path(path) / "cmake.toml";
|
||||||
if (!fs::exists(toml_path)) {
|
if (!fs::exists(toml_path)) {
|
||||||
|
|||||||
Generated
+20
-8
@@ -14,7 +14,7 @@ add_test(
|
|||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/basic"
|
"${CMAKE_CURRENT_LIST_DIR}/basic"
|
||||||
COMMAND
|
COMMAND
|
||||||
$<TARGET_FILE:cmkr>
|
"$<TARGET_FILE:cmkr>"
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ add_test(
|
|||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/interface"
|
"${CMAKE_CURRENT_LIST_DIR}/interface"
|
||||||
COMMAND
|
COMMAND
|
||||||
$<TARGET_FILE:cmkr>
|
"$<TARGET_FILE:cmkr>"
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ add_test(
|
|||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/fetch-content"
|
"${CMAKE_CURRENT_LIST_DIR}/fetch-content"
|
||||||
COMMAND
|
COMMAND
|
||||||
$<TARGET_FILE:cmkr>
|
"$<TARGET_FILE:cmkr>"
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ add_test(
|
|||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/conditions"
|
"${CMAKE_CURRENT_LIST_DIR}/conditions"
|
||||||
COMMAND
|
COMMAND
|
||||||
$<TARGET_FILE:cmkr>
|
"$<TARGET_FILE:cmkr>"
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ add_test(
|
|||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/vcpkg"
|
"${CMAKE_CURRENT_LIST_DIR}/vcpkg"
|
||||||
COMMAND
|
COMMAND
|
||||||
$<TARGET_FILE:cmkr>
|
"$<TARGET_FILE:cmkr>"
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ add_test(
|
|||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/cxx-standard"
|
"${CMAKE_CURRENT_LIST_DIR}/cxx-standard"
|
||||||
COMMAND
|
COMMAND
|
||||||
$<TARGET_FILE:cmkr>
|
"$<TARGET_FILE:cmkr>"
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ add_test(
|
|||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/globbing"
|
"${CMAKE_CURRENT_LIST_DIR}/globbing"
|
||||||
COMMAND
|
COMMAND
|
||||||
$<TARGET_FILE:cmkr>
|
"$<TARGET_FILE:cmkr>"
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -84,7 +84,19 @@ add_test(
|
|||||||
WORKING_DIRECTORY
|
WORKING_DIRECTORY
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/templates"
|
"${CMAKE_CURRENT_LIST_DIR}/templates"
|
||||||
COMMAND
|
COMMAND
|
||||||
$<TARGET_FILE:cmkr>
|
"$<TARGET_FILE:cmkr>"
|
||||||
build
|
build
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(MSVC) # msvc
|
||||||
|
add_test(
|
||||||
|
NAME
|
||||||
|
msvc-runtime
|
||||||
|
WORKING_DIRECTORY
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/msvc-runtime"
|
||||||
|
COMMAND
|
||||||
|
"$<TARGET_FILE:cmkr>"
|
||||||
|
build
|
||||||
|
)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -45,3 +45,10 @@ name = "templates"
|
|||||||
working-directory = "templates"
|
working-directory = "templates"
|
||||||
command = "$<TARGET_FILE:cmkr>"
|
command = "$<TARGET_FILE:cmkr>"
|
||||||
arguments = ["build"]
|
arguments = ["build"]
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
condition = "msvc"
|
||||||
|
name = "msvc-runtime"
|
||||||
|
working-directory = "msvc-runtime"
|
||||||
|
command = "$<TARGET_FILE:cmkr>"
|
||||||
|
arguments = ["build"]
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[project]
|
||||||
|
name = "msvc-runtime"
|
||||||
|
description = "Static MSVC runtime"
|
||||||
|
msvc-runtime = "static"
|
||||||
|
|
||||||
|
# This target will compile with a static runtime
|
||||||
|
[target.static-runtime]
|
||||||
|
type = "executable"
|
||||||
|
sources = ["src/main.cpp"]
|
||||||
|
|
||||||
|
# This target overrides the [project].msvc-runtime
|
||||||
|
[target.dynamic-runtime]
|
||||||
|
type = "executable"
|
||||||
|
sources = ["src/main.cpp"]
|
||||||
|
msvc-runtime = "dynamic"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
puts("Hello from cmkr(msvc-static)!");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user