From 0f36156740aaea82795444c8468fbfd5dc1e3810 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 16 Oct 2023 13:57:54 -0400 Subject: cxxmodules: include `INCLUDES DESTINATION` directories These paths are added outside the normal property management mechanisms. Shuttle the value to the C++ module export as needed. Fixes: #25289 --- Source/cmExportBuildFileGenerator.cxx | 2 +- Source/cmExportFileGenerator.cxx | 35 +++++++++++++++++++--- Source/cmExportFileGenerator.h | 6 ++-- Source/cmExportInstallFileGenerator.cxx | 6 ++-- .../CMakeLists.txt | 6 ++-- .../importable.cxx | 6 ++++ .../includes/includes.h | 3 ++ .../CMakeLists.txt | 9 ++++-- .../importable.cxx | 6 ++++ .../includes/includes.h | 3 ++ 10 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 Tests/RunCMake/CXXModules/examples/export-include-directories-build/includes/includes.h create mode 100644 Tests/RunCMake/CXXModules/examples/export-include-directories-install/includes/includes.h diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 69572f4..bf3bb8b 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -127,7 +127,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) std::string errorMessage; if (!this->PopulateCxxModuleExportProperties( - gte, properties, cmGeneratorExpression::BuildInterface, + gte, properties, cmGeneratorExpression::BuildInterface, {}, errorMessage)) { this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage( MessageType::FATAL_ERROR, errorMessage, diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index dae061b..d0e69fb 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -374,10 +374,13 @@ void cmExportFileGenerator::PopulateSourcesInterface( void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, cmTargetExport const& te) + ImportPropertyMap& properties, cmTargetExport const& te, + std::string& includesDestinationDirs) { assert(preprocessRule == cmGeneratorExpression::InstallInterface); + includesDestinationDirs.clear(); + const char* propName = "INTERFACE_INCLUDE_DIRECTORIES"; cmValue input = target->GetProperty(propName); @@ -414,6 +417,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( } prefixItems(exportDirs); + includesDestinationDirs = exportDirs; std::string includes = (input ? *input : ""); const char* sep = input ? ";" : ""; @@ -1260,8 +1264,23 @@ enum class PropertyType { Strings, Paths, + IncludePaths, }; +namespace { +bool PropertyTypeIsForPaths(PropertyType pt) +{ + switch (pt) { + case PropertyType::Strings: + return false; + case PropertyType::Paths: + case PropertyType::IncludePaths: + return true; + } + return false; +} +} + struct ModulePropertyTable { cm::static_string_view Name; @@ -1270,7 +1289,8 @@ struct ModulePropertyTable bool cmExportFileGenerator::PopulateCxxModuleExportProperties( cmGeneratorTarget const* gte, ImportPropertyMap& properties, - cmGeneratorExpression::PreprocessContext ctx, std::string& errorMessage) + cmGeneratorExpression::PreprocessContext ctx, + std::string const& includesDestinationDirs, std::string& errorMessage) { if (!gte->HaveCxx20ModuleSources(&errorMessage)) { return true; @@ -1292,7 +1312,7 @@ bool cmExportFileGenerator::PopulateCxxModuleExportProperties( } const ModulePropertyTable exportedModuleProperties[] = { - { "INCLUDE_DIRECTORIES"_s, PropertyType::Paths }, + { "INCLUDE_DIRECTORIES"_s, PropertyType::IncludePaths }, { "COMPILE_DEFINITIONS"_s, PropertyType::Strings }, { "COMPILE_OPTIONS"_s, PropertyType::Strings }, { "COMPILE_FEATURES"_s, PropertyType::Strings }, @@ -1310,9 +1330,16 @@ bool cmExportFileGenerator::PopulateCxxModuleExportProperties( properties[exportedPropName] = cmGeneratorExpression::Preprocess(*prop, ctx); if (ctx == cmGeneratorExpression::InstallInterface && - propEntry.Type == PropertyType::Paths) { + PropertyTypeIsForPaths(propEntry.Type)) { this->ReplaceInstallPrefix(properties[exportedPropName]); prefixItems(properties[exportedPropName]); + if (propEntry.Type == PropertyType::IncludePaths && + !includesDestinationDirs.empty()) { + if (!properties[exportedPropName].empty()) { + properties[exportedPropName] += ';'; + } + properties[exportedPropName] += includesDestinationDirs; + } } } } diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 6fa19ee..f396e0e 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -143,7 +143,8 @@ protected: void PopulateIncludeDirectoriesInterface( cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, cmTargetExport const& te); + ImportPropertyMap& properties, cmTargetExport const& te, + std::string& includesDestinationDirs); void PopulateSourcesInterface( cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, @@ -177,7 +178,8 @@ protected: bool PopulateCxxModuleExportProperties( cmGeneratorTarget const* gte, ImportPropertyMap& properties, - cmGeneratorExpression::PreprocessContext ctx, std::string& errorMessage); + cmGeneratorExpression::PreprocessContext ctx, + std::string const& includesDestinationDirs, std::string& errorMessage); bool PopulateExportProperties(cmGeneratorTarget const* gte, ImportPropertyMap& properties, std::string& errorMessage); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 908bb31..a264f5e 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -92,8 +92,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) ImportPropertyMap properties; + std::string includesDestinationDirs; this->PopulateIncludeDirectoriesInterface( - gt, cmGeneratorExpression::InstallInterface, properties, *te); + gt, cmGeneratorExpression::InstallInterface, properties, *te, + includesDestinationDirs); this->PopulateSourcesInterface(gt, cmGeneratorExpression::InstallInterface, properties); this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt, @@ -128,7 +130,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) std::string errorMessage; if (!this->PopulateCxxModuleExportProperties( gt, properties, cmGeneratorExpression::InstallInterface, - errorMessage)) { + includesDestinationDirs, errorMessage)) { cmSystemTools::Error(errorMessage); return false; } diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/CMakeLists.txt index 560994e..dd35c1f 100644 --- a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/CMakeLists.txt @@ -4,7 +4,8 @@ project(cxx_modules_export_include_directories CXX) include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") add_library(export_include_directories STATIC - include/include.h) + include/include.h + includes/includes.h) target_sources(export_include_directories PRIVATE forward.cxx @@ -25,7 +26,8 @@ target_sources(export_include_directories target_compile_features(export_include_directories PUBLIC cxx_std_20) target_include_directories(export_include_directories PRIVATE - "$") + "$" + "$") add_library(no_modules STATIC no_modules.cxx) diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/importable.cxx index 6a1d83e..2c29683 100644 --- a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/importable.cxx +++ b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/importable.cxx @@ -6,6 +6,12 @@ module; # error "include define not found" #endif +#include "includes/includes.h" + +#ifndef includes_h_included +# error "includes define not found" +#endif + export module importable; extern "C++" { diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-build/includes/includes.h b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/includes/includes.h new file mode 100644 index 0000000..96bf33b --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-include-directories-build/includes/includes.h @@ -0,0 +1,3 @@ +#pragma once + +#define includes_h_included diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/CMakeLists.txt index 3d4e687..3e447f5 100644 --- a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/CMakeLists.txt @@ -4,7 +4,8 @@ project(cxx_modules_export_include_directories CXX) include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") add_library(export_include_directories STATIC - include/include.h) + include/include.h + includes/includes.h) target_sources(export_include_directories PRIVATE forward.cxx @@ -26,15 +27,19 @@ target_compile_features(export_include_directories PUBLIC cxx_std_20) target_include_directories(export_include_directories PRIVATE "$" + "$" "$") add_library(no_modules STATIC no_modules.cxx) install(TARGETS export_include_directories no_modules EXPORT CXXModules - FILE_SET modules DESTINATION "lib/cxx/miu") + FILE_SET modules DESTINATION "lib/cxx/miu" + INCLUDES DESTINATION "elsewhere") install(DIRECTORY include DESTINATION "include") +install(DIRECTORY includes + DESTINATION "elsewhere") install(EXPORT CXXModules NAMESPACE CXXModules:: DESTINATION "lib/cmake/export_include_directories" diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/importable.cxx index 6a1d83e..2c29683 100644 --- a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/importable.cxx +++ b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/importable.cxx @@ -6,6 +6,12 @@ module; # error "include define not found" #endif +#include "includes/includes.h" + +#ifndef includes_h_included +# error "includes define not found" +#endif + export module importable; extern "C++" { diff --git a/Tests/RunCMake/CXXModules/examples/export-include-directories-install/includes/includes.h b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/includes/includes.h new file mode 100644 index 0000000..96bf33b --- /dev/null +++ b/Tests/RunCMake/CXXModules/examples/export-include-directories-install/includes/includes.h @@ -0,0 +1,3 @@ +#pragma once + +#define includes_h_included -- cgit v0.12