diff options
25 files changed, 133 insertions, 20 deletions
diff --git a/Help/command/install.rst b/Help/command/install.rst index 993cf7f..2259176 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -619,7 +619,7 @@ Custom Installation Logic .. code-block:: cmake install([[SCRIPT <file>] [CODE <code>]] - [COMPONENT <component>] [EXCLUDE_FROM_ALL] [...]) + [COMPONENT <component>] [EXCLUDE_FROM_ALL] [ALL_COMPONENTS] [...]) The ``SCRIPT`` form will invoke the given CMake script files during installation. If the script file name is a relative path it will be @@ -634,6 +634,12 @@ example, the code will print a message during installation. +The option ``ALL_COMPONENTS`` + .. versionadded:: 3.21 + + Run the custom installation script code for every component of a + component-specific installation. + .. versionadded:: 3.14 ``<file>`` or ``<code>`` may use "generator expressions" with the syntax ``$<...>`` (in the case of ``<file>``, this refers to their use in the file diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst index 445ebeb..0e530bc 100644 --- a/Help/manual/cmake-file-api.7.rst +++ b/Help/manual/cmake-file-api.7.rst @@ -751,6 +751,11 @@ with members: Optional member that is present with boolean value ``true`` when :command:`install` is called with the ``EXCLUDE_FROM_ALL`` option. + ``isForAllComponents`` + Optional member that is present with boolean value ``true`` when + :command:`install(SCRIPT|CODE)` is called with the + ``ALL_COMPONENTS`` option. + ``isOptional`` Optional member that is present with boolean value ``true`` when :command:`install` is called with the ``OPTIONAL`` option. diff --git a/Help/release/dev/install-script-all-components.rst b/Help/release/dev/install-script-all-components.rst new file mode 100644 index 0000000..e421d3d --- /dev/null +++ b/Help/release/dev/install-script-all-components.rst @@ -0,0 +1,7 @@ +install-script-all-components +----------------------------- + +* The :command:`install(SCRIPT|CODE)` command + supports a new option ``ALL_COMPONENTS`` which allows + the corresponding code to run for every component of + a per component installation. diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 6b35842..945b547 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -1016,6 +1016,11 @@ Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen) if (gen->GetExcludeFromAll()) { installer["isExcludeFromAll"] = true; } + + if (gen->GetAllComponentsFlag()) { + installer["isForAllComponents"] = true; + } + this->AddBacktrace(installer, gen->GetBacktrace()); return installer; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index d5d6d93..e973764 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -161,6 +161,7 @@ bool HandleScriptMode(std::vector<std::string> const& args, bool doing_script = false; bool doing_code = false; bool exclude_from_all = false; + bool all_components = false; // Scan the args once for COMPONENT. Only allow one. // @@ -172,6 +173,8 @@ bool HandleScriptMode(std::vector<std::string> const& args, } if (args[i] == "EXCLUDE_FROM_ALL") { exclude_from_all = true; + } else if (args[i] == "ALL_COMPONENTS") { + all_components = true; } } @@ -182,6 +185,11 @@ bool HandleScriptMode(std::vector<std::string> const& args, return false; } + if (all_components && componentCount == 1) { + status.SetError("ALL_COMPONENTS and COMPONENT are mutually exclusive"); + return false; + } + // Scan the args again, this time adding install generators each time we // encounter a SCRIPT or CODE arg: // @@ -208,14 +216,14 @@ bool HandleScriptMode(std::vector<std::string> const& args, } helper.Makefile->AddInstallGenerator( cm::make_unique<cmInstallScriptGenerator>( - script, false, component, exclude_from_all, + script, false, component, exclude_from_all, all_components, helper.Makefile->GetBacktrace())); } else if (doing_code) { doing_code = false; std::string const& code = arg; helper.Makefile->AddInstallGenerator( cm::make_unique<cmInstallScriptGenerator>( - code, true, component, exclude_from_all, + code, true, component, exclude_from_all, all_components, helper.Makefile->GetBacktrace())); } } diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index 4eb5f69..86362e4 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -18,7 +18,7 @@ cmInstallDirectoryGenerator::cmInstallDirectoryGenerator( MessageLevel message, bool exclude_from_all, std::string literal_args, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , LocalGenerator(nullptr) , Directories(dirs) , FilePermissions(std::move(file_permissions)) diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index fdc3f8c..ccefd92 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -26,7 +26,7 @@ cmInstallExportGenerator::cmInstallExportGenerator( std::string filename, std::string name_space, bool exportOld, bool android, cmListFileBacktrace backtrace) : cmInstallGenerator(destination, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , ExportSet(exportSet) , FilePermissions(std::move(file_permissions)) , FileName(std::move(filename)) diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 556c938..04aaa29 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -17,7 +17,7 @@ cmInstallFilesGenerator::cmInstallFilesGenerator( MessageLevel message, bool exclude_from_all, std::string rename, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , LocalGenerator(nullptr) , Files(files) , FilePermissions(std::move(file_permissions)) diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 98e3766..cf5f45e 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -11,12 +11,13 @@ cmInstallGenerator::cmInstallGenerator( std::string destination, std::vector<std::string> const& configurations, std::string component, MessageLevel message, bool exclude_from_all, - cmListFileBacktrace backtrace) + bool all_components, cmListFileBacktrace backtrace) : cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations) , Destination(std::move(destination)) , Component(std::move(component)) , Message(message) , ExcludeFromAll(exclude_from_all) + , AllComponents(all_components) , Backtrace(std::move(backtrace)) { } @@ -160,15 +161,20 @@ void cmInstallGenerator::GenerateScript(std::ostream& os) Indent indent; // Begin this block of installation. - std::string component_test = - this->CreateComponentTest(this->Component, this->ExcludeFromAll); - os << indent << "if(" << component_test << ")\n"; + if (!this->AllComponents) { + std::string component_test = + this->CreateComponentTest(this->Component, this->ExcludeFromAll); + os << indent << "if(" << component_test << ")\n"; + } // Generate the script possibly with per-configuration code. - this->GenerateScriptConfigs(os, indent.Next()); + this->GenerateScriptConfigs(os, + this->AllComponents ? indent : indent.Next()); // End this block of installation. - os << indent << "endif()\n\n"; + if (!this->AllComponents) { + os << indent << "endif()\n\n"; + } } bool cmInstallGenerator::InstallsForConfig(const std::string& config) diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h index 6cd9ff9..0117617 100644 --- a/Source/cmInstallGenerator.h +++ b/Source/cmInstallGenerator.h @@ -33,7 +33,8 @@ public: cmInstallGenerator(std::string destination, std::vector<std::string> const& configurations, std::string component, MessageLevel message, - bool exclude_from_all, cmListFileBacktrace backtrace); + bool exclude_from_all, bool all_components, + cmListFileBacktrace backtrace); ~cmInstallGenerator() override; cmInstallGenerator(cmInstallGenerator const&) = delete; @@ -65,6 +66,7 @@ public: std::string const& GetComponent() const { return this->Component; } bool GetExcludeFromAll() const { return this->ExcludeFromAll; } + bool GetAllComponentsFlag() const { return this->AllComponents; } cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; } @@ -79,5 +81,6 @@ protected: std::string const Component; MessageLevel const Message; bool const ExcludeFromAll; + bool const AllComponents; cmListFileBacktrace const Backtrace; }; diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index bb38990..bec98b6 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -14,9 +14,10 @@ cmInstallScriptGenerator::cmInstallScriptGenerator( std::string script, bool code, std::string const& component, - bool exclude_from_all, cmListFileBacktrace backtrace) + bool exclude_from_all, bool all_components, cmListFileBacktrace backtrace) : cmInstallGenerator("", std::vector<std::string>(), component, - MessageDefault, exclude_from_all, std::move(backtrace)) + MessageDefault, exclude_from_all, all_components, + std::move(backtrace)) , Script(std::move(script)) , Code(code) , AllowGenex(false) diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h index 6274f1c..2cf6a4b 100644 --- a/Source/cmInstallScriptGenerator.h +++ b/Source/cmInstallScriptGenerator.h @@ -21,7 +21,7 @@ class cmInstallScriptGenerator : public cmInstallGenerator public: cmInstallScriptGenerator( std::string script, bool code, std::string const& component, - bool exclude_from_all, + bool exclude_from_all, bool all_components, cmListFileBacktrace backtrace = cmListFileBacktrace()); ~cmInstallScriptGenerator() override; diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx index 76806e5..0fcfa54 100644 --- a/Source/cmInstallSubdirectoryGenerator.cxx +++ b/Source/cmInstallSubdirectoryGenerator.cxx @@ -17,7 +17,7 @@ cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator( cmMakefile* makefile, std::string binaryDirectory, bool excludeFromAll, cmListFileBacktrace backtrace) : cmInstallGenerator("", std::vector<std::string>(), "", MessageDefault, - excludeFromAll, std::move(backtrace)) + excludeFromAll, false, std::move(backtrace)) , Makefile(makefile) , BinaryDirectory(std::move(binaryDirectory)) { diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index eb214fa..3e79ad8 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -46,7 +46,7 @@ cmInstallTargetGenerator::cmInstallTargetGenerator( std::string const& component, MessageLevel message, bool exclude_from_all, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , TargetName(std::move(targetName)) , Target(nullptr) , FilePermissions(std::move(file_permissions)) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4db9216..0c686aa 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -3317,7 +3317,7 @@ void cmLocalGenerator::GenerateTargetInstallRules( // Include the user-specified pre-install script for this target. if (cmProp preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) { - cmInstallScriptGenerator g(*preinstall, false, "", false); + cmInstallScriptGenerator g(*preinstall, false, "", false, false); g.Generate(os, config, configurationTypes); } @@ -3370,7 +3370,7 @@ void cmLocalGenerator::GenerateTargetInstallRules( // Include the user-specified post-install script for this target. if (cmProp postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) { - cmInstallScriptGenerator g(*postinstall, false, "", false); + cmInstallScriptGenerator g(*postinstall, false, "", false, false); g.Generate(os, config, configurationTypes); } } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index 0d718a4..b9a1fbf 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -136,6 +136,10 @@ def check_directory(c): expected_keys.append("isExcludeFromAll") assert is_bool(a["isExcludeFromAll"], e["isExcludeFromAll"]) + if e["isForAllComponents"] is not None: + expected_keys.append("isForAllComponents") + assert is_bool(a["isForAllComponents"], e["isForAllComponents"]) + if e["isOptional"] is not None: expected_keys.append("isOptional") assert is_bool(a["isOptional"], e["isOptional"]) diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json index 55dd573..6d2952d 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json @@ -20,6 +20,7 @@ "^.*/Tests/RunCMake/FileAPIExternalSource/\\.$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -51,6 +52,7 @@ "^.*/Tests/RunCMake/FileAPIExternalSource$" ], "isExcludeFromAll": true, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json index ef2dd0b..44bc725 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json @@ -23,6 +23,7 @@ "^object/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?c_object_exe(\\.exe)?$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^c_object_exe::@5ed5358f70faf8d8af7a$", "targetIndex": "c_object_exe", @@ -54,6 +55,7 @@ "^object/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?cxx_object_exe(\\.exe)?$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^cxx_object_exe::@5ed5358f70faf8d8af7a$", "targetIndex": "cxx_object_exe", diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json index 4727607..99287fb 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json @@ -35,6 +35,7 @@ "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?cxx_exe(\\.exe)?$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^cxx_exe::@a56b12a3f5c0529fb296$", "targetIndex": "cxx_exe", @@ -78,6 +79,7 @@ "^((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(lib|dll\\.a)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", "targetIndex": "c_shared_lib", @@ -126,6 +128,7 @@ "^lib/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(so\\.1|1\\.dylib)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", "targetIndex": "c_shared_lib", @@ -169,6 +172,7 @@ "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?cxx_shared_lib\\.(lib|dll\\.a)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^cxx_shared_lib::@a56b12a3f5c0529fb296$", "targetIndex": "cxx_shared_lib", @@ -213,6 +217,7 @@ "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib|cyg|msys-)?cxx_shared_lib\\.(dll|so|dylib)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^cxx_shared_lib::@a56b12a3f5c0529fb296$", "targetIndex": "cxx_shared_lib", @@ -256,6 +261,7 @@ "^lib/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(dll|so|dylib)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", "targetIndex": "c_shared_lib", @@ -302,6 +308,7 @@ } ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": true, "targetId": null, "targetIndex": null, @@ -346,6 +353,7 @@ "^empty\\.h$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -394,6 +402,7 @@ } ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": true, "targetId": null, "targetIndex": null, @@ -445,6 +454,7 @@ } ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -488,6 +498,7 @@ "^CMakeFiles/Export/lib/cmake/foo/FooTargets\\.cmake$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -534,6 +545,7 @@ "destination": null, "paths": null, "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -568,6 +580,48 @@ "hasParent": false } ] + }, + { + "component": "Unspecified", + "type": "code", + "destination": null, + "paths": null, + "isExcludeFromAll": null, + "isForAllComponents": true, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 54, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] } ] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake index 528f075..da928eb 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake +++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake @@ -51,3 +51,4 @@ install(DIRECTORY . dir cxx/ OPTIONAL DESTINATION dir1) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}/cxx/" DESTINATION dir2) install(EXPORT FooTargets DESTINATION lib/cmake/foo) install(SCRIPT InstallScript.cmake) +install(CODE "message(foo)" ALL_COMPONENTS) diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index 3e56746..94887a0 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -179,3 +179,4 @@ run_install_test(FILES-EXCLUDE_FROM_ALL) run_install_test(TARGETS-EXCLUDE_FROM_ALL) run_install_test(TARGETS-NAMELINK_COMPONENT) run_install_test(SCRIPT-COMPONENT) +run_install_test(SCRIPT-ALL_COMPONENTS) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake new file mode 100644 index 0000000..aa3f9d1 --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake @@ -0,0 +1,5 @@ +install( + SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/install_script.cmake" + CODE "write_empty_file(empty2.txt)" + ALL_COMPONENTS + ) |