diff options
18 files changed, 136 insertions, 32 deletions
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 9b5f2b4..e764545 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -112,9 +112,27 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args, return false; } - if (!status.GetMakefile().CanIWriteThisFile(arguments.OutputFile)) { - status.SetError("attempted to output into a file: " + - arguments.OutputFile + " into a source directory."); + std::string inputFilename = arguments.InputFile; + std::string outputFilename = arguments.OutputFile; + std::string errorFilename = arguments.ErrorFile; + if (!arguments.WorkingDirectory.empty()) { + if (!inputFilename.empty()) { + inputFilename = cmSystemTools::CollapseFullPath( + inputFilename, arguments.WorkingDirectory); + } + if (!outputFilename.empty()) { + outputFilename = cmSystemTools::CollapseFullPath( + outputFilename, arguments.WorkingDirectory); + } + if (!errorFilename.empty()) { + errorFilename = cmSystemTools::CollapseFullPath( + errorFilename, arguments.WorkingDirectory); + } + } + + if (!status.GetMakefile().CanIWriteThisFile(outputFilename)) { + status.SetError("attempted to output into a file: " + outputFilename + + " into a source directory."); cmSystemTools::SetFatalErrorOccurred(); return false; } @@ -162,20 +180,24 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args, // Check the output variables. std::unique_ptr<FILE, int (*)(FILE*)> inputFile(nullptr, fclose); - if (!arguments.InputFile.empty()) { - inputFile.reset(cmsys::SystemTools::Fopen(arguments.InputFile, "rb")); - builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT, - cm_fileno(inputFile.get())); + if (!inputFilename.empty()) { + inputFile.reset(cmsys::SystemTools::Fopen(inputFilename, "rb")); + if (inputFile) { + builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT, + cm_fileno(inputFile.get())); + } } else { builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT, cm_fileno(stdin)); } std::unique_ptr<FILE, int (*)(FILE*)> outputFile(nullptr, fclose); - if (!arguments.OutputFile.empty()) { - outputFile.reset(cmsys::SystemTools::Fopen(arguments.OutputFile, "wb")); - builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, - cm_fileno(outputFile.get())); + if (!outputFilename.empty()) { + outputFile.reset(cmsys::SystemTools::Fopen(outputFilename, "wb")); + if (outputFile) { + builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, + cm_fileno(outputFile.get())); + } } else { if (arguments.OutputVariable == arguments.ErrorVariable && !arguments.ErrorVariable.empty()) { @@ -186,14 +208,18 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args, } std::unique_ptr<FILE, int (*)(FILE*)> errorFile(nullptr, fclose); - if (!arguments.ErrorFile.empty()) { - if (arguments.ErrorFile == arguments.OutputFile) { - builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, - cm_fileno(outputFile.get())); + if (!errorFilename.empty()) { + if (errorFilename == outputFilename) { + if (outputFile) { + builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, + cm_fileno(outputFile.get())); + } } else { - errorFile.reset(cmsys::SystemTools::Fopen(arguments.ErrorFile, "wb")); - builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, - cm_fileno(errorFile.get())); + errorFile.reset(cmsys::SystemTools::Fopen(errorFilename, "wb")); + if (errorFile) { + builder.SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, + cm_fileno(errorFile.get())); + } } } else if (arguments.ErrorVariable.empty() || (!arguments.ErrorVariable.empty() && 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 - "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>") + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/includes>") 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 "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/includes>" "$<INSTALL_INTERFACE:include>") 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 diff --git a/Tests/RunCMake/NinjaPrivateDeps/CMP0154-NEW-Build-PrivateFileSet-check.cmake b/Tests/RunCMake/NinjaPrivateDeps/CMP0154-NEW-Build-PrivateFileSet-check.cmake index 357b8c0..e8c78ed 100644 --- a/Tests/RunCMake/NinjaPrivateDeps/CMP0154-NEW-Build-PrivateFileSet-check.cmake +++ b/Tests/RunCMake/NinjaPrivateDeps/CMP0154-NEW-Build-PrivateFileSet-check.cmake @@ -1,3 +1,3 @@ if (NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/private.h) - set(RunCMake_TEST_FAILED "Private header generated before compilation.") + set(RunCMake_TEST_FAILED "Private header should be generated for target compilation") endif() diff --git a/Tests/RunCMake/execute_process/InOutErrDirectory.cmake b/Tests/RunCMake/execute_process/InOutErrDirectory.cmake new file mode 100644 index 0000000..fe5a836 --- /dev/null +++ b/Tests/RunCMake/execute_process/InOutErrDirectory.cmake @@ -0,0 +1,13 @@ +file(MAKE_DIRECTORY dir) +file(WRITE dir/in.txt "This is a test") +execute_process(COMMAND ${PRINT_STDIN_EXE} WORKING_DIRECTORY dir INPUT_FILE in.txt OUTPUT_FILE out.txt ERROR_FILE err.txt) +if(NOT EXISTS dir/out.txt) + message(SEND_ERROR "Did not create dir/out.txt") +endif() +file(READ dir/out.txt out) +if(NOT out STREQUAL "This is a test") + message(SEND_ERROR "Did not read dir/in.txt") +endif() +if(NOT EXISTS dir/err.txt) + message(SEND_ERROR "Did not create dir/err.txt") +endif() diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake index 1f89829..1e9e10a 100644 --- a/Tests/RunCMake/execute_process/RunCMakeTest.cmake +++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake @@ -35,6 +35,11 @@ run_cmake_command(LastCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/La run_cmake_command(LastCommandTimeout ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandTimeout.cmake) run_cmake_command(LastCommandGood ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandGood.cmake) run_cmake_command(Stdin ${CMAKE_COMMAND} -DPRINT_STDIN_EXE=${PRINT_STDIN_EXE} -P ${RunCMake_SOURCE_DIR}/Stdin.cmake) +run_cmake_command(StdinNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StdinNoexist.cmake) +run_cmake_command(StdoutNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StdoutNoexist.cmake) +run_cmake_command(StderrNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StderrNoexist.cmake) +run_cmake_command(StdoutStderrNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StderrNoexist.cmake) +run_cmake_command(InOutErrDirectory ${CMAKE_COMMAND} -DPRINT_STDIN_EXE=${PRINT_STDIN_EXE} -P ${RunCMake_SOURCE_DIR}/InOutErrDirectory.cmake) if(UNIX AND Python_EXECUTABLE) run_cmake_command(AnyCommandAbnormalExit ${CMAKE_COMMAND} -DPython_EXECUTABLE=${Python_EXECUTABLE} -P ${RunCMake_SOURCE_DIR}/AnyCommandAbnormalExit.cmake) diff --git a/Tests/RunCMake/execute_process/StderrNoexist.cmake b/Tests/RunCMake/execute_process/StderrNoexist.cmake new file mode 100644 index 0000000..632c4a2 --- /dev/null +++ b/Tests/RunCMake/execute_process/StderrNoexist.cmake @@ -0,0 +1 @@ +execute_process(COMMAND ${CMAKE_COMMAND} -E true ERROR_FILE noexist/error.txt) diff --git a/Tests/RunCMake/execute_process/StdinNoexist.cmake b/Tests/RunCMake/execute_process/StdinNoexist.cmake new file mode 100644 index 0000000..6421cc8 --- /dev/null +++ b/Tests/RunCMake/execute_process/StdinNoexist.cmake @@ -0,0 +1 @@ +execute_process(COMMAND ${CMAKE_COMMAND} -E true INPUT_FILE noexist/input.txt) diff --git a/Tests/RunCMake/execute_process/StdouStderrNoexist.cmake b/Tests/RunCMake/execute_process/StdouStderrNoexist.cmake new file mode 100644 index 0000000..5334cdc --- /dev/null +++ b/Tests/RunCMake/execute_process/StdouStderrNoexist.cmake @@ -0,0 +1 @@ +execute_process(COMMAND ${CMAKE_COMMAND} -E true OUTPUT_FILE noexist/merged.txt ERROR_FILE noexist/merged.txt) diff --git a/Tests/RunCMake/execute_process/StdoutNoexist.cmake b/Tests/RunCMake/execute_process/StdoutNoexist.cmake new file mode 100644 index 0000000..4f5c33e --- /dev/null +++ b/Tests/RunCMake/execute_process/StdoutNoexist.cmake @@ -0,0 +1 @@ +execute_process(COMMAND ${CMAKE_COMMAND} -E true OUTPUT_FILE noexist/output.txt) |