mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
install: Implement new install(CODE|SCRIPT) option ALL_COMPONENTS
In a per-component installation the generated installation scripts are invoked once for each component. Per default custom installation script code added by install(CODE|SCRIPT) only runs for one specific component in this context. The new ALL_COMPONENTS option allows custom script code to be run once for each component being installed.
This commit is contained in:
@@ -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
|
||||
|
@@ -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.
|
||||
|
7
Help/release/dev/install-script-all-components.rst
Normal file
7
Help/release/dev/install-script-all-components.rst
Normal file
@@ -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.
|
@@ -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;
|
||||
|
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
@@ -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))
|
||||
|
@@ -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))
|
||||
|
@@ -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))
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
};
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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))
|
||||
{
|
||||
|
@@ -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))
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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"])
|
||||
|
@@ -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,
|
||||
|
@@ -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",
|
||||
|
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -0,0 +1 @@
|
||||
check_installed([[^empty1.txt;empty2.txt$]])
|
@@ -0,0 +1 @@
|
||||
check_installed([[^empty1.txt;empty2.txt$]])
|
@@ -0,0 +1 @@
|
||||
check_installed([[^empty1.txt;empty2.txt$]])
|
5
Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake
Normal file
5
Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
install(
|
||||
SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/install_script.cmake"
|
||||
CODE "write_empty_file(empty2.txt)"
|
||||
ALL_COMPONENTS
|
||||
)
|
Reference in New Issue
Block a user