Merge pull request #94 from build-cpp/user-experience

Add a special "root" value for `[options]`
main
Duncan Ogilvie 1 year ago committed by GitHub
commit 7508816fe7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -100,9 +100,12 @@ include-after = ["cmake/after-subdir.cmake"]
[options]
MYPROJECT_BUILD_TESTS = false
MYPROJECT_SPECIAL_OPTION = { value = true, help = "Docstring for this option." }
MYPROJECT_BUILD_EXAMPLES = "root"
```
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).
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).
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]`).
## Variables

@ -25,7 +25,7 @@ struct Variable {
struct Option {
std::string name;
std::string help;
bool value = false;
mpark::variant<bool, std::string> value;
};
struct Package {

@ -656,7 +656,13 @@ 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, RawArg(Command::quote(opt.help)), opt.value ? "ON" : "OFF");
std::string default_val;
if (opt.value.index() == 0) {
default_val = mpark::get<0>(opt.value) ? "ON" : "OFF";
} else {
default_val = mpark::get<1>(opt.value);
}
cmd("option")(opt.name, RawArg(Command::quote(opt.help)), default_val);
}
endl();
}

@ -377,10 +377,33 @@ Project::Project(const Project *parent, const std::string &path, bool build) : p
const auto &value = itr.second;
if (value.is_boolean()) {
o.value = value.as_boolean();
} else {
} else if (value.is_string()) {
auto str = std::string(value.as_string());
if (str == "root") {
o.value = std::string("${CMKR_ROOT_PROJECT}");
} else {
throw_key_error("Unsupported option value '" + str + "'", str, value);
}
} else if (value.is_table()) {
auto &option = checker.create(value);
option.optional("help", o.help);
option.optional("value", o.value);
if (option.contains("value")) {
const auto &ovalue = option.find("value");
if (ovalue.is_boolean()) {
o.value = ovalue.as_boolean();
} else if (ovalue.is_string()) {
auto str = std::string(ovalue.as_string());
if (str == "root") {
o.value = std::string("${CMKR_ROOT_PROJECT}");
} else {
throw_key_error("Unsupported option value '" + str + "'", str, value);
}
} else {
throw_key_error(toml::concat_to_string("Unsupported value type: ", ovalue.type()), "value", value);
}
}
} else {
throw_key_error(toml::concat_to_string("Unsupported value type: ", itr.second.type()), itr.first, itr.second);
}
options.push_back(o);
conditions.emplace(o.name, o.name);

Loading…
Cancel
Save