@@ -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++) {
0 commit comments