mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-13 17:47:49 +08:00
install(): Add IMPORTED_RUNTIME_ARTIFACTS mode
This commit is contained in:
@@ -9,6 +9,7 @@ Synopsis
|
||||
.. parsed-literal::
|
||||
|
||||
install(`TARGETS`_ <target>... [...])
|
||||
install(`IMPORTED_RUNTIME_ARTIFACTS`_ <target>... [...])
|
||||
install({`FILES`_ | `PROGRAMS`_} <file>... [...])
|
||||
install(`DIRECTORY`_ <dir>... [...])
|
||||
install(`SCRIPT`_ <file> [...])
|
||||
@@ -382,6 +383,38 @@ set to ``TRUE`` has undefined behavior.
|
||||
to ensure that such out-of-directory targets are built before the
|
||||
subdirectory-specific install rules are run.
|
||||
|
||||
Installing Imported Runtime Artifacts
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. _`install(IMPORTED_RUNTIME_ARTIFACTS)`:
|
||||
.. _IMPORTED_RUNTIME_ARTIFACTS:
|
||||
|
||||
.. versionadded:: 3.21
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
install(IMPORTED_RUNTIME_ARTIFACTS targets...
|
||||
[[LIBRARY|RUNTIME|FRAMEWORK|BUNDLE]
|
||||
[DESTINATION <dir>]
|
||||
[PERMISSIONS permissions...]
|
||||
[CONFIGURATIONS [Debug|Release|...]]
|
||||
[COMPONENT <component>]
|
||||
[OPTIONAL] [EXCLUDE_FROM_ALL]
|
||||
] [...]
|
||||
)
|
||||
|
||||
The ``IMPORTED_RUNTIME_ARTIFACTS`` form specifies rules for installing the
|
||||
runtime artifacts of imported targets. Projects may do this if they want to
|
||||
bundle outside executables or modules inside their installation. The
|
||||
``LIBRARY``, ``RUNTIME``, ``FRAMEWORK``, and ``BUNDLE`` arguments have the
|
||||
same semantics that they do in the `TARGETS`_ mode. Only the runtime artifacts
|
||||
of imported targets are installed (except in the case of :prop_tgt:`FRAMEWORK`
|
||||
libraries, :prop_tgt:`MACOSX_BUNDLE` executables, and :prop_tgt:`BUNDLE`
|
||||
CFBundles.) For example, headers and import libraries associated with DLLs are
|
||||
not installed. In the case of :prop_tgt:`FRAMEWORK` libraries,
|
||||
:prop_tgt:`MACOSX_BUNDLE` executables, and :prop_tgt:`BUNDLE` CFBundles, the
|
||||
entire directory is installed.
|
||||
|
||||
Installing Files
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
|
5
Help/release/dev/install-imported-runtime-artifacts.rst
Normal file
5
Help/release/dev/install-imported-runtime-artifacts.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
install-imported-runtime-artifacts
|
||||
----------------------------------
|
||||
|
||||
* The :command:`install` command gained a new ``IMPORTED_RUNTIME_ARTIFACTS``
|
||||
mode, which can be used to install the runtime artifacts of imported targets.
|
@@ -350,6 +350,8 @@ set(SRCS
|
||||
cmInstalledFile.cxx
|
||||
cmInstallFilesGenerator.h
|
||||
cmInstallFilesGenerator.cxx
|
||||
cmInstallImportedRuntimeArtifactsGenerator.h
|
||||
cmInstallImportedRuntimeArtifactsGenerator.cxx
|
||||
cmInstallScriptGenerator.h
|
||||
cmInstallScriptGenerator.cxx
|
||||
cmInstallSubdirectoryGenerator.h
|
||||
|
@@ -2,6 +2,7 @@
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmInstallCommand.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
@@ -22,6 +23,7 @@
|
||||
#include "cmInstallExportGenerator.h"
|
||||
#include "cmInstallFilesGenerator.h"
|
||||
#include "cmInstallGenerator.h"
|
||||
#include "cmInstallImportedRuntimeArtifactsGenerator.h"
|
||||
#include "cmInstallScriptGenerator.h"
|
||||
#include "cmInstallTargetGenerator.h"
|
||||
#include "cmListFileCache.h"
|
||||
@@ -865,6 +867,227 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleImportedRuntimeArtifactsMode(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
Helper helper(status);
|
||||
|
||||
// This is the IMPORTED_RUNTIME_ARTIFACTS mode.
|
||||
std::vector<cmTarget*> targets;
|
||||
|
||||
struct ArgVectors
|
||||
{
|
||||
std::vector<std::string> Library;
|
||||
std::vector<std::string> Runtime;
|
||||
std::vector<std::string> Framework;
|
||||
std::vector<std::string> Bundle;
|
||||
};
|
||||
|
||||
static auto const argHelper = cmArgumentParser<ArgVectors>{}
|
||||
.Bind("LIBRARY"_s, &ArgVectors::Library)
|
||||
.Bind("RUNTIME"_s, &ArgVectors::Runtime)
|
||||
.Bind("FRAMEWORK"_s, &ArgVectors::Framework)
|
||||
.Bind("BUNDLE"_s, &ArgVectors::Bundle);
|
||||
|
||||
std::vector<std::string> genericArgVector;
|
||||
ArgVectors const argVectors = argHelper.Parse(args, &genericArgVector);
|
||||
|
||||
// now parse the generic args (i.e. the ones not specialized on LIBRARY,
|
||||
// RUNTIME etc. (see above)
|
||||
std::vector<std::string> targetList;
|
||||
std::vector<std::string> unknownArgs;
|
||||
cmInstallCommandArguments genericArgs(helper.DefaultComponentName);
|
||||
genericArgs.Bind("IMPORTED_RUNTIME_ARTIFACTS"_s, targetList);
|
||||
genericArgs.Parse(genericArgVector, &unknownArgs);
|
||||
bool success = genericArgs.Finalize();
|
||||
|
||||
cmInstallCommandArguments libraryArgs(helper.DefaultComponentName);
|
||||
cmInstallCommandArguments runtimeArgs(helper.DefaultComponentName);
|
||||
cmInstallCommandArguments frameworkArgs(helper.DefaultComponentName);
|
||||
cmInstallCommandArguments bundleArgs(helper.DefaultComponentName);
|
||||
|
||||
// now parse the args for specific parts of the target (e.g. LIBRARY,
|
||||
// RUNTIME etc.
|
||||
libraryArgs.Parse(argVectors.Library, &unknownArgs);
|
||||
runtimeArgs.Parse(argVectors.Runtime, &unknownArgs);
|
||||
frameworkArgs.Parse(argVectors.Framework, &unknownArgs);
|
||||
bundleArgs.Parse(argVectors.Bundle, &unknownArgs);
|
||||
|
||||
if (!unknownArgs.empty()) {
|
||||
// Unknown argument.
|
||||
status.SetError(
|
||||
cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given unknown argument \"",
|
||||
unknownArgs[0], "\"."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// apply generic args
|
||||
libraryArgs.SetGenericArguments(&genericArgs);
|
||||
runtimeArgs.SetGenericArguments(&genericArgs);
|
||||
frameworkArgs.SetGenericArguments(&genericArgs);
|
||||
bundleArgs.SetGenericArguments(&genericArgs);
|
||||
|
||||
success = success && libraryArgs.Finalize();
|
||||
success = success && runtimeArgs.Finalize();
|
||||
success = success && frameworkArgs.Finalize();
|
||||
success = success && bundleArgs.Finalize();
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if there is something to do.
|
||||
if (targetList.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (std::string const& tgt : targetList) {
|
||||
if (helper.Makefile->IsAlias(tgt)) {
|
||||
status.SetError(cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given target \"",
|
||||
tgt, "\" which is an alias."));
|
||||
return false;
|
||||
}
|
||||
// Lookup this target in the current directory.
|
||||
cmTarget* target = helper.Makefile->FindTargetToUse(tgt);
|
||||
if (!target || !target->IsImported()) {
|
||||
// If no local target has been found, find it in the global scope.
|
||||
cmTarget* const global_target =
|
||||
helper.Makefile->GetGlobalGenerator()->FindTarget(tgt, true);
|
||||
if (global_target && global_target->IsImported()) {
|
||||
target = global_target;
|
||||
}
|
||||
}
|
||||
if (target) {
|
||||
// Found the target. Check its type.
|
||||
if (target->GetType() != cmStateEnums::EXECUTABLE &&
|
||||
target->GetType() != cmStateEnums::SHARED_LIBRARY &&
|
||||
target->GetType() != cmStateEnums::MODULE_LIBRARY) {
|
||||
status.SetError(
|
||||
cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given target \"", tgt,
|
||||
"\" which is not an executable, library, or module."));
|
||||
return false;
|
||||
}
|
||||
// Store the target in the list to be installed.
|
||||
targets.push_back(target);
|
||||
} else {
|
||||
// Did not find the target.
|
||||
status.SetError(cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given target \"",
|
||||
tgt, "\" which does not exist."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep track of whether we will be performing an installation of
|
||||
// any files of the given type.
|
||||
bool installsLibrary = false;
|
||||
bool installsRuntime = false;
|
||||
bool installsFramework = false;
|
||||
bool installsBundle = false;
|
||||
|
||||
auto const createInstallGenerator =
|
||||
[helper](cmTarget& target, const cmInstallCommandArguments& typeArgs,
|
||||
const std::string& destination)
|
||||
-> std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator> {
|
||||
return cm::make_unique<cmInstallImportedRuntimeArtifactsGenerator>(
|
||||
target.GetName(), destination, typeArgs.GetPermissions(),
|
||||
typeArgs.GetConfigurations(), typeArgs.GetComponent(),
|
||||
cmInstallGenerator::SelectMessageLevel(helper.Makefile),
|
||||
typeArgs.GetExcludeFromAll(), typeArgs.GetOptional(),
|
||||
helper.Makefile->GetBacktrace());
|
||||
};
|
||||
|
||||
// Generate install script code to install the given targets.
|
||||
for (cmTarget* ti : targets) {
|
||||
// Handle each target type.
|
||||
cmTarget& target = *ti;
|
||||
std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator>
|
||||
libraryGenerator;
|
||||
std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator>
|
||||
runtimeGenerator;
|
||||
std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator>
|
||||
frameworkGenerator;
|
||||
std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator>
|
||||
bundleGenerator;
|
||||
|
||||
switch (target.GetType()) {
|
||||
case cmStateEnums::SHARED_LIBRARY:
|
||||
if (target.IsDLLPlatform()) {
|
||||
runtimeGenerator = createInstallGenerator(
|
||||
target, runtimeArgs, helper.GetRuntimeDestination(&runtimeArgs));
|
||||
} else if (target.IsFrameworkOnApple()) {
|
||||
if (frameworkArgs.GetDestination().empty()) {
|
||||
status.SetError(cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given no "
|
||||
"FRAMEWORK DESTINATION for shared "
|
||||
"library FRAMEWORK target \"",
|
||||
target.GetName(), "\"."));
|
||||
return false;
|
||||
}
|
||||
frameworkGenerator = createInstallGenerator(
|
||||
target, frameworkArgs, frameworkArgs.GetDestination());
|
||||
} else {
|
||||
libraryGenerator = createInstallGenerator(
|
||||
target, libraryArgs, helper.GetLibraryDestination(&libraryArgs));
|
||||
}
|
||||
break;
|
||||
case cmStateEnums::MODULE_LIBRARY:
|
||||
libraryGenerator = createInstallGenerator(
|
||||
target, libraryArgs, helper.GetLibraryDestination(&libraryArgs));
|
||||
break;
|
||||
case cmStateEnums::EXECUTABLE:
|
||||
if (target.IsAppBundleOnApple()) {
|
||||
if (bundleArgs.GetDestination().empty()) {
|
||||
status.SetError(
|
||||
cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given no BUNDLE "
|
||||
"DESTINATION for MACOSX_BUNDLE executable target \"",
|
||||
target.GetName(), "\"."));
|
||||
return false;
|
||||
}
|
||||
bundleGenerator = createInstallGenerator(
|
||||
target, bundleArgs, bundleArgs.GetDestination());
|
||||
} else {
|
||||
runtimeGenerator = createInstallGenerator(
|
||||
target, runtimeArgs, helper.GetRuntimeDestination(&runtimeArgs));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false && "This should never happen");
|
||||
break;
|
||||
}
|
||||
|
||||
// Keep track of whether we're installing anything in each category
|
||||
installsLibrary = installsLibrary || libraryGenerator;
|
||||
installsRuntime = installsRuntime || runtimeGenerator;
|
||||
installsFramework = installsFramework || frameworkGenerator;
|
||||
installsBundle = installsBundle || bundleGenerator;
|
||||
|
||||
helper.Makefile->AddInstallGenerator(std::move(libraryGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(runtimeGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(frameworkGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(bundleGenerator));
|
||||
}
|
||||
|
||||
// Tell the global generator about any installation component names
|
||||
// specified
|
||||
if (installsLibrary) {
|
||||
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||
libraryArgs.GetComponent());
|
||||
}
|
||||
if (installsRuntime) {
|
||||
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||
runtimeArgs.GetComponent());
|
||||
}
|
||||
if (installsFramework) {
|
||||
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||
frameworkArgs.GetComponent());
|
||||
}
|
||||
if (installsBundle) {
|
||||
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||
bundleArgs.GetComponent());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleFilesMode(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
@@ -1705,6 +1928,7 @@ bool cmInstallCommand(std::vector<std::string> const& args,
|
||||
{ "SCRIPT"_s, HandleScriptMode },
|
||||
{ "CODE"_s, HandleScriptMode },
|
||||
{ "TARGETS"_s, HandleTargetsMode },
|
||||
{ "IMPORTED_RUNTIME_ARTIFACTS"_s, HandleImportedRuntimeArtifactsMode },
|
||||
{ "FILES"_s, HandleFilesMode },
|
||||
{ "PROGRAMS"_s, HandleFilesMode },
|
||||
{ "DIRECTORY"_s, HandleDirectoryMode },
|
||||
|
146
Source/cmInstallImportedRuntimeArtifactsGenerator.cxx
Normal file
146
Source/cmInstallImportedRuntimeArtifactsGenerator.cxx
Normal file
@@ -0,0 +1,146 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmInstallImportedRuntimeArtifactsGenerator.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "cmsys/RegularExpression.hxx"
|
||||
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmInstallType.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
|
||||
namespace {
|
||||
const cmsys::RegularExpression FrameworkRegularExpression(
|
||||
"^(.*/)?([^/]*)\\.framework/(.*)$");
|
||||
|
||||
const cmsys::RegularExpression BundleRegularExpression(
|
||||
"^(.*/)?([^/]*)\\.app/(.*)$");
|
||||
|
||||
const cmsys::RegularExpression CFBundleRegularExpression(
|
||||
"^(.*/)?([^/]*)\\.bundle/(.*)$");
|
||||
}
|
||||
|
||||
cmInstallImportedRuntimeArtifactsGenerator::
|
||||
cmInstallImportedRuntimeArtifactsGenerator(
|
||||
std::string targetName, std::string const& dest,
|
||||
std::string file_permissions,
|
||||
std::vector<std::string> const& configurations,
|
||||
std::string const& component, MessageLevel message, bool exclude_from_all,
|
||||
bool optional, cmListFileBacktrace backtrace)
|
||||
: cmInstallGenerator(dest, configurations, component, message,
|
||||
exclude_from_all, false, std::move(backtrace))
|
||||
, TargetName(std::move(targetName))
|
||||
, FilePermissions(std::move(file_permissions))
|
||||
, Optional(optional)
|
||||
{
|
||||
this->ActionsPerConfig = true;
|
||||
}
|
||||
|
||||
bool cmInstallImportedRuntimeArtifactsGenerator::Compute(cmLocalGenerator* lg)
|
||||
{
|
||||
// Lookup this target in the current directory.
|
||||
this->Target = lg->FindGeneratorTargetToUse(this->TargetName);
|
||||
if (!this->Target || !this->Target->IsImported()) {
|
||||
// If no local target has been found, find it in the global scope.
|
||||
this->Target =
|
||||
lg->GetGlobalGenerator()->FindGeneratorTarget(this->TargetName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string cmInstallImportedRuntimeArtifactsGenerator::GetDestination(
|
||||
std::string const& config) const
|
||||
{
|
||||
return cmGeneratorExpression::Evaluate(
|
||||
this->Destination, this->Target->GetLocalGenerator(), config);
|
||||
}
|
||||
|
||||
void cmInstallImportedRuntimeArtifactsGenerator::GenerateScriptForConfig(
|
||||
std::ostream& os, const std::string& config, Indent indent)
|
||||
{
|
||||
auto location = this->Target->GetFullPath(config);
|
||||
|
||||
switch (this->Target->GetType()) {
|
||||
case cmStateEnums::EXECUTABLE:
|
||||
if (this->Target->IsBundleOnApple()) {
|
||||
cmsys::RegularExpressionMatch match;
|
||||
if (BundleRegularExpression.find(location.c_str(), match)) {
|
||||
auto bundleDir = match.match(1);
|
||||
auto bundleName = match.match(2);
|
||||
auto bundlePath = cmStrCat(bundleDir, bundleName, ".app");
|
||||
this->AddInstallRule(os, this->GetDestination(config),
|
||||
cmInstallType_DIRECTORY, { bundlePath },
|
||||
this->Optional, nullptr,
|
||||
this->FilePermissions.c_str(), nullptr,
|
||||
" USE_SOURCE_PERMISSIONS", indent);
|
||||
}
|
||||
} else {
|
||||
this->AddInstallRule(os, this->GetDestination(config),
|
||||
cmInstallType_EXECUTABLE, { location },
|
||||
this->Optional, this->FilePermissions.c_str(),
|
||||
nullptr, nullptr, nullptr, indent);
|
||||
}
|
||||
break;
|
||||
case cmStateEnums::SHARED_LIBRARY:
|
||||
if (this->Target->IsFrameworkOnApple()) {
|
||||
cmsys::RegularExpressionMatch match;
|
||||
if (FrameworkRegularExpression.find(location.c_str(), match)) {
|
||||
auto frameworkDir = match.match(1);
|
||||
auto frameworkName = match.match(2);
|
||||
auto frameworkPath =
|
||||
cmStrCat(frameworkDir, frameworkName, ".framework");
|
||||
this->AddInstallRule(os, this->GetDestination(config),
|
||||
cmInstallType_DIRECTORY, { frameworkPath },
|
||||
this->Optional, nullptr,
|
||||
this->FilePermissions.c_str(), nullptr,
|
||||
" USE_SOURCE_PERMISSIONS", indent);
|
||||
}
|
||||
} else {
|
||||
std::vector<std::string> files{ location };
|
||||
auto soName = this->Target->GetSOName(config);
|
||||
auto soNameFile =
|
||||
cmStrCat(this->Target->GetDirectory(config), '/', soName);
|
||||
if (!soName.empty() && soNameFile != location) {
|
||||
files.push_back(soNameFile);
|
||||
}
|
||||
this->AddInstallRule(os, this->GetDestination(config),
|
||||
cmInstallType_SHARED_LIBRARY, files,
|
||||
this->Optional, this->FilePermissions.c_str(),
|
||||
nullptr, nullptr, nullptr, indent);
|
||||
}
|
||||
break;
|
||||
case cmStateEnums::MODULE_LIBRARY:
|
||||
if (this->Target->IsCFBundleOnApple()) {
|
||||
cmsys::RegularExpressionMatch match;
|
||||
if (CFBundleRegularExpression.find(location.c_str(), match)) {
|
||||
auto bundleDir = match.match(1);
|
||||
auto bundleName = match.match(2);
|
||||
auto bundlePath = cmStrCat(bundleDir, bundleName, ".bundle");
|
||||
this->AddInstallRule(os, this->GetDestination(config),
|
||||
cmInstallType_DIRECTORY, { bundlePath },
|
||||
this->Optional, nullptr,
|
||||
this->FilePermissions.c_str(), nullptr,
|
||||
" USE_SOURCE_PERMISSIONS", indent);
|
||||
}
|
||||
} else {
|
||||
this->AddInstallRule(os, this->GetDestination(config),
|
||||
cmInstallType_MODULE_LIBRARY, { location },
|
||||
this->Optional, this->FilePermissions.c_str(),
|
||||
nullptr, nullptr, nullptr, indent);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false && "This should never happen");
|
||||
break;
|
||||
}
|
||||
}
|
44
Source/cmInstallImportedRuntimeArtifactsGenerator.h
Normal file
44
Source/cmInstallImportedRuntimeArtifactsGenerator.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cmInstallGenerator.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmScriptGenerator.h"
|
||||
|
||||
class cmGeneratorTarget;
|
||||
class cmLocalGenerator;
|
||||
|
||||
class cmInstallImportedRuntimeArtifactsGenerator : public cmInstallGenerator
|
||||
{
|
||||
public:
|
||||
cmInstallImportedRuntimeArtifactsGenerator(
|
||||
std::string targetName, std::string const& dest,
|
||||
std::string file_permissions,
|
||||
std::vector<std::string> const& configurations,
|
||||
std::string const& component, MessageLevel message, bool exclude_from_all,
|
||||
bool optional, cmListFileBacktrace backtrace = cmListFileBacktrace());
|
||||
~cmInstallImportedRuntimeArtifactsGenerator() override = default;
|
||||
|
||||
bool Compute(cmLocalGenerator* lg) override;
|
||||
|
||||
cmGeneratorTarget* GetTarget() const { return this->Target; }
|
||||
|
||||
bool GetOptional() const { return this->Optional; }
|
||||
|
||||
std::string GetDestination(std::string const& config) const;
|
||||
|
||||
protected:
|
||||
void GenerateScriptForConfig(std::ostream& os, const std::string& config,
|
||||
Indent indent) override;
|
||||
|
||||
private:
|
||||
std::string const TargetName;
|
||||
cmGeneratorTarget* Target;
|
||||
std::string const FilePermissions;
|
||||
bool const Optional;
|
||||
};
|
@@ -16,14 +16,12 @@ set_property(
|
||||
)
|
||||
|
||||
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(_isMultiConfig)
|
||||
set(NESTED_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}")
|
||||
if(_isMultiConfig OR CMAKE_BUILD_TYPE)
|
||||
set(NESTED_CONFIG_TYPE -C "$<CONFIG>")
|
||||
set(NESTED_CONFIG_INSTALL_TYPE --config "$<CONFIG>")
|
||||
else()
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
set(NESTED_CONFIG_TYPE -C "${CMAKE_BUILD_TYPE}")
|
||||
else()
|
||||
set(NESTED_CONFIG_TYPE)
|
||||
endif()
|
||||
set(NESTED_CONFIG_TYPE)
|
||||
set(NESTED_CONFIG_INSTALL_TYPE)
|
||||
endif()
|
||||
|
||||
if(MINGW OR MSYS)
|
||||
@@ -79,5 +77,21 @@ set_property(
|
||||
PROPERTY SYMBOLIC 1
|
||||
)
|
||||
|
||||
# Install the imported targets.
|
||||
add_custom_command(
|
||||
OUTPUT ${ExportImport_BINARY_DIR}/ImportInstall
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf ${ExportImport_BINARY_DIR}/Import/install
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
--install ${ExportImport_BINARY_DIR}/Import
|
||||
--prefix ${ExportImport_BINARY_DIR}/Import/install
|
||||
${NESTED_CONFIG_INSTALL_TYPE}
|
||||
)
|
||||
add_custom_target(ImportInstallTarget ALL DEPENDS ${ExportImport_BINARY_DIR}/ImportInstall)
|
||||
add_dependencies(ImportInstallTarget ImportTarget)
|
||||
set_property(
|
||||
SOURCE ${ExportImport_BINARY_DIR}/ImportInstall
|
||||
PROPERTY SYMBOLIC 1
|
||||
)
|
||||
|
||||
add_executable(ExportImport main.c)
|
||||
add_dependencies(ExportImport ImportTarget)
|
||||
|
@@ -395,6 +395,10 @@ target_include_directories(systemlib
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
||||
add_library(testMod1 MODULE empty.cpp)
|
||||
add_library(testMod2 MODULE empty.cpp)
|
||||
set_property(TARGET testMod2 PROPERTY BUNDLE 1)
|
||||
|
||||
install(TARGETS testLibRequired
|
||||
EXPORT RequiredExp DESTINATION lib
|
||||
INCLUDES DESTINATION
|
||||
@@ -523,6 +527,7 @@ install(
|
||||
testLibDeprecation
|
||||
testLibCycleA testLibCycleB
|
||||
testLibNoSONAME
|
||||
testMod1 testMod2
|
||||
cmp0022NEW cmp0022OLD
|
||||
TopDirLib SubDirLinkA
|
||||
systemlib
|
||||
@@ -595,6 +600,7 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 te
|
||||
testLib4lib testLib4libdbg testLib4libopt
|
||||
testLibCycleA testLibCycleB
|
||||
testLibNoSONAME
|
||||
testMod1 testMod2
|
||||
testLibPerConfigDest
|
||||
NAMESPACE bld_
|
||||
APPEND FILE ExportBuildTree.cmake
|
||||
|
@@ -26,3 +26,6 @@ add_subdirectory(Interface)
|
||||
|
||||
# Test package version range
|
||||
add_subdirectory(version_range)
|
||||
|
||||
# Test install(IMPORTED_RUNTIME_ARTIFACTS)
|
||||
add_subdirectory(install-IMPORTED_RUNTIME_ARTIFACTS)
|
||||
|
@@ -0,0 +1,30 @@
|
||||
# Import targets from the exported build tree.
|
||||
include(${Import_BINARY_DIR}/../Export/ExportBuildTree.cmake)
|
||||
|
||||
set(_tgts
|
||||
bld_testExe1 # Ordinary executable
|
||||
bld_testExe2lib # Ordinary shared library
|
||||
bld_testLib3 # Shared library with version and soversion
|
||||
bld_testLib4 # Framework library
|
||||
bld_testExe3 # Bundle executable
|
||||
bld_testMod1 # Module library
|
||||
bld_testMod2 # CFBundle
|
||||
)
|
||||
|
||||
install(IMPORTED_RUNTIME_ARTIFACTS ${_tgts}
|
||||
RUNTIME DESTINATION aaa/executables
|
||||
LIBRARY DESTINATION aaa/libraries
|
||||
BUNDLE DESTINATION aaa/bundles
|
||||
FRAMEWORK DESTINATION aaa/frameworks
|
||||
)
|
||||
|
||||
install(IMPORTED_RUNTIME_ARTIFACTS ${_tgts}
|
||||
DESTINATION bbb
|
||||
)
|
||||
|
||||
install(IMPORTED_RUNTIME_ARTIFACTS ${_tgts}
|
||||
BUNDLE DESTINATION zzz/bundles
|
||||
FRAMEWORK DESTINATION zzz/frameworks
|
||||
)
|
||||
|
||||
install(SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/check_installed.cmake")
|
@@ -0,0 +1,57 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
function(check_installed expect)
|
||||
file(GLOB_RECURSE actual
|
||||
LIST_DIRECTORIES TRUE
|
||||
RELATIVE ${CMAKE_INSTALL_PREFIX}
|
||||
${CMAKE_INSTALL_PREFIX}/*
|
||||
)
|
||||
if(actual)
|
||||
list(SORT actual)
|
||||
endif()
|
||||
if(NOT "${actual}" MATCHES "${expect}")
|
||||
message(FATAL_ERROR "Installed files:
|
||||
${actual}
|
||||
do not match what we expected:
|
||||
${expect}
|
||||
in directory:
|
||||
${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(_dirs [[aaa;aaa/executables;aaa/executables/testExe1-4;aaa/executables/testExe3;aaa/libraries;aaa/libraries/libtestExe2lib\.so;aaa/libraries/libtestLib3lib(-d|-r)?\.so\.1\.2;aaa/libraries/libtestLib3lib(-d|-r)?\.so\.3;aaa/libraries/libtestLib4\.so;aaa/libraries/libtestMod1\.so;aaa/libraries/libtestMod2\.so]])
|
||||
set(_alldest [[bbb;bbb/libtestExe2lib\.so;bbb/libtestLib3lib(-d|-r)?\.so\.1\.2;bbb/libtestLib3lib(-d|-r)?\.so\.3;bbb/libtestLib4\.so;bbb/libtestMod1\.so;bbb/libtestMod2\.so;bbb/testExe1-4;bbb/testExe3]])
|
||||
set(_default [[bin;bin/testExe1-4;bin/testExe3;lib;lib/libtestExe2lib\.so;lib/libtestLib3lib(-d|-r)?\.so\.1\.2;lib/libtestLib3lib(-d|-r)?\.so\.3;lib/libtestLib4\.so;lib/libtestMod1\.so;lib/libtestMod2\.so]])
|
||||
check_installed("^${_dirs};${_alldest};${_default}$")
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(_dirs_msvc [[aaa;aaa/executables;aaa/executables/testExe1\.exe;aaa/executables/testExe2lib\.dll;aaa/executables/testExe3\.exe;aaa/executables/testLib3dll(-d|-r)?\.dll;aaa/executables/testLib4\.dll;aaa/libraries;aaa/libraries/testMod1\.dll;aaa/libraries/testMod2\.dll]])
|
||||
set(_dirs_mingw [[aaa;aaa/executables;aaa/executables/libtestExe2lib\.dll;aaa/executables/libtestLib3dll(-d|-r)?\.dll;aaa/executables/libtestLib4\.dll;aaa/executables/testExe1\.exe;aaa/executables/testExe3\.exe;aaa/libraries;aaa/libraries/libtestMod1\.dll;aaa/libraries/libtestMod2\.dll]])
|
||||
|
||||
set(_alldest_msvc [[bbb;bbb/testExe1\.exe;bbb/testExe2lib\.dll;bbb/testExe3\.exe;bbb/testLib3dll(-d|-r)?\.dll;bbb/testLib4\.dll;bbb/testMod1\.dll;bbb/testMod2\.dll]])
|
||||
set(_alldest_mingw [[bbb;bbb/libtestExe2lib\.dll;bbb/libtestLib3dll(-d|-r)?\.dll;bbb/libtestLib4\.dll;bbb/libtestMod1\.dll;bbb/libtestMod2\.dll;bbb/testExe1\.exe;bbb/testExe3\.exe]])
|
||||
|
||||
set(_default_msvc [[bin;bin/testExe1\.exe;bin/testExe2lib\.dll;bin/testExe3\.exe;bin/testLib3dll(-d|-r)?\.dll;bin/testLib4\.dll;lib;lib/testMod1\.dll;lib/testMod2\.dll]])
|
||||
set(_default_mingw [[bin;bin/libtestExe2lib\.dll;bin/libtestLib3dll(-d|-r)?\.dll;bin/libtestLib4\.dll;bin/testExe1\.exe;bin/testExe3\.exe;lib;lib/libtestMod1\.dll;lib/libtestMod2\.dll]])
|
||||
|
||||
check_installed("^(${_dirs_msvc};${_alldest_msvc};${_default_msvc}|${_dirs_mingw};${_alldest_mingw};${_default_mingw})$")
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(_bundles [[aaa/bundles;aaa/bundles/testExe3\.app;aaa/bundles/testExe3\.app/Contents;aaa/bundles/testExe3\.app/Contents/Info\.plist;aaa/bundles/testExe3\.app/Contents/MacOS;aaa/bundles/testExe3\.app/Contents/MacOS/testExe3(;aaa/bundles/testExe3\.app/Contents/PkgInfo)?(;aaa/bundles/testExe3\.app/Contents/_CodeSignature;aaa/bundles/testExe3\.app/Contents/_CodeSignature/CodeResources)?]])
|
||||
set(_executables [[aaa/executables;aaa/executables/testExe1(-4)?]])
|
||||
set(_frameworks [[aaa/frameworks;aaa/frameworks/testLib4\.framework;aaa/frameworks/testLib4\.framework/Headers;aaa/frameworks/testLib4\.framework/Headers/testLib4\.h;aaa/frameworks/testLib4\.framework/Resources;aaa/frameworks/testLib4\.framework/Versions;aaa/frameworks/testLib4\.framework/Versions/A;aaa/frameworks/testLib4\.framework/Versions/A/Resources;aaa/frameworks/testLib4\.framework/Versions/A/Resources/Info\.plist(;aaa/frameworks/testLib4\.framework/Versions/A/_CodeSignature;aaa/frameworks/testLib4\.framework/Versions/A/_CodeSignature/CodeResources)?;aaa/frameworks/testLib4\.framework/Versions/A/testLib4;aaa/frameworks/testLib4\.framework/Versions/Current;aaa/frameworks/testLib4\.framework/testLib4]])
|
||||
set(_libraries [[aaa/libraries;aaa/libraries/libtestExe2lib\.dylib;aaa/libraries/libtestLib3lib(-d|-r)?\.1\.2\.dylib;aaa/libraries/libtestLib3lib(-d|-r)?\.3\.dylib;aaa/libraries/libtestMod1\.so;aaa/libraries/testMod2\.bundle;aaa/libraries/testMod2\.bundle/Contents;aaa/libraries/testMod2\.bundle/Contents/Info\.plist;aaa/libraries/testMod2\.bundle/Contents/MacOS;aaa/libraries/testMod2\.bundle/Contents/MacOS/testMod2(;aaa/libraries/testMod2\.bundle/Contents/_CodeSignature;aaa/libraries/testMod2\.bundle/Contents/_CodeSignature/CodeResources)?]])
|
||||
set(_dirs "aaa;${_bundles};${_executables};${_frameworks};${_libraries}")
|
||||
|
||||
set(_alldest [[bbb;bbb/libtestExe2lib\.dylib;bbb/libtestLib3lib(-d|-r)?\.1\.2\.dylib;bbb/libtestLib3lib(-d|-r)?\.3\.dylib;bbb/libtestMod1\.so;bbb/testExe1(-4)?;bbb/testExe3\.app;bbb/testExe3\.app/Contents;bbb/testExe3\.app/Contents/Info\.plist;bbb/testExe3\.app/Contents/MacOS;bbb/testExe3\.app/Contents/MacOS/testExe3(;bbb/testExe3\.app/Contents/PkgInfo)?(;bbb/testExe3\.app/Contents/_CodeSignature;bbb/testExe3\.app/Contents/_CodeSignature/CodeResources)?;bbb/testLib4\.framework;bbb/testLib4\.framework/Headers;bbb/testLib4\.framework/Headers/testLib4\.h;bbb/testLib4\.framework/Resources;bbb/testLib4\.framework/Versions;bbb/testLib4\.framework/Versions/A;bbb/testLib4\.framework/Versions/A/Resources;bbb/testLib4\.framework/Versions/A/Resources/Info\.plist(;bbb/testLib4\.framework/Versions/A/_CodeSignature;bbb/testLib4\.framework/Versions/A/_CodeSignature/CodeResources)?;bbb/testLib4\.framework/Versions/A/testLib4;bbb/testLib4\.framework/Versions/Current;bbb/testLib4\.framework/testLib4;bbb/testMod2\.bundle;bbb/testMod2\.bundle/Contents;bbb/testMod2\.bundle/Contents/Info\.plist;bbb/testMod2\.bundle/Contents/MacOS;bbb/testMod2\.bundle/Contents/MacOS/testMod2(;bbb/testMod2\.bundle/Contents/_CodeSignature;bbb/testMod2\.bundle/Contents/_CodeSignature/CodeResources)?]])
|
||||
|
||||
set(_default_bin [[bin;bin/testExe1(-4)?]])
|
||||
set(_default_lib [[lib;lib/libtestExe2lib\.dylib;lib/libtestLib3lib(-d|-r)?\.1\.2\.dylib;lib/libtestLib3lib(-d|-r)?\.3\.dylib;lib/libtestMod1\.so;lib/testMod2\.bundle;lib/testMod2\.bundle/Contents;lib/testMod2\.bundle/Contents/Info\.plist;lib/testMod2\.bundle/Contents/MacOS;lib/testMod2\.bundle/Contents/MacOS/testMod2(;lib/testMod2\.bundle/Contents/_CodeSignature;lib/testMod2\.bundle/Contents/_CodeSignature/CodeResources)?]])
|
||||
set(_default_bundles [[zzz/bundles;zzz/bundles/testExe3\.app;zzz/bundles/testExe3\.app/Contents;zzz/bundles/testExe3\.app/Contents/Info\.plist;zzz/bundles/testExe3\.app/Contents/MacOS;zzz/bundles/testExe3\.app/Contents/MacOS/testExe3(;zzz/bundles/testExe3\.app/Contents/PkgInfo)?(;zzz/bundles/testExe3\.app/Contents/_CodeSignature;zzz/bundles/testExe3\.app/Contents/_CodeSignature/CodeResources)?]])
|
||||
set(_default_frameworks [[zzz/frameworks;zzz/frameworks/testLib4\.framework;zzz/frameworks/testLib4\.framework/Headers;zzz/frameworks/testLib4\.framework/Headers/testLib4\.h;zzz/frameworks/testLib4\.framework/Resources;zzz/frameworks/testLib4\.framework/Versions;zzz/frameworks/testLib4\.framework/Versions/A;zzz/frameworks/testLib4\.framework/Versions/A/Resources;zzz/frameworks/testLib4\.framework/Versions/A/Resources/Info\.plist(;zzz/frameworks/testLib4\.framework/Versions/A/_CodeSignature;zzz/frameworks/testLib4\.framework/Versions/A/_CodeSignature/CodeResources)?;zzz/frameworks/testLib4\.framework/Versions/A/testLib4;zzz/frameworks/testLib4\.framework/Versions/Current;zzz/frameworks/testLib4\.framework/testLib4]])
|
||||
set(_default "${_default_bin};${_default_lib};zzz;${_default_bundles};${_default_frameworks}")
|
||||
|
||||
# Need to break this up due to too many pairs of parentheses
|
||||
check_installed("^${_dirs};bbb;")
|
||||
check_installed(";${_alldest};bin;")
|
||||
check_installed(";${_default}$")
|
||||
endif()
|
Reference in New Issue
Block a user