Skip to content

Commit 7508816

Browse files
authored
Merge pull request #94 from build-cpp/user-experience
Add a special "root" value for `[options]`
2 parents a499df8 + b869e56 commit 7508816

File tree

4 files changed

+37
-5
lines changed

4 files changed

+37
-5
lines changed

docs/cmake-toml.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,12 @@ include-after = ["cmake/after-subdir.cmake"]
100100
[options]
101101
MYPROJECT_BUILD_TESTS = false
102102
MYPROJECT_SPECIAL_OPTION = { value = true, help = "Docstring for this option." }
103+
MYPROJECT_BUILD_EXAMPLES = "root"
103104
```
104105

105-
Options correspond to [CMake cache variables](https://cmake.org/cmake/help/book/mastering-cmake/chapter/CMake%20Cache.html) that can be used to customize your project at configure-time. You can configure with `cmake -DMYPROJECT_BUILD_TESTS=ON` to enable the option. Every options automatically gets a corresponding [condition](#conditions).
106+
Options correspond to [CMake cache variables](https://cmake.org/cmake/help/book/mastering-cmake/chapter/CMake%20Cache.html) that can be used to customize your project at configure-time. You can configure with `cmake -DMYPROJECT_BUILD_TESTS=ON` to enable the option. Every option automatically gets a corresponding [condition](#conditions).
107+
108+
The special value `root` can be used to set the option to `true` if the project is compiled as the root project (it will be `false` if someone is including your project via `[fetch-content]` or `[subdir]`).
106109

107110
## Variables
108111

include/project_parser.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct Variable {
2525
struct Option {
2626
std::string name;
2727
std::string help;
28-
bool value = false;
28+
mpark::variant<bool, std::string> value;
2929
};
3030

3131
struct Package {

src/cmake_generator.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,13 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
656656
if (!project.options.empty()) {
657657
comment("Options");
658658
for (const auto &opt : project.options) {
659-
cmd("option")(opt.name, RawArg(Command::quote(opt.help)), opt.value ? "ON" : "OFF");
659+
std::string default_val;
660+
if (opt.value.index() == 0) {
661+
default_val = mpark::get<0>(opt.value) ? "ON" : "OFF";
662+
} else {
663+
default_val = mpark::get<1>(opt.value);
664+
}
665+
cmd("option")(opt.name, RawArg(Command::quote(opt.help)), default_val);
660666
}
661667
endl();
662668
}

src/project_parser.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,33 @@ Project::Project(const Project *parent, const std::string &path, bool build) : p
377377
const auto &value = itr.second;
378378
if (value.is_boolean()) {
379379
o.value = value.as_boolean();
380-
} else {
380+
} else if (value.is_string()) {
381+
auto str = std::string(value.as_string());
382+
if (str == "root") {
383+
o.value = std::string("${CMKR_ROOT_PROJECT}");
384+
} else {
385+
throw_key_error("Unsupported option value '" + str + "'", str, value);
386+
}
387+
} else if (value.is_table()) {
381388
auto &option = checker.create(value);
382389
option.optional("help", o.help);
383-
option.optional("value", o.value);
390+
if (option.contains("value")) {
391+
const auto &ovalue = option.find("value");
392+
if (ovalue.is_boolean()) {
393+
o.value = ovalue.as_boolean();
394+
} else if (ovalue.is_string()) {
395+
auto str = std::string(ovalue.as_string());
396+
if (str == "root") {
397+
o.value = std::string("${CMKR_ROOT_PROJECT}");
398+
} else {
399+
throw_key_error("Unsupported option value '" + str + "'", str, value);
400+
}
401+
} else {
402+
throw_key_error(toml::concat_to_string("Unsupported value type: ", ovalue.type()), "value", value);
403+
}
404+
}
405+
} else {
406+
throw_key_error(toml::concat_to_string("Unsupported value type: ", itr.second.type()), itr.first, itr.second);
384407
}
385408
options.push_back(o);
386409
conditions.emplace(o.name, o.name);

0 commit comments

Comments
 (0)