Skip to content

Commit 4772a2b

Browse files
committed
Add support for conditional [project].languages
Closes #184
1 parent fb4931d commit 4772a2b

File tree

3 files changed

+50
-36
lines changed

3 files changed

+50
-36
lines changed

include/project_parser.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ struct Project {
194194
std::string project_name;
195195
std::string project_version;
196196
std::string project_description;
197-
std::vector<std::string> project_languages;
197+
ConditionVector project_languages;
198198
bool project_allow_unknown_languages = false;
199199
MsvcRuntimeType project_msvc_runtime = msvc_last;
200200
Condition<std::string> cmake_before;

src/cmake_generator.cpp

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -725,16 +725,41 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
725725

726726
parser::Project project(parent_project, path, false);
727727

728-
for (const auto &lang : project.project_languages) {
729-
if (known_languages.find(lang) == known_languages.end()) {
728+
tsl::ordered_set<std::string> flat_project_languages;
729+
for (const auto &itr : project.project_languages) {
730+
for (const auto &language : itr.second) {
731+
flat_project_languages.insert(language);
732+
}
733+
}
734+
735+
// Reference: https://gitlab.kitware.com/cmake/cmake/-/issues/24340#note_1304703
736+
flat_project_languages.insert("RC");
737+
738+
// All acceptable extensions based off our given languages.
739+
tsl::ordered_set<std::string> project_extensions;
740+
for (const auto &language : flat_project_languages) {
741+
auto itr = known_languages.find(language);
742+
if (itr == known_languages.end()) {
730743
if (project.project_allow_unknown_languages) {
731-
printf("[warning] Unknown language '%s' specified\n", lang.c_str());
744+
printf("[warning] Unknown language '%s' specified\n", language.c_str());
732745
} else {
733-
throw std::runtime_error("Unknown language '" + lang + "' specified");
746+
throw std::runtime_error("Unknown language '" + language + "' specified");
734747
}
748+
} else {
749+
project_extensions.insert(itr->second.begin(), itr->second.end());
735750
}
736751
}
737752

753+
auto contains_language_source = [&project_extensions](const std::vector<std::string> &sources) {
754+
for (const auto &source : sources) {
755+
auto extension = fs::path(source).extension().string();
756+
if (project_extensions.count(extension) > 0) {
757+
return true;
758+
}
759+
}
760+
return false;
761+
};
762+
738763
Generator gen(project, path);
739764

740765
// Helper lambdas for more convenient CMake generation
@@ -912,17 +937,29 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
912937
gen.conditional_cmake(project.cmake_before);
913938

914939
if (!project.project_name.empty()) {
915-
auto languages = std::make_pair("LANGUAGES", project.project_languages);
940+
auto languages = std::make_pair("LANGUAGES", project.project_languages[""]);
916941
auto version = std::make_pair("VERSION", project.project_version);
917942
auto description = std::make_pair("DESCRIPTION", project.project_description);
918-
cmd("project")(project.project_name, languages, version, description).endl();
943+
cmd("project")(project.project_name, languages, version, description);
919944

920-
for (const auto &language : project.project_languages) {
945+
for (const auto &language : project.project_languages[""]) {
921946
if (language == "CSharp") {
922947
cmd("include")("CSharpUtilities").endl();
923948
break;
924949
}
925950
}
951+
952+
gen.handle_condition(project.project_languages, [&cmd](const std::string &condition, const std::vector<std::string> &languages) {
953+
if (!condition.empty()) {
954+
cmd("enable_language")(languages).endl();
955+
for (const auto &language : languages) {
956+
if (language == "CSharp") {
957+
cmd("include")("CSharpUtilities").endl();
958+
break;
959+
}
960+
}
961+
}
962+
});
926963
}
927964

928965
gen.conditional_includes(project.include_after);
@@ -1138,34 +1175,6 @@ void generate_cmake(const char *path, const parser::Project *parent_project) {
11381175
gen.conditional_cmake(subdir.cmake_after);
11391176
}
11401177

1141-
// The implicit default is ["C", "CXX"], so make sure this list isn't
1142-
// empty or projects without languages explicitly defined will error.
1143-
auto project_languages = project.project_languages;
1144-
if (project_languages.empty())
1145-
project_languages = {"C", "CXX"};
1146-
1147-
// Reference: https://gitlab.kitware.com/cmake/cmake/-/issues/24340#note_1304703
1148-
project_languages.push_back("RC");
1149-
1150-
// All acceptable extensions based off our given languages.
1151-
tsl::ordered_set<std::string> project_extensions;
1152-
for (const auto &language : project_languages) {
1153-
auto itr = known_languages.find(language);
1154-
if (itr != known_languages.end()) {
1155-
project_extensions.insert(itr->second.begin(), itr->second.end());
1156-
}
1157-
}
1158-
1159-
auto contains_language_source = [&project_extensions](const std::vector<std::string> &sources) {
1160-
for (const auto &source : sources) {
1161-
auto extension = fs::path(source).extension().string();
1162-
if (project_extensions.count(extension) > 0) {
1163-
return true;
1164-
}
1165-
}
1166-
return false;
1167-
};
1168-
11691178
if (!project.targets.empty()) {
11701179
auto project_root = project.root();
11711180
for (size_t i = 0; i < project.targets.size(); i++) {

src/project_parser.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ Project::Project(const Project *parent, const std::string &path, bool build) : p
301301
project.required("name", project_name);
302302
project.optional("version", project_version);
303303
project.optional("description", project_description);
304+
305+
// The implicit default is ["C", "CXX"], so make sure this list isn't
306+
// empty or projects without languages explicitly defined will error.
307+
project_languages[""] = {"C", "CXX"};
308+
304309
project.optional("languages", project_languages);
305310
project.optional("allow-unknown-languages", project_allow_unknown_languages);
306311
project.optional("cmake-before", cmake_before);

0 commit comments

Comments
 (0)