mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-05 05:39:57 -05:00
Merge topic 'cpack-external'
4c71548766Help: Add release notes for CPack External generator47c87cdd1fHelp: Add documentation for CPack External generator2ef966bc77Testing: Add test for CPack External generator80914d88daCPack: Add "CPack External" generator3ced881db6cmCPackGenerator: Store CPACK_INSTALL_CMAKE_PROJECTS in an internal field4938abb600cmCPackGenerator: Refactor InstallProjectViaInstallCMakeProjects() Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !2142
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
CPack External Generator
|
||||
------------------------
|
||||
|
||||
CPack provides many generators to create packages for a variety of platforms
|
||||
and packaging systems. The intention is for CMake/CPack to be a complete
|
||||
end-to-end solution for building and packaging a software project. However, it
|
||||
may not always be possible to use CPack for the entire packaging process, due
|
||||
to either technical limitations or policies that require the use of certain
|
||||
tools. For this reason, CPack provides the "External" generator, which allows
|
||||
external packaging software to take advantage of some of the functionality
|
||||
provided by CPack, such as component installation and the dependency graph.
|
||||
|
||||
The CPack External generator doesn't actually package any files. Instead, it
|
||||
generates a .json file containing the CPack internal metadata, which gives
|
||||
external software information on how to package the software. This metadata
|
||||
file contains a list of CPack components and component groups, the various
|
||||
options passed to :command:`cpack_add_component` and
|
||||
:command:`cpack_add_component_group`, the dependencies between the components
|
||||
and component groups, and various other options passed to CPack.
|
||||
|
||||
Format
|
||||
^^^^^^
|
||||
|
||||
The file produced by the CPack External generator is a .json file with an
|
||||
object as its root. This root object will always provide two fields:
|
||||
``formatVersionMajor`` and ``formatVersionMinor``, which are always integers
|
||||
that describe the output format of the generator. Backwards-compatible changes
|
||||
to the output format (for example, adding a new field that didn't exist before)
|
||||
cause the minor version to be incremented, and backwards-incompatible changes
|
||||
(for example, deleting a field or changing its meaning) cause the major version
|
||||
to be incremented and the minor version reset to 0. The format version is
|
||||
always of the format ``major.minor``. In other words, it always has exactly two
|
||||
parts, separated by a period.
|
||||
|
||||
You can request one or more specific versions of the output format as described
|
||||
below with :variable:`CPACK_EXT_REQUESTED_VERSIONS`. The output format will
|
||||
have a major version that exactly matches the requested major version, and a
|
||||
minor version that is greater than or equal to the requested minor version. If
|
||||
no version is requested with :variable:`CPACK_EXT_REQUESTED_VERSIONS`, the
|
||||
latest known major version is used by default. Currently, the only supported
|
||||
format is 1.0, which is described below.
|
||||
|
||||
Version 1.0
|
||||
***********
|
||||
|
||||
In addition to the standard format fields, format version 1.0 provides the
|
||||
following fields in the root:
|
||||
|
||||
``components``
|
||||
The ``components`` field is an object with component names as the keys and
|
||||
objects describing the components as the values. The component objects have
|
||||
the following fields:
|
||||
|
||||
``name``
|
||||
The name of the component. This is always the same as the key in the
|
||||
``components`` object.
|
||||
|
||||
``displayName``
|
||||
The value of the ``DISPLAY_NAME`` field passed to
|
||||
:command:`cpack_add_component`.
|
||||
|
||||
``description``
|
||||
The value of the ``DESCRIPTION`` field passed to
|
||||
:command:`cpack_add_component`.
|
||||
|
||||
``isHidden``
|
||||
True if ``HIDDEN`` was passed to :command:`cpack_add_component`, false if
|
||||
it was not.
|
||||
|
||||
``isRequired``
|
||||
True if ``REQUIRED`` was passed to :command:`cpack_add_component`, false if
|
||||
it was not.
|
||||
|
||||
``isDisabledByDefault``
|
||||
True if ``DISABLED`` was passed to :command:`cpack_add_component`, false if
|
||||
it was not.
|
||||
|
||||
``group``
|
||||
Only present if ``GROUP`` was passed to :command:`cpack_add_component`. If
|
||||
so, this field is a string value containing the component's group.
|
||||
|
||||
``dependencies``
|
||||
An array of components the component depends on. This contains the values
|
||||
in the ``DEPENDS`` argument passed to :command:`cpack_add_component`. If no
|
||||
``DEPENDS`` argument was passed, this is an empty list.
|
||||
|
||||
``installationTypes``
|
||||
An array of installation types the component is part of. This contains the
|
||||
values in the ``INSTALL_TYPES`` argument passed to
|
||||
:command:`cpack_add_component`. If no ``INSTALL_TYPES`` argument was
|
||||
passed, this is an empty list.
|
||||
|
||||
``isDownloaded``
|
||||
True if ``DOWNLOADED`` was passed to :command:`cpack_add_component`, false
|
||||
if it was not.
|
||||
|
||||
``archiveFile``
|
||||
The name of the archive file passed with the ``ARCHIVE_FILE`` argument to
|
||||
:command:`cpack_add_component`. If no ``ARCHIVE_FILE`` argument was passed,
|
||||
this is an empty string.
|
||||
|
||||
``componentGroups``
|
||||
The ``componentGroups`` field is an object with component group names as the
|
||||
keys and objects describing the component groups as the values. The component
|
||||
group objects have the following fields:
|
||||
|
||||
``name``
|
||||
The name of the component group. This is always the same as the key in the
|
||||
``componentGroups`` object.
|
||||
|
||||
``displayName``
|
||||
The value of the ``DISPLAY_NAME`` field passed to
|
||||
:command:`cpack_add_component_group`.
|
||||
|
||||
``description``
|
||||
The value of the ``DESCRIPTION`` field passed to
|
||||
:command:`cpack_add_component_group`.
|
||||
|
||||
``parentGroup``
|
||||
Only present if ``PARENT_GROUP`` was passed to
|
||||
:command:`cpack_add_component_group`. If so, this field is a string value
|
||||
containing the component group's parent group.
|
||||
|
||||
``isExpandedByDefault``
|
||||
True if ``EXPANDED`` was passed to :command:`cpack_add_component_group`,
|
||||
false if it was not.
|
||||
|
||||
``isBold``
|
||||
True if ``BOLD_TITLE`` was passed to :command:`cpack_add_component_group`,
|
||||
false if it was not.
|
||||
|
||||
``components``
|
||||
An array of names of components that are direct members of the group
|
||||
(components that have this group as their ``GROUP``). Components of
|
||||
subgroups are not included.
|
||||
|
||||
``subgroups``
|
||||
An array of names of component groups that are subgroups of the group
|
||||
(groups that have this group as their ``PARENT_GROUP``).
|
||||
|
||||
``installationTypes``
|
||||
The ``installationTypes`` field is an object with installation type names as
|
||||
the keys and objects describing the installation types as the values. The
|
||||
installation type objects have the following fields:
|
||||
|
||||
``name``
|
||||
The name of the installation type. This is always the same as the key in
|
||||
the ``installationTypes`` object.
|
||||
|
||||
``displayName``
|
||||
The value of the ``DISPLAY_NAME`` field passed to
|
||||
:command:`cpack_add_install_type`.
|
||||
|
||||
``index``
|
||||
The integer index of the installation type in the list.
|
||||
|
||||
``projects``
|
||||
The ``projects`` field is an array of objects describing CMake projects which
|
||||
comprise the CPack project. The values in this field are derived from
|
||||
:variable:`CPACK_INSTALL_CMAKE_PROJECTS`. In most cases, this will be only a
|
||||
single project. The project objects have the following fields:
|
||||
|
||||
``projectName``
|
||||
The project name passed to :variable:`CPACK_INSTALL_CMAKE_PROJECTS`.
|
||||
|
||||
``component``
|
||||
The name of the component or component set which comprises the project.
|
||||
|
||||
``directory``
|
||||
The build directory of the CMake project. This is the directory which
|
||||
contains the ``cmake_install.cmake`` script.
|
||||
|
||||
``subDirectory``
|
||||
The subdirectory to install the project into inside the CPack package.
|
||||
|
||||
``packageName``
|
||||
The package name given in :variable:`CPACK_PACKAGE_NAME`. Only present if
|
||||
this option is set.
|
||||
|
||||
``packageVersion``
|
||||
The package version given in :variable:`CPACK_PACKAGE_VERSION`. Only present
|
||||
if this option is set.
|
||||
|
||||
``packageDescriptionFile``
|
||||
The package description file given in
|
||||
:variable:`CPACK_PACKAGE_DESCRIPTION_FILE`. Only present if this option is
|
||||
set.
|
||||
|
||||
``packageDescriptionSummary``
|
||||
The package description summary given in
|
||||
:variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY`. Only present if this option is
|
||||
set.
|
||||
|
||||
``buildConfig``
|
||||
The build configuration given to CPack with the ``-C`` option. Only present
|
||||
if this option is set.
|
||||
|
||||
``defaultDirectoryPermissions``
|
||||
The default directory permissions given in
|
||||
:variable:`CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS`. Only present if this
|
||||
option is set.
|
||||
|
||||
``setDestdir``
|
||||
True if :variable:`CPACK_SET_DESTDIR` is true, false if it is not.
|
||||
|
||||
``packagingInstallPrefix``
|
||||
The install prefix given in :variable:`CPACK_PACKAGING_INSTALL_PREFIX`. Only
|
||||
present if :variable:`CPACK_SET_DESTDIR` is true.
|
||||
|
||||
``stripFiles``
|
||||
True if :variable:`CPACK_STRIP_FILES` is true, false if it is not.
|
||||
|
||||
``warnOnAbsoluteInstallDestination``
|
||||
True if :variable:`CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION` is true, false
|
||||
if it is not.
|
||||
|
||||
``errorOnAbsoluteInstallDestination``
|
||||
True if :variable:`CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION` is true,
|
||||
false if it is not.
|
||||
|
||||
Variables specific to CPack External generator
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. variable:: CPACK_EXT_REQUESTED_VERSIONS
|
||||
|
||||
This variable is used to request a specific version of the CPack External
|
||||
generator. It is a list of ``major.minor`` values, separated by semicolons.
|
||||
|
||||
If this variable is set to a non-empty value, the CPack External generator
|
||||
will iterate through each item in the list to search for a version that it
|
||||
knows how to generate. Requested versions should be listed in order of
|
||||
descending preference by the client software, as the first matching version
|
||||
in the list will be generated.
|
||||
|
||||
The generator knows how to generate the version if it has a versioned
|
||||
generator whose major version exactly matches the requested major version,
|
||||
and whose minor version is greater than or equal to the requested minor
|
||||
version. For example, if ``CPACK_EXT_REQUESTED_VERSIONS`` contains 1.0, and
|
||||
the CPack External generator knows how to generate 1.1, it will generate 1.1.
|
||||
If the generator doesn't know how to generate a version in the list, it skips
|
||||
the version and looks at the next one. If it doesn't know how to generate any
|
||||
of the requested versions, an error is thrown.
|
||||
|
||||
If this variable is not set, or is empty, the CPack External generator will
|
||||
generate the highest major and minor version that it knows how to generate.
|
||||
|
||||
If an invalid version is encountered in ``CPACK_EXT_REQUESTED_VERSIONS`` (one
|
||||
that doesn't match ``major.minor``, where ``major`` and ``minor`` are
|
||||
integers), it is ignored.
|
||||
@@ -18,6 +18,7 @@ Generators
|
||||
/cpack_gen/cygwin
|
||||
/cpack_gen/deb
|
||||
/cpack_gen/dmg
|
||||
/cpack_gen/external
|
||||
/cpack_gen/freebsd
|
||||
/cpack_gen/ifw
|
||||
/cpack_gen/nsis
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
cpack-external
|
||||
--------------
|
||||
|
||||
* CPack gained a new :cpack_gen:`CPack External Generator` which is used to
|
||||
export the CPack metadata in a format that other software can understand. The
|
||||
intention of this generator is to allow external packaging software to take
|
||||
advantage of CPack's features when it may not be possible to use CPack for
|
||||
the entire packaging process.
|
||||
@@ -0,0 +1,53 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
if(NOT "${CPACK_EXT_REQUESTED_VERSIONS}" STREQUAL "")
|
||||
unset(_found_major)
|
||||
|
||||
foreach(_req_version IN LISTS CPACK_EXT_REQUESTED_VERSIONS)
|
||||
if(_req_version MATCHES "^([0-9]+)\\.([0-9]+)$")
|
||||
set(_req_major "${CMAKE_MATCH_1}")
|
||||
set(_req_minor "${CMAKE_MATCH_2}")
|
||||
|
||||
foreach(_known_version IN LISTS CPACK_EXT_KNOWN_VERSIONS)
|
||||
string(REGEX MATCH
|
||||
"^([0-9]+)\\.([0-9]+)$"
|
||||
_known_version_dummy
|
||||
"${_known_version}"
|
||||
)
|
||||
|
||||
set(_known_major "${CMAKE_MATCH_1}")
|
||||
set(_known_minor "${CMAKE_MATCH_2}")
|
||||
|
||||
if(_req_major EQUAL _known_major AND NOT _known_minor LESS _req_minor)
|
||||
set(_found_major "${_known_major}")
|
||||
set(_found_minor "${_known_minor}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(DEFINED _found_major)
|
||||
break()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(DEFINED _found_major)
|
||||
set(CPACK_EXT_SELECTED_MAJOR "${_found_major}")
|
||||
set(CPACK_EXT_SELECTED_MINOR "${_found_minor}")
|
||||
set(CPACK_EXT_SELECTED_VERSION "${_found_major}.${_found_minor}")
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS"
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
list(GET CPACK_EXT_KNOWN_VERSIONS 0 CPACK_EXT_SELECTED_VERSION)
|
||||
string(REGEX MATCH
|
||||
"^([0-9]+)\\.([0-9]+)$"
|
||||
_dummy
|
||||
"${CPACK_EXT_SELECTED_VERSION}"
|
||||
)
|
||||
set(CPACK_EXT_SELECTED_MAJOR "${CMAKE_MATCH_1}")
|
||||
set(CPACK_EXT_SELECTED_MINOR "${CMAKE_MATCH_2}")
|
||||
endif()
|
||||
@@ -886,6 +886,8 @@ include_directories(
|
||||
set(CPACK_SRCS
|
||||
CPack/cmCPackArchiveGenerator.cxx
|
||||
CPack/cmCPackComponentGroup.cxx
|
||||
CPack/cmCPackDebGenerator.cxx
|
||||
CPack/cmCPackExtGenerator.cxx
|
||||
CPack/cmCPackGeneratorFactory.cxx
|
||||
CPack/cmCPackGenerator.cxx
|
||||
CPack/cmCPackLog.cxx
|
||||
@@ -898,7 +900,6 @@ set(CPACK_SRCS
|
||||
CPack/cmCPackTarCompressGenerator.cxx
|
||||
CPack/cmCPackZIPGenerator.cxx
|
||||
CPack/cmCPack7zGenerator.cxx
|
||||
CPack/cmCPackDebGenerator.cxx
|
||||
)
|
||||
# CPack IFW generator
|
||||
set(CPACK_SRCS ${CPACK_SRCS}
|
||||
|
||||
@@ -143,4 +143,29 @@ public:
|
||||
std::vector<cmCPackComponentGroup*> Subgroups;
|
||||
};
|
||||
|
||||
/** \class cmCPackInstallCMakeProject
|
||||
* \brief A single quadruplet from the CPACK_INSTALL_CMAKE_PROJECTS variable.
|
||||
*/
|
||||
class cmCPackInstallCMakeProject
|
||||
{
|
||||
public:
|
||||
/// The directory of the CMake project.
|
||||
std::string Directory;
|
||||
|
||||
/// The name of the CMake project.
|
||||
std::string ProjectName;
|
||||
|
||||
/// The name of the component (or component set) to install.
|
||||
std::string Component;
|
||||
|
||||
/// The subdirectory to install into.
|
||||
std::string SubDirectory;
|
||||
|
||||
/// The list of installation types.
|
||||
std::vector<cmCPackInstallationType*> InstallationTypes;
|
||||
|
||||
/// The list of components.
|
||||
std::vector<cmCPackComponent*> Components;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmCPackExtGenerator.h"
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmCPackComponentGroup.h"
|
||||
#include "cmCPackLog.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
#include "cm_jsoncpp_value.h"
|
||||
#include "cm_jsoncpp_writer.h"
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
int cmCPackExtGenerator::InitializeInternal()
|
||||
{
|
||||
this->SetOption("CPACK_EXT_KNOWN_VERSIONS", "1.0");
|
||||
|
||||
if (!this->ReadListFile("Internal/CPack/CPackExt.cmake")) {
|
||||
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||||
"Error while executing CPackExt.cmake" << std::endl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string major = this->GetOption("CPACK_EXT_SELECTED_MAJOR");
|
||||
if (major == "1") {
|
||||
this->Generator = cm::make_unique<cmCPackExtVersion1Generator>(this);
|
||||
}
|
||||
|
||||
return this->Superclass::InitializeInternal();
|
||||
}
|
||||
|
||||
int cmCPackExtGenerator::PackageFiles()
|
||||
{
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder["indentation"] = " ";
|
||||
|
||||
std::string filename = "package.json";
|
||||
if (!this->packageFileNames.empty()) {
|
||||
filename = this->packageFileNames[0];
|
||||
}
|
||||
|
||||
cmsys::ofstream fout(filename.c_str());
|
||||
std::unique_ptr<Json::StreamWriter> jout(builder.newStreamWriter());
|
||||
|
||||
Json::Value root(Json::objectValue);
|
||||
|
||||
if (!this->Generator->WriteToJSON(root)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (jout->write(root, &fout)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool cmCPackExtGenerator::SupportsComponentInstallation() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int cmCPackExtGenerator::InstallProjectViaInstallCommands(
|
||||
bool setDestDir, const std::string& tempInstallDirectory)
|
||||
{
|
||||
(void)setDestDir;
|
||||
(void)tempInstallDirectory;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmCPackExtGenerator::InstallProjectViaInstallScript(
|
||||
bool setDestDir, const std::string& tempInstallDirectory)
|
||||
{
|
||||
(void)setDestDir;
|
||||
(void)tempInstallDirectory;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmCPackExtGenerator::InstallProjectViaInstalledDirectories(
|
||||
bool setDestDir, const std::string& tempInstallDirectory,
|
||||
const mode_t* default_dir_mode)
|
||||
{
|
||||
(void)setDestDir;
|
||||
(void)tempInstallDirectory;
|
||||
(void)default_dir_mode;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmCPackExtGenerator::RunPreinstallTarget(
|
||||
const std::string& installProjectName, const std::string& installDirectory,
|
||||
cmGlobalGenerator* globalGenerator, const std::string& buildConfig)
|
||||
{
|
||||
(void)installProjectName;
|
||||
(void)installDirectory;
|
||||
(void)globalGenerator;
|
||||
(void)buildConfig;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmCPackExtGenerator::InstallCMakeProject(
|
||||
bool setDestDir, const std::string& installDirectory,
|
||||
const std::string& baseTempInstallDirectory, const mode_t* default_dir_mode,
|
||||
const std::string& component, bool componentInstall,
|
||||
const std::string& installSubDirectory, const std::string& buildConfig,
|
||||
std::string& absoluteDestFiles)
|
||||
{
|
||||
(void)setDestDir;
|
||||
(void)installDirectory;
|
||||
(void)baseTempInstallDirectory;
|
||||
(void)default_dir_mode;
|
||||
(void)component;
|
||||
(void)componentInstall;
|
||||
(void)installSubDirectory;
|
||||
(void)buildConfig;
|
||||
(void)absoluteDestFiles;
|
||||
return 1;
|
||||
}
|
||||
|
||||
cmCPackExtGenerator::cmCPackExtVersionGenerator::cmCPackExtVersionGenerator(
|
||||
cmCPackExtGenerator* parent)
|
||||
: Parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int cmCPackExtGenerator::cmCPackExtVersionGenerator::WriteVersion(
|
||||
Json::Value& root)
|
||||
{
|
||||
root["formatVersionMajor"] = this->GetVersionMajor();
|
||||
root["formatVersionMinor"] = this->GetVersionMinor();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmCPackExtGenerator::cmCPackExtVersionGenerator::WriteToJSON(
|
||||
Json::Value& root)
|
||||
{
|
||||
if (!this->WriteVersion(root)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* packageName = this->Parent->GetOption("CPACK_PACKAGE_NAME");
|
||||
if (packageName) {
|
||||
root["packageName"] = packageName;
|
||||
}
|
||||
|
||||
const char* packageVersion =
|
||||
this->Parent->GetOption("CPACK_PACKAGE_VERSION");
|
||||
if (packageVersion) {
|
||||
root["packageVersion"] = packageVersion;
|
||||
}
|
||||
|
||||
const char* packageDescriptionFile =
|
||||
this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE");
|
||||
if (packageDescriptionFile) {
|
||||
root["packageDescriptionFile"] = packageDescriptionFile;
|
||||
}
|
||||
|
||||
const char* packageDescriptionSummary =
|
||||
this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY");
|
||||
if (packageDescriptionSummary) {
|
||||
root["packageDescriptionSummary"] = packageDescriptionSummary;
|
||||
}
|
||||
|
||||
const char* buildConfigCstr = this->Parent->GetOption("CPACK_BUILD_CONFIG");
|
||||
if (buildConfigCstr) {
|
||||
root["buildConfig"] = buildConfigCstr;
|
||||
}
|
||||
|
||||
const char* defaultDirectoryPermissions =
|
||||
this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
|
||||
if (defaultDirectoryPermissions && *defaultDirectoryPermissions) {
|
||||
root["defaultDirectoryPermissions"] = defaultDirectoryPermissions;
|
||||
}
|
||||
if (cmSystemTools::IsInternallyOn(
|
||||
this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
|
||||
root["setDestdir"] = true;
|
||||
root["packagingInstallPrefix"] =
|
||||
this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
|
||||
} else {
|
||||
root["setDestdir"] = false;
|
||||
}
|
||||
|
||||
root["stripFiles"] =
|
||||
!cmSystemTools::IsOff(this->Parent->GetOption("CPACK_STRIP_FILES"));
|
||||
root["warnOnAbsoluteInstallDestination"] =
|
||||
this->Parent->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION");
|
||||
root["errorOnAbsoluteInstallDestination"] =
|
||||
this->Parent->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION");
|
||||
|
||||
Json::Value& projects = root["projects"] = Json::Value(Json::arrayValue);
|
||||
for (auto& project : this->Parent->CMakeProjects) {
|
||||
Json::Value jsonProject(Json::objectValue);
|
||||
|
||||
jsonProject["projectName"] = project.ProjectName;
|
||||
jsonProject["component"] = project.Component;
|
||||
jsonProject["directory"] = project.Directory;
|
||||
jsonProject["subDirectory"] = project.SubDirectory;
|
||||
|
||||
Json::Value& installationTypes = jsonProject["installationTypes"] =
|
||||
Json::Value(Json::arrayValue);
|
||||
for (auto& installationType : project.InstallationTypes) {
|
||||
installationTypes.append(installationType->Name);
|
||||
}
|
||||
|
||||
Json::Value& components = jsonProject["components"] =
|
||||
Json::Value(Json::arrayValue);
|
||||
for (auto& component : project.Components) {
|
||||
components.append(component->Name);
|
||||
}
|
||||
|
||||
projects.append(jsonProject);
|
||||
}
|
||||
|
||||
Json::Value& installationTypes = root["installationTypes"] =
|
||||
Json::Value(Json::objectValue);
|
||||
for (auto& installationType : this->Parent->InstallationTypes) {
|
||||
Json::Value& jsonInstallationType =
|
||||
installationTypes[installationType.first] =
|
||||
Json::Value(Json::objectValue);
|
||||
|
||||
jsonInstallationType["name"] = installationType.second.Name;
|
||||
jsonInstallationType["displayName"] = installationType.second.DisplayName;
|
||||
jsonInstallationType["index"] = installationType.second.Index;
|
||||
}
|
||||
|
||||
Json::Value& components = root["components"] =
|
||||
Json::Value(Json::objectValue);
|
||||
for (auto& component : this->Parent->Components) {
|
||||
Json::Value& jsonComponent = components[component.first] =
|
||||
Json::Value(Json::objectValue);
|
||||
|
||||
jsonComponent["name"] = component.second.Name;
|
||||
jsonComponent["displayName"] = component.second.DisplayName;
|
||||
if (component.second.Group) {
|
||||
jsonComponent["group"] = component.second.Group->Name;
|
||||
}
|
||||
jsonComponent["isRequired"] = component.second.IsRequired;
|
||||
jsonComponent["isHidden"] = component.second.IsHidden;
|
||||
jsonComponent["isDisabledByDefault"] =
|
||||
component.second.IsDisabledByDefault;
|
||||
jsonComponent["isDownloaded"] = component.second.IsDownloaded;
|
||||
jsonComponent["description"] = component.second.Description;
|
||||
jsonComponent["archiveFile"] = component.second.ArchiveFile;
|
||||
|
||||
Json::Value& cmpInstallationTypes = jsonComponent["installationTypes"] =
|
||||
Json::Value(Json::arrayValue);
|
||||
for (auto& installationType : component.second.InstallationTypes) {
|
||||
cmpInstallationTypes.append(installationType->Name);
|
||||
}
|
||||
|
||||
Json::Value& dependencies = jsonComponent["dependencies"] =
|
||||
Json::Value(Json::arrayValue);
|
||||
for (auto& dep : component.second.Dependencies) {
|
||||
dependencies.append(dep->Name);
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value& groups = root["componentGroups"] =
|
||||
Json::Value(Json::objectValue);
|
||||
for (auto& group : this->Parent->ComponentGroups) {
|
||||
Json::Value& jsonGroup = groups[group.first] =
|
||||
Json::Value(Json::objectValue);
|
||||
|
||||
jsonGroup["name"] = group.second.Name;
|
||||
jsonGroup["displayName"] = group.second.DisplayName;
|
||||
jsonGroup["description"] = group.second.Description;
|
||||
jsonGroup["isBold"] = group.second.IsBold;
|
||||
jsonGroup["isExpandedByDefault"] = group.second.IsExpandedByDefault;
|
||||
if (group.second.ParentGroup) {
|
||||
jsonGroup["parentGroup"] = group.second.ParentGroup->Name;
|
||||
}
|
||||
|
||||
Json::Value& subgroups = jsonGroup["subgroups"] =
|
||||
Json::Value(Json::arrayValue);
|
||||
for (auto& subgroup : group.second.Subgroups) {
|
||||
subgroups.append(subgroup->Name);
|
||||
}
|
||||
|
||||
Json::Value& groupComponents = jsonGroup["components"] =
|
||||
Json::Value(Json::arrayValue);
|
||||
for (auto& component : group.second.Components) {
|
||||
groupComponents.append(component->Name);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmCPackExtGenerator_h
|
||||
#define cmCPackExtGenerator_h
|
||||
|
||||
#include "cmCPackGenerator.h"
|
||||
#include "cm_sys_stat.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class cmGlobalGenerator;
|
||||
namespace Json {
|
||||
class Value;
|
||||
}
|
||||
|
||||
/** \class cmCPackExtGenerator
|
||||
* \brief A generator for CPack External packaging tools
|
||||
*/
|
||||
class cmCPackExtGenerator : public cmCPackGenerator
|
||||
{
|
||||
public:
|
||||
cmCPackTypeMacro(cmCPackExtGenerator, cmCPackGenerator);
|
||||
|
||||
const char* GetOutputExtension() override { return ".json"; }
|
||||
|
||||
protected:
|
||||
int InitializeInternal() override;
|
||||
|
||||
int PackageFiles() override;
|
||||
|
||||
bool SupportsComponentInstallation() const override;
|
||||
|
||||
int InstallProjectViaInstallCommands(
|
||||
bool setDestDir, const std::string& tempInstallDirectory) override;
|
||||
int InstallProjectViaInstallScript(
|
||||
bool setDestDir, const std::string& tempInstallDirectory) override;
|
||||
int InstallProjectViaInstalledDirectories(
|
||||
bool setDestDir, const std::string& tempInstallDirectory,
|
||||
const mode_t* default_dir_mode) override;
|
||||
|
||||
int RunPreinstallTarget(const std::string& installProjectName,
|
||||
const std::string& installDirectory,
|
||||
cmGlobalGenerator* globalGenerator,
|
||||
const std::string& buildConfig) override;
|
||||
int InstallCMakeProject(bool setDestDir, const std::string& installDirectory,
|
||||
const std::string& baseTempInstallDirectory,
|
||||
const mode_t* default_dir_mode,
|
||||
const std::string& component, bool componentInstall,
|
||||
const std::string& installSubDirectory,
|
||||
const std::string& buildConfig,
|
||||
std::string& absoluteDestFiles) override;
|
||||
|
||||
private:
|
||||
class cmCPackExtVersionGenerator
|
||||
{
|
||||
public:
|
||||
cmCPackExtVersionGenerator(cmCPackExtGenerator* parent);
|
||||
|
||||
virtual ~cmCPackExtVersionGenerator() = default;
|
||||
|
||||
virtual int WriteToJSON(Json::Value& root);
|
||||
|
||||
protected:
|
||||
virtual int GetVersionMajor() = 0;
|
||||
virtual int GetVersionMinor() = 0;
|
||||
|
||||
int WriteVersion(Json::Value& root);
|
||||
|
||||
cmCPackExtGenerator* Parent;
|
||||
};
|
||||
|
||||
class cmCPackExtVersion1Generator : public cmCPackExtVersionGenerator
|
||||
{
|
||||
public:
|
||||
using cmCPackExtVersionGenerator::cmCPackExtVersionGenerator;
|
||||
|
||||
protected:
|
||||
int GetVersionMajor() override { return 1; }
|
||||
int GetVersionMinor() override { return 0; }
|
||||
};
|
||||
|
||||
std::unique_ptr<cmCPackExtVersionGenerator> Generator;
|
||||
};
|
||||
|
||||
#endif
|
||||
+310
-286
@@ -545,10 +545,13 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
|
||||
++it;
|
||||
std::string installProjectName = *it;
|
||||
++it;
|
||||
std::string installComponent = *it;
|
||||
cmCPackInstallCMakeProject project;
|
||||
|
||||
project.Directory = installDirectory;
|
||||
project.ProjectName = installProjectName;
|
||||
project.Component = *it;
|
||||
++it;
|
||||
std::string installSubDirectory = *it;
|
||||
std::string installFile = installDirectory + "/cmake_install.cmake";
|
||||
project.SubDirectory = *it;
|
||||
|
||||
std::vector<std::string> componentsVector;
|
||||
|
||||
@@ -559,34 +562,36 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
|
||||
* - the user did not request Monolithic install
|
||||
* (this works at CPack time too)
|
||||
*/
|
||||
if (this->SupportsComponentInstallation() &
|
||||
if (this->SupportsComponentInstallation() &&
|
||||
!(this->IsOn("CPACK_MONOLITHIC_INSTALL"))) {
|
||||
// Determine the installation types for this project (if provided).
|
||||
std::string installTypesVar = "CPACK_" +
|
||||
cmSystemTools::UpperCase(installComponent) + "_INSTALL_TYPES";
|
||||
cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES";
|
||||
const char* installTypes = this->GetOption(installTypesVar);
|
||||
if (installTypes && *installTypes) {
|
||||
std::vector<std::string> installTypesVector;
|
||||
cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
|
||||
for (std::string const& installType : installTypesVector) {
|
||||
this->GetInstallationType(installProjectName, installType);
|
||||
project.InstallationTypes.push_back(
|
||||
this->GetInstallationType(project.ProjectName, installType));
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the set of components that will be used in this project
|
||||
std::string componentsVar =
|
||||
"CPACK_COMPONENTS_" + cmSystemTools::UpperCase(installComponent);
|
||||
"CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component);
|
||||
const char* components = this->GetOption(componentsVar);
|
||||
if (components && *components) {
|
||||
cmSystemTools::ExpandListArgument(components, componentsVector);
|
||||
for (std::string const& comp : componentsVector) {
|
||||
GetComponent(installProjectName, comp);
|
||||
project.Components.push_back(
|
||||
this->GetComponent(project.ProjectName, comp));
|
||||
}
|
||||
componentInstall = true;
|
||||
}
|
||||
}
|
||||
if (componentsVector.empty()) {
|
||||
componentsVector.push_back(installComponent);
|
||||
componentsVector.push_back(project.Component);
|
||||
}
|
||||
|
||||
const char* buildConfigCstr = this->GetOption("CPACK_BUILD_CONFIG");
|
||||
@@ -606,293 +611,27 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
|
||||
// on windows.
|
||||
cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths());
|
||||
|
||||
// Does this generator require pre-install?
|
||||
if (const char* preinstall =
|
||||
globalGenerator->GetPreinstallTargetName()) {
|
||||
std::string buildCommand = globalGenerator->GenerateCMakeBuildCommand(
|
||||
preinstall, buildConfig, "", false);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Install command: " << buildCommand << std::endl);
|
||||
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
|
||||
"- Run preinstall target for: " << installProjectName
|
||||
<< std::endl);
|
||||
std::string output;
|
||||
int retVal = 1;
|
||||
bool resB = cmSystemTools::RunSingleCommand(
|
||||
buildCommand.c_str(), &output, &output, &retVal,
|
||||
installDirectory.c_str(), this->GeneratorVerbose,
|
||||
cmDuration::zero());
|
||||
if (!resB || retVal) {
|
||||
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
|
||||
tmpFile += "/PreinstallOutput.log";
|
||||
cmGeneratedFileStream ofs(tmpFile.c_str());
|
||||
ofs << "# Run command: " << buildCommand << std::endl
|
||||
<< "# Directory: " << installDirectory << std::endl
|
||||
<< "# Output:" << std::endl
|
||||
<< output << std::endl;
|
||||
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||||
"Problem running install command: "
|
||||
<< buildCommand << std::endl
|
||||
<< "Please check " << tmpFile << " for errors"
|
||||
<< std::endl);
|
||||
return 0;
|
||||
}
|
||||
if (!this->RunPreinstallTarget(project.ProjectName, project.Directory,
|
||||
globalGenerator, buildConfig)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
delete globalGenerator;
|
||||
|
||||
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
|
||||
"- Install project: " << installProjectName << std::endl);
|
||||
"- Install project: " << project.ProjectName << std::endl);
|
||||
|
||||
// Run the installation for each component
|
||||
for (std::string const& component : componentsVector) {
|
||||
std::string tempInstallDirectory = baseTempInstallDirectory;
|
||||
installComponent = component;
|
||||
if (componentInstall) {
|
||||
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
|
||||
"- Install component: " << installComponent
|
||||
<< std::endl);
|
||||
}
|
||||
|
||||
cmake cm(cmake::RoleScript);
|
||||
cm.SetHomeDirectory("");
|
||||
cm.SetHomeOutputDirectory("");
|
||||
cm.GetCurrentSnapshot().SetDefaultDefinitions();
|
||||
cm.AddCMakePaths();
|
||||
cm.SetProgressCallback(cmCPackGeneratorProgress, this);
|
||||
cm.SetTrace(this->Trace);
|
||||
cm.SetTraceExpand(this->TraceExpand);
|
||||
cmGlobalGenerator gg(&cm);
|
||||
cmMakefile mf(&gg, cm.GetCurrentSnapshot());
|
||||
if (!installSubDirectory.empty() && installSubDirectory != "/" &&
|
||||
installSubDirectory != ".") {
|
||||
tempInstallDirectory += installSubDirectory;
|
||||
}
|
||||
if (componentInstall) {
|
||||
tempInstallDirectory += "/";
|
||||
// Some CPack generators would rather chose
|
||||
// the local installation directory suffix.
|
||||
// Some (e.g. RPM) use
|
||||
// one install directory for each component **GROUP**
|
||||
// instead of the default
|
||||
// one install directory for each component.
|
||||
tempInstallDirectory +=
|
||||
GetComponentInstallDirNameSuffix(installComponent);
|
||||
if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) {
|
||||
tempInstallDirectory += "/";
|
||||
tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME");
|
||||
}
|
||||
}
|
||||
|
||||
const char* default_dir_inst_permissions =
|
||||
this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
|
||||
if (default_dir_inst_permissions && *default_dir_inst_permissions) {
|
||||
mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS",
|
||||
default_dir_inst_permissions);
|
||||
}
|
||||
|
||||
if (!setDestDir) {
|
||||
tempInstallDirectory += this->GetPackagingInstallPrefix();
|
||||
}
|
||||
|
||||
if (setDestDir) {
|
||||
// For DESTDIR based packaging, use the *project*
|
||||
// CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
|
||||
// value of the project's CMAKE_INSTALL_PREFIX is sent in here as
|
||||
// the value of the CPACK_INSTALL_PREFIX variable.
|
||||
//
|
||||
// If DESTDIR has been 'internally set ON' this means that
|
||||
// the underlying CPack specific generator did ask for that
|
||||
// In this case we may override CPACK_INSTALL_PREFIX with
|
||||
// CPACK_PACKAGING_INSTALL_PREFIX
|
||||
// I know this is tricky and awkward but it's the price for
|
||||
// CPACK_SET_DESTDIR backward compatibility.
|
||||
if (cmSystemTools::IsInternallyOn(
|
||||
this->GetOption("CPACK_SET_DESTDIR"))) {
|
||||
this->SetOption("CPACK_INSTALL_PREFIX",
|
||||
this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"));
|
||||
}
|
||||
std::string dir;
|
||||
if (this->GetOption("CPACK_INSTALL_PREFIX")) {
|
||||
dir += this->GetOption("CPACK_INSTALL_PREFIX");
|
||||
}
|
||||
mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str());
|
||||
|
||||
cmCPackLogger(
|
||||
cmCPackLog::LOG_DEBUG,
|
||||
"- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf.AddDefinition)"
|
||||
<< std::endl);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'"
|
||||
<< std::endl);
|
||||
|
||||
// Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory
|
||||
// exists:
|
||||
//
|
||||
if (cmSystemTools::StringStartsWith(dir.c_str(), "/")) {
|
||||
dir = tempInstallDirectory + dir;
|
||||
} else {
|
||||
dir = tempInstallDirectory + "/" + dir;
|
||||
}
|
||||
/*
|
||||
* We must re-set DESTDIR for each component
|
||||
* We must not add the CPACK_INSTALL_PREFIX part because
|
||||
* it will be added using the override of CMAKE_INSTALL_PREFIX
|
||||
* The main reason for this awkward trick is that
|
||||
* are using DESTDIR for 2 different reasons:
|
||||
* - Because it was asked by the CPack Generator or the user
|
||||
* using CPACK_SET_DESTDIR
|
||||
* - Because it was already used for component install
|
||||
* in order to put things in subdirs...
|
||||
*/
|
||||
cmSystemTools::PutEnv(std::string("DESTDIR=") +
|
||||
tempInstallDirectory);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Creating directory: '" << dir << "'" << std::endl);
|
||||
|
||||
if (!cmsys::SystemTools::MakeDirectory(dir, default_dir_mode)) {
|
||||
cmCPackLogger(
|
||||
cmCPackLog::LOG_ERROR,
|
||||
"Problem creating temporary directory: " << dir << std::endl);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
mf.AddDefinition("CMAKE_INSTALL_PREFIX",
|
||||
tempInstallDirectory.c_str());
|
||||
|
||||
if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory,
|
||||
default_dir_mode)) {
|
||||
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||||
"Problem creating temporary directory: "
|
||||
<< tempInstallDirectory << std::endl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Using non-DESTDIR install... (mf.AddDefinition)"
|
||||
<< std::endl);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Setting CMAKE_INSTALL_PREFIX to '"
|
||||
<< tempInstallDirectory << "'" << std::endl);
|
||||
}
|
||||
|
||||
if (!buildConfig.empty()) {
|
||||
mf.AddDefinition("BUILD_TYPE", buildConfig.c_str());
|
||||
}
|
||||
std::string installComponentLowerCase =
|
||||
cmSystemTools::LowerCase(installComponent);
|
||||
if (installComponentLowerCase != "all") {
|
||||
mf.AddDefinition("CMAKE_INSTALL_COMPONENT",
|
||||
installComponent.c_str());
|
||||
}
|
||||
|
||||
// strip on TRUE, ON, 1, one or several file names, but not on
|
||||
// FALSE, OFF, 0 and an empty string
|
||||
if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES"))) {
|
||||
mf.AddDefinition("CMAKE_INSTALL_DO_STRIP", "1");
|
||||
}
|
||||
// Remember the list of files before installation
|
||||
// of the current component (if we are in component install)
|
||||
std::string const& InstallPrefix = tempInstallDirectory;
|
||||
std::vector<std::string> filesBefore;
|
||||
std::string findExpr = tempInstallDirectory;
|
||||
if (componentInstall) {
|
||||
cmsys::Glob glB;
|
||||
findExpr += "/*";
|
||||
glB.RecurseOn();
|
||||
glB.SetRecurseListDirs(true);
|
||||
glB.FindFiles(findExpr);
|
||||
filesBefore = glB.GetFiles();
|
||||
std::sort(filesBefore.begin(), filesBefore.end());
|
||||
}
|
||||
|
||||
// If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION
|
||||
// then forward request to cmake_install.cmake script
|
||||
if (this->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) {
|
||||
mf.AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", "1");
|
||||
}
|
||||
// If current CPack generator does support
|
||||
// ABSOLUTE INSTALL DESTINATION or CPack has been asked for
|
||||
// then ask cmake_install.cmake script to error out
|
||||
// as soon as it occurs (before installing file)
|
||||
if (!SupportsAbsoluteDestination() ||
|
||||
this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) {
|
||||
mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1");
|
||||
}
|
||||
// do installation
|
||||
int res = mf.ReadListFile(installFile.c_str());
|
||||
// forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES
|
||||
// to CPack (may be used by generators like CPack RPM or DEB)
|
||||
// in order to transparently handle ABSOLUTE PATH
|
||||
if (mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) {
|
||||
mf.AddDefinition(
|
||||
"CPACK_ABSOLUTE_DESTINATION_FILES",
|
||||
mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES"));
|
||||
}
|
||||
|
||||
// Now rebuild the list of files after installation
|
||||
// of the current component (if we are in component install)
|
||||
if (componentInstall) {
|
||||
cmsys::Glob glA;
|
||||
glA.RecurseOn();
|
||||
glA.SetRecurseListDirs(true);
|
||||
glA.SetRecurseThroughSymlinks(false);
|
||||
glA.FindFiles(findExpr);
|
||||
std::vector<std::string> filesAfter = glA.GetFiles();
|
||||
std::sort(filesAfter.begin(), filesAfter.end());
|
||||
std::vector<std::string>::iterator diff;
|
||||
std::vector<std::string> result(filesAfter.size());
|
||||
diff = std::set_difference(filesAfter.begin(), filesAfter.end(),
|
||||
filesBefore.begin(), filesBefore.end(),
|
||||
result.begin());
|
||||
|
||||
std::vector<std::string>::iterator fit;
|
||||
std::string localFileName;
|
||||
// Populate the File field of each component
|
||||
for (fit = result.begin(); fit != diff; ++fit) {
|
||||
localFileName = cmSystemTools::RelativePath(InstallPrefix, *fit);
|
||||
localFileName =
|
||||
localFileName.substr(localFileName.find_first_not_of('/'));
|
||||
Components[installComponent].Files.push_back(localFileName);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"Adding file <"
|
||||
<< localFileName << "> to component <"
|
||||
<< installComponent << ">" << std::endl);
|
||||
}
|
||||
}
|
||||
|
||||
if (nullptr != mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
|
||||
if (!absoluteDestFiles.empty()) {
|
||||
absoluteDestFiles += ";";
|
||||
}
|
||||
absoluteDestFiles +=
|
||||
mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"Got some ABSOLUTE DESTINATION FILES: "
|
||||
<< absoluteDestFiles << std::endl);
|
||||
// define component specific var
|
||||
if (componentInstall) {
|
||||
std::string absoluteDestFileComponent =
|
||||
std::string("CPACK_ABSOLUTE_DESTINATION_FILES") + "_" +
|
||||
GetComponentInstallDirNameSuffix(installComponent);
|
||||
if (nullptr != this->GetOption(absoluteDestFileComponent)) {
|
||||
std::string absoluteDestFilesListComponent =
|
||||
this->GetOption(absoluteDestFileComponent);
|
||||
absoluteDestFilesListComponent += ";";
|
||||
absoluteDestFilesListComponent +=
|
||||
mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
|
||||
this->SetOption(absoluteDestFileComponent,
|
||||
absoluteDestFilesListComponent.c_str());
|
||||
} else {
|
||||
this->SetOption(
|
||||
absoluteDestFileComponent,
|
||||
mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmSystemTools::GetErrorOccuredFlag() || !res) {
|
||||
if (!this->InstallCMakeProject(
|
||||
setDestDir, project.Directory, baseTempInstallDirectory,
|
||||
default_dir_mode, component, componentInstall,
|
||||
project.SubDirectory, buildConfig, absoluteDestFiles)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
this->CMakeProjects.push_back(project);
|
||||
}
|
||||
}
|
||||
this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES",
|
||||
@@ -900,6 +639,291 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmCPackGenerator::RunPreinstallTarget(
|
||||
const std::string& installProjectName, const std::string& installDirectory,
|
||||
cmGlobalGenerator* globalGenerator, const std::string& buildConfig)
|
||||
{
|
||||
// Does this generator require pre-install?
|
||||
if (const char* preinstall = globalGenerator->GetPreinstallTargetName()) {
|
||||
std::string buildCommand = globalGenerator->GenerateCMakeBuildCommand(
|
||||
preinstall, buildConfig, "", false);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Install command: " << buildCommand << std::endl);
|
||||
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
|
||||
"- Run preinstall target for: " << installProjectName
|
||||
<< std::endl);
|
||||
std::string output;
|
||||
int retVal = 1;
|
||||
bool resB = cmSystemTools::RunSingleCommand(
|
||||
buildCommand.c_str(), &output, &output, &retVal,
|
||||
installDirectory.c_str(), this->GeneratorVerbose, cmDuration::zero());
|
||||
if (!resB || retVal) {
|
||||
std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
|
||||
tmpFile += "/PreinstallOutput.log";
|
||||
cmGeneratedFileStream ofs(tmpFile.c_str());
|
||||
ofs << "# Run command: " << buildCommand << std::endl
|
||||
<< "# Directory: " << installDirectory << std::endl
|
||||
<< "# Output:" << std::endl
|
||||
<< output << std::endl;
|
||||
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||||
"Problem running install command: "
|
||||
<< buildCommand << std::endl
|
||||
<< "Please check " << tmpFile << " for errors"
|
||||
<< std::endl);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmCPackGenerator::InstallCMakeProject(
|
||||
bool setDestDir, const std::string& installDirectory,
|
||||
const std::string& baseTempInstallDirectory, const mode_t* default_dir_mode,
|
||||
const std::string& component, bool componentInstall,
|
||||
const std::string& installSubDirectory, const std::string& buildConfig,
|
||||
std::string& absoluteDestFiles)
|
||||
{
|
||||
std::string tempInstallDirectory = baseTempInstallDirectory;
|
||||
std::string installFile = installDirectory + "/cmake_install.cmake";
|
||||
|
||||
if (componentInstall) {
|
||||
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
|
||||
"- Install component: " << component << std::endl);
|
||||
}
|
||||
|
||||
cmake cm(cmake::RoleScript);
|
||||
cm.SetHomeDirectory("");
|
||||
cm.SetHomeOutputDirectory("");
|
||||
cm.GetCurrentSnapshot().SetDefaultDefinitions();
|
||||
cm.AddCMakePaths();
|
||||
cm.SetProgressCallback(cmCPackGeneratorProgress, this);
|
||||
cm.SetTrace(this->Trace);
|
||||
cm.SetTraceExpand(this->TraceExpand);
|
||||
cmGlobalGenerator gg(&cm);
|
||||
cmMakefile mf(&gg, cm.GetCurrentSnapshot());
|
||||
if (!installSubDirectory.empty() && installSubDirectory != "/" &&
|
||||
installSubDirectory != ".") {
|
||||
tempInstallDirectory += installSubDirectory;
|
||||
}
|
||||
if (componentInstall) {
|
||||
tempInstallDirectory += "/";
|
||||
// Some CPack generators would rather chose
|
||||
// the local installation directory suffix.
|
||||
// Some (e.g. RPM) use
|
||||
// one install directory for each component **GROUP**
|
||||
// instead of the default
|
||||
// one install directory for each component.
|
||||
tempInstallDirectory += GetComponentInstallDirNameSuffix(component);
|
||||
if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) {
|
||||
tempInstallDirectory += "/";
|
||||
tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME");
|
||||
}
|
||||
}
|
||||
|
||||
const char* default_dir_inst_permissions =
|
||||
this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
|
||||
if (default_dir_inst_permissions && *default_dir_inst_permissions) {
|
||||
mf.AddDefinition("CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS",
|
||||
default_dir_inst_permissions);
|
||||
}
|
||||
|
||||
if (!setDestDir) {
|
||||
tempInstallDirectory += this->GetPackagingInstallPrefix();
|
||||
}
|
||||
|
||||
if (setDestDir) {
|
||||
// For DESTDIR based packaging, use the *project*
|
||||
// CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
|
||||
// value of the project's CMAKE_INSTALL_PREFIX is sent in here as
|
||||
// the value of the CPACK_INSTALL_PREFIX variable.
|
||||
//
|
||||
// If DESTDIR has been 'internally set ON' this means that
|
||||
// the underlying CPack specific generator did ask for that
|
||||
// In this case we may override CPACK_INSTALL_PREFIX with
|
||||
// CPACK_PACKAGING_INSTALL_PREFIX
|
||||
// I know this is tricky and awkward but it's the price for
|
||||
// CPACK_SET_DESTDIR backward compatibility.
|
||||
if (cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"))) {
|
||||
this->SetOption("CPACK_INSTALL_PREFIX",
|
||||
this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"));
|
||||
}
|
||||
std::string dir;
|
||||
if (this->GetOption("CPACK_INSTALL_PREFIX")) {
|
||||
dir += this->GetOption("CPACK_INSTALL_PREFIX");
|
||||
}
|
||||
mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str());
|
||||
|
||||
cmCPackLogger(
|
||||
cmCPackLog::LOG_DEBUG,
|
||||
"- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf.AddDefinition)"
|
||||
<< std::endl);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'"
|
||||
<< std::endl);
|
||||
|
||||
// Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory
|
||||
// exists:
|
||||
//
|
||||
if (cmSystemTools::StringStartsWith(dir.c_str(), "/")) {
|
||||
dir = tempInstallDirectory + dir;
|
||||
} else {
|
||||
dir = tempInstallDirectory + "/" + dir;
|
||||
}
|
||||
/*
|
||||
* We must re-set DESTDIR for each component
|
||||
* We must not add the CPACK_INSTALL_PREFIX part because
|
||||
* it will be added using the override of CMAKE_INSTALL_PREFIX
|
||||
* The main reason for this awkward trick is that
|
||||
* are using DESTDIR for 2 different reasons:
|
||||
* - Because it was asked by the CPack Generator or the user
|
||||
* using CPACK_SET_DESTDIR
|
||||
* - Because it was already used for component install
|
||||
* in order to put things in subdirs...
|
||||
*/
|
||||
cmSystemTools::PutEnv(std::string("DESTDIR=") + tempInstallDirectory);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Creating directory: '" << dir << "'" << std::endl);
|
||||
|
||||
if (!cmsys::SystemTools::MakeDirectory(dir, default_dir_mode)) {
|
||||
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||||
"Problem creating temporary directory: " << dir
|
||||
<< std::endl);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str());
|
||||
|
||||
if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory,
|
||||
default_dir_mode)) {
|
||||
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
||||
"Problem creating temporary directory: "
|
||||
<< tempInstallDirectory << std::endl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Using non-DESTDIR install... (mf.AddDefinition)"
|
||||
<< std::endl);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"- Setting CMAKE_INSTALL_PREFIX to '" << tempInstallDirectory
|
||||
<< "'" << std::endl);
|
||||
}
|
||||
|
||||
if (!buildConfig.empty()) {
|
||||
mf.AddDefinition("BUILD_TYPE", buildConfig.c_str());
|
||||
}
|
||||
std::string installComponentLowerCase = cmSystemTools::LowerCase(component);
|
||||
if (installComponentLowerCase != "all") {
|
||||
mf.AddDefinition("CMAKE_INSTALL_COMPONENT", component.c_str());
|
||||
}
|
||||
|
||||
// strip on TRUE, ON, 1, one or several file names, but not on
|
||||
// FALSE, OFF, 0 and an empty string
|
||||
if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES"))) {
|
||||
mf.AddDefinition("CMAKE_INSTALL_DO_STRIP", "1");
|
||||
}
|
||||
// Remember the list of files before installation
|
||||
// of the current component (if we are in component install)
|
||||
std::string const& InstallPrefix = tempInstallDirectory;
|
||||
std::vector<std::string> filesBefore;
|
||||
std::string findExpr = tempInstallDirectory;
|
||||
if (componentInstall) {
|
||||
cmsys::Glob glB;
|
||||
findExpr += "/*";
|
||||
glB.RecurseOn();
|
||||
glB.SetRecurseListDirs(true);
|
||||
glB.FindFiles(findExpr);
|
||||
filesBefore = glB.GetFiles();
|
||||
std::sort(filesBefore.begin(), filesBefore.end());
|
||||
}
|
||||
|
||||
// If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION
|
||||
// then forward request to cmake_install.cmake script
|
||||
if (this->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) {
|
||||
mf.AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", "1");
|
||||
}
|
||||
// If current CPack generator does support
|
||||
// ABSOLUTE INSTALL DESTINATION or CPack has been asked for
|
||||
// then ask cmake_install.cmake script to error out
|
||||
// as soon as it occurs (before installing file)
|
||||
if (!SupportsAbsoluteDestination() ||
|
||||
this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) {
|
||||
mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1");
|
||||
}
|
||||
// do installation
|
||||
int res = mf.ReadListFile(installFile.c_str());
|
||||
// forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES
|
||||
// to CPack (may be used by generators like CPack RPM or DEB)
|
||||
// in order to transparently handle ABSOLUTE PATH
|
||||
if (mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) {
|
||||
mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES",
|
||||
mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES"));
|
||||
}
|
||||
|
||||
// Now rebuild the list of files after installation
|
||||
// of the current component (if we are in component install)
|
||||
if (componentInstall) {
|
||||
cmsys::Glob glA;
|
||||
glA.RecurseOn();
|
||||
glA.SetRecurseListDirs(true);
|
||||
glA.SetRecurseThroughSymlinks(false);
|
||||
glA.FindFiles(findExpr);
|
||||
std::vector<std::string> filesAfter = glA.GetFiles();
|
||||
std::sort(filesAfter.begin(), filesAfter.end());
|
||||
std::vector<std::string>::iterator diff;
|
||||
std::vector<std::string> result(filesAfter.size());
|
||||
diff = std::set_difference(filesAfter.begin(), filesAfter.end(),
|
||||
filesBefore.begin(), filesBefore.end(),
|
||||
result.begin());
|
||||
|
||||
std::vector<std::string>::iterator fit;
|
||||
std::string localFileName;
|
||||
// Populate the File field of each component
|
||||
for (fit = result.begin(); fit != diff; ++fit) {
|
||||
localFileName = cmSystemTools::RelativePath(InstallPrefix, *fit);
|
||||
localFileName =
|
||||
localFileName.substr(localFileName.find_first_not_of('/'));
|
||||
Components[component].Files.push_back(localFileName);
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"Adding file <" << localFileName << "> to component <"
|
||||
<< component << ">" << std::endl);
|
||||
}
|
||||
}
|
||||
|
||||
if (nullptr != mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
|
||||
if (!absoluteDestFiles.empty()) {
|
||||
absoluteDestFiles += ";";
|
||||
}
|
||||
absoluteDestFiles += mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
|
||||
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
||||
"Got some ABSOLUTE DESTINATION FILES: " << absoluteDestFiles
|
||||
<< std::endl);
|
||||
// define component specific var
|
||||
if (componentInstall) {
|
||||
std::string absoluteDestFileComponent =
|
||||
std::string("CPACK_ABSOLUTE_DESTINATION_FILES") + "_" +
|
||||
GetComponentInstallDirNameSuffix(component);
|
||||
if (nullptr != this->GetOption(absoluteDestFileComponent)) {
|
||||
std::string absoluteDestFilesListComponent =
|
||||
this->GetOption(absoluteDestFileComponent);
|
||||
absoluteDestFilesListComponent += ";";
|
||||
absoluteDestFilesListComponent +=
|
||||
mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
|
||||
this->SetOption(absoluteDestFileComponent,
|
||||
absoluteDestFilesListComponent.c_str());
|
||||
} else {
|
||||
this->SetOption(absoluteDestFileComponent,
|
||||
mf.GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmSystemTools::GetErrorOccuredFlag() || !res) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool cmCPackGenerator::ReadListFile(const char* moduleName)
|
||||
{
|
||||
bool retval;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "cm_sys_stat.h"
|
||||
|
||||
class cmCPackLog;
|
||||
class cmGlobalGenerator;
|
||||
class cmInstalledFile;
|
||||
class cmMakefile;
|
||||
|
||||
@@ -185,6 +186,17 @@ protected:
|
||||
bool setDestDir, const std::string& tempInstallDirectory,
|
||||
const mode_t* default_dir_mode);
|
||||
|
||||
virtual int RunPreinstallTarget(const std::string& installProjectName,
|
||||
const std::string& installDirectory,
|
||||
cmGlobalGenerator* globalGenerator,
|
||||
const std::string& buildConfig);
|
||||
virtual int InstallCMakeProject(
|
||||
bool setDestDir, const std::string& installDirectory,
|
||||
const std::string& baseTempInstallDirectory,
|
||||
const mode_t* default_dir_mode, const std::string& component,
|
||||
bool componentInstall, const std::string& installSubDirectory,
|
||||
const std::string& buildConfig, std::string& absoluteDestFiles);
|
||||
|
||||
/**
|
||||
* The various level of support of
|
||||
* CPACK_SET_DESTDIR used by the generator.
|
||||
@@ -271,6 +283,7 @@ protected:
|
||||
*/
|
||||
std::vector<std::string> files;
|
||||
|
||||
std::vector<cmCPackInstallCMakeProject> CMakeProjects;
|
||||
std::map<std::string, cmCPackInstallationType> InstallationTypes;
|
||||
/**
|
||||
* The set of components.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# include "cmCPackFreeBSDGenerator.h"
|
||||
#endif
|
||||
#include "cmCPackDebGenerator.h"
|
||||
#include "cmCPackExtGenerator.h"
|
||||
#include "cmCPackGenerator.h"
|
||||
#include "cmCPackLog.h"
|
||||
#include "cmCPackNSISGenerator.h"
|
||||
@@ -110,6 +111,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
|
||||
this->RegisterGenerator("NuGet", "NuGet packages",
|
||||
cmCPackNuGetGenerator::CreateGenerator);
|
||||
}
|
||||
if (cmCPackExtGenerator::CanGenerate()) {
|
||||
this->RegisterGenerator("Ext", "CPack External packages",
|
||||
cmCPackExtGenerator::CreateGenerator);
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
if (cmCPackDragNDropGenerator::CanGenerate()) {
|
||||
this->RegisterGenerator("DragNDrop", "Mac OSX Drag And Drop",
|
||||
|
||||
@@ -422,7 +422,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
|
||||
add_RunCMake_test(ctest_labels_for_subprojects)
|
||||
endif()
|
||||
|
||||
add_RunCMake_test_group(CPack "DEB;RPM;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ")
|
||||
add_RunCMake_test_group(CPack "DEB;RPM;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;Ext")
|
||||
# add a test to make sure symbols are exported from a shared library
|
||||
# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
|
||||
add_RunCMake_test(AutoExportDll)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
function(getPackageNameGlobexpr NAME COMPONENT VERSION REVISION FILE_NO RESULT_VAR)
|
||||
set(${RESULT_VAR} "${NAME}-${VERSION}-*.json" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(getPackageContentList FILE RESULT_VAR)
|
||||
set("${RESULT_VAR}" "" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(toExpectedContentList FILE_NO CONTENT_VAR)
|
||||
set("${CONTENT_VAR}" "" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
set(ALL_FILES_GLOB "*.json")
|
||||
|
||||
function(check_ext_json EXPECTED_FILE ACTUAL_FILE)
|
||||
file(READ "${EXPECTED_FILE}" _expected_regex)
|
||||
file(READ "${ACTUAL_FILE}" _actual_contents)
|
||||
|
||||
string(REGEX REPLACE "\n+$" "" _expected_regex "${_expected_regex}")
|
||||
string(REGEX REPLACE "\n+$" "" _actual_contents "${_actual_contents}")
|
||||
|
||||
if(NOT "${_actual_contents}" MATCHES "${_expected_regex}")
|
||||
message(FATAL_ERROR
|
||||
"Output JSON does not match expected regex.\n"
|
||||
"Expected regex:\n"
|
||||
"${_expected_regex}\n"
|
||||
"Actual output:\n"
|
||||
"${_actual_contents}\n"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -18,7 +18,7 @@ run_cpack_test(GENERATE_SHLIBS_LDCONFIG "DEB" true "COMPONENT")
|
||||
run_cpack_test(INSTALL_SCRIPTS "RPM" false "COMPONENT")
|
||||
run_cpack_test(LONG_FILENAMES "DEB" false "MONOLITHIC")
|
||||
run_cpack_test_subtests(MAIN_COMPONENT "invalid;found" "RPM" false "COMPONENT")
|
||||
run_cpack_test(MINIMAL "RPM;DEB;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ" false "MONOLITHIC;COMPONENT")
|
||||
run_cpack_test(MINIMAL "RPM;DEB;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;Ext" false "MONOLITHIC;COMPONENT")
|
||||
run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false "MONOLITHIC")
|
||||
run_cpack_test(PARTIALLY_RELOCATABLE_WARNING "RPM" false "COMPONENT")
|
||||
run_cpack_test(PER_COMPONENT_FIELDS "RPM;DEB" false "COMPONENT")
|
||||
@@ -31,3 +31,4 @@ run_cpack_test(USER_FILELIST "RPM" false "MONOLITHIC")
|
||||
run_cpack_test(MD5SUMS "DEB" false "MONOLITHIC;COMPONENT")
|
||||
run_cpack_test(CPACK_INSTALL_SCRIPT "ZIP" false "MONOLITHIC")
|
||||
run_cpack_test(DEB_PACKAGE_VERSION_BACK_COMPATIBILITY "DEB" false "MONOLITHIC;COMPONENT")
|
||||
run_cpack_test_subtests(EXT "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad" "Ext" false "MONOLITHIC;COMPONENT")
|
||||
|
||||
@@ -56,8 +56,12 @@ if(NOT EXPECTED_FILES_COUNT EQUAL 0)
|
||||
set(EXPECTED_FILE_CONTENT_${file_no_} "${EXPECTED_FILE_CONTENT_${file_no_}_LIST}")
|
||||
toExpectedContentList("${file_no_}" "EXPECTED_FILE_CONTENT_${file_no_}")
|
||||
|
||||
list(SORT PACKAGE_CONTENT)
|
||||
list(SORT EXPECTED_FILE_CONTENT_${file_no_})
|
||||
if(NOT PACKAGE_CONTENT STREQUAL "")
|
||||
list(SORT PACKAGE_CONTENT)
|
||||
endif()
|
||||
if(NOT EXPECTED_FILE_CONTENT_${file_no_} STREQUAL "")
|
||||
list(SORT EXPECTED_FILE_CONTENT_${file_no_})
|
||||
endif()
|
||||
|
||||
if(PACKAGE_CONTENT STREQUAL EXPECTED_FILE_CONTENT_${file_no_})
|
||||
set(expected_content_list TRUE)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
if(RunCMake_SUBTEST_SUFFIX MATCHES "^(none|good(_multi)?|invalid_good)$")
|
||||
set(EXPECTED_FILES_COUNT "1")
|
||||
set(EXPECTED_FILE_CONTENT_1_LIST "/share;/share/cpack-test;/share/cpack-test/f1.txt;/share/cpack-test/f2.txt;/share/cpack-test/f3.txt;/share/cpack-test/f4.txt")
|
||||
else()
|
||||
set(EXPECTED_FILES_COUNT "0")
|
||||
endif()
|
||||
@@ -0,0 +1,3 @@
|
||||
if(RunCMake_SUBTEST_SUFFIX MATCHES "^(none|good(_multi)?|invalid_good)")
|
||||
check_ext_json("${src_dir}/tests/EXT/expected-json-1.0.txt" "${FOUND_FILE_1}")
|
||||
endif()
|
||||
@@ -0,0 +1,6 @@
|
||||
CMake Error at .*/Modules/Internal/CPack/CPackExt\.cmake:[0-9]+ \(message\):
|
||||
Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS
|
||||
|
||||
|
||||
CPack Error: Error while executing CPackExt\.cmake
|
||||
CPack Error: Cannot initialize the generator Ext
|
||||
@@ -0,0 +1,6 @@
|
||||
CMake Error at .*/Modules/Internal/CPack/CPackExt\.cmake:[0-9]+ \(message\):
|
||||
Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS
|
||||
|
||||
|
||||
CPack Error: Error while executing CPackExt\.cmake
|
||||
CPack Error: Cannot initialize the generator Ext
|
||||
@@ -0,0 +1,176 @@
|
||||
^\{
|
||||
"componentGroups" :[ ]
|
||||
\{
|
||||
"f12" :[ ]
|
||||
\{
|
||||
"components" :[ ]
|
||||
\[
|
||||
"f1",
|
||||
"f2"
|
||||
\],
|
||||
"description" : "Component group for files 1 and 2",
|
||||
"displayName" : "Files 1 and 2",
|
||||
"isBold" : false,
|
||||
"isExpandedByDefault" : false,
|
||||
"name" : "f12",
|
||||
"parentGroup" : "f1234",
|
||||
"subgroups" : \[\]
|
||||
\},
|
||||
"f1234" :[ ]
|
||||
\{
|
||||
"components" : \[\],
|
||||
"description" : "Component group for all files",
|
||||
"displayName" : "Files 1-4",
|
||||
"isBold" : false,
|
||||
"isExpandedByDefault" : false,
|
||||
"name" : "f1234",
|
||||
"subgroups" :[ ]
|
||||
\[
|
||||
"f12",
|
||||
"f34"
|
||||
\]
|
||||
\},
|
||||
"f34" :[ ]
|
||||
\{
|
||||
"components" :[ ]
|
||||
\[
|
||||
"f3",
|
||||
"f4"
|
||||
\],
|
||||
"description" : "Component group for files 3 and 4",
|
||||
"displayName" : "Files 3 and 4",
|
||||
"isBold" : false,
|
||||
"isExpandedByDefault" : false,
|
||||
"name" : "f34",
|
||||
"parentGroup" : "f1234",
|
||||
"subgroups" : \[\]
|
||||
\}
|
||||
\},
|
||||
"components" :[ ]
|
||||
\{
|
||||
"f1" :[ ]
|
||||
\{
|
||||
"archiveFile" : "",
|
||||
"dependencies" : \[\],
|
||||
"description" : "Component for file 1",
|
||||
"displayName" : "File 1",
|
||||
"group" : "f12",
|
||||
"installationTypes" :[ ]
|
||||
\[
|
||||
"full",
|
||||
"f12"
|
||||
\],
|
||||
"isDisabledByDefault" : false,
|
||||
"isDownloaded" : false,
|
||||
"isHidden" : false,
|
||||
"isRequired" : false,
|
||||
"name" : "f1"
|
||||
\},
|
||||
"f2" :[ ]
|
||||
\{
|
||||
"archiveFile" : "",
|
||||
"dependencies" :[ ]
|
||||
\[
|
||||
"f1"
|
||||
\],
|
||||
"description" : "Component for file 2",
|
||||
"displayName" : "File 2",
|
||||
"group" : "f12",
|
||||
"installationTypes" :[ ]
|
||||
\[
|
||||
"full",
|
||||
"f12"
|
||||
\],
|
||||
"isDisabledByDefault" : false,
|
||||
"isDownloaded" : false,
|
||||
"isHidden" : false,
|
||||
"isRequired" : false,
|
||||
"name" : "f2"
|
||||
\},
|
||||
"f3" :[ ]
|
||||
\{
|
||||
"archiveFile" : "",
|
||||
"dependencies" :[ ]
|
||||
\[
|
||||
"f1",
|
||||
"f2"
|
||||
\],
|
||||
"description" : "Component for file 3",
|
||||
"displayName" : "File 3",
|
||||
"group" : "f34",
|
||||
"installationTypes" :[ ]
|
||||
\[
|
||||
"full"
|
||||
\],
|
||||
"isDisabledByDefault" : false,
|
||||
"isDownloaded" : false,
|
||||
"isHidden" : false,
|
||||
"isRequired" : false,
|
||||
"name" : "f3"
|
||||
\},
|
||||
"f4" :[ ]
|
||||
\{
|
||||
"archiveFile" : "",
|
||||
"dependencies" :[ ]
|
||||
\[
|
||||
"f2",
|
||||
"f3",
|
||||
"f1"
|
||||
\],
|
||||
"description" : "Component for file 4",
|
||||
"displayName" : "File 4",
|
||||
"group" : "f34",
|
||||
"installationTypes" :[ ]
|
||||
\[
|
||||
"full"
|
||||
\],
|
||||
"isDisabledByDefault" : false,
|
||||
"isDownloaded" : false,
|
||||
"isHidden" : false,
|
||||
"isRequired" : false,
|
||||
"name" : "f4"
|
||||
\}
|
||||
\},
|
||||
"errorOnAbsoluteInstallDestination" : false,
|
||||
"formatVersionMajor" : 1,
|
||||
"formatVersionMinor" : 0,
|
||||
"installationTypes" :[ ]
|
||||
\{
|
||||
"f12" :[ ]
|
||||
\{
|
||||
"displayName" : "Only files 1 and 2",
|
||||
"index" : 2,
|
||||
"name" : "f12"
|
||||
\},
|
||||
"full" :[ ]
|
||||
\{
|
||||
"displayName" : "Full installation",
|
||||
"index" : 1,
|
||||
"name" : "full"
|
||||
\}
|
||||
\},
|
||||
"packageDescriptionFile" : ".*/Templates/CPack\.GenericDescription\.txt",
|
||||
"packageDescriptionSummary" : "EXT-(none|good(_multi)?|invalid_good)-subtest-(MONOLITHIC|COMPONENT)-type built using CMake",
|
||||
"packageName" : "ext",
|
||||
"packageVersion" : "0\.1\.1",
|
||||
"projects" :[ ]
|
||||
\[
|
||||
\{
|
||||
"component" : "ALL",
|
||||
"components" :[ ]
|
||||
\[
|
||||
"f1",
|
||||
"f2",
|
||||
"f3",
|
||||
"f4"
|
||||
\],
|
||||
"directory" : ".*/Tests/RunCMake/Ext/CPack/EXT-build-(none|good(_multi)?|invalid_good)-subtest",
|
||||
"installationTypes" : \[\],
|
||||
"projectName" : "EXT-(none|good(_multi)?|invalid_good)-subtest-(MONOLITHIC|COMPONENT)-type",
|
||||
"subDirectory" : "/"
|
||||
\}
|
||||
\],
|
||||
"setDestdir" : false,
|
||||
"stripFiles" : false,
|
||||
"warnOnAbsoluteInstallDestination" : false
|
||||
\}$
|
||||
@@ -0,0 +1,6 @@
|
||||
CMake Error at .*/Modules/Internal/CPack/CPackExt\.cmake:[0-9]+ \(message\):
|
||||
Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS
|
||||
|
||||
|
||||
CPack Error: Error while executing CPackExt\.cmake
|
||||
CPack Error: Cannot initialize the generator Ext
|
||||
@@ -0,0 +1,83 @@
|
||||
include(CPackComponent)
|
||||
|
||||
if(RunCMake_SUBTEST_SUFFIX STREQUAL "none")
|
||||
unset(CPACK_EXT_REQUESTED_VERSIONS)
|
||||
elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "good")
|
||||
set(CPACK_EXT_REQUESTED_VERSIONS "1.0")
|
||||
elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "good_multi")
|
||||
set(CPACK_EXT_REQUESTED_VERSIONS "1.0;2.0")
|
||||
elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "bad_major")
|
||||
set(CPACK_EXT_REQUESTED_VERSIONS "2.0")
|
||||
elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "bad_minor")
|
||||
set(CPACK_EXT_REQUESTED_VERSIONS "1.1")
|
||||
elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "invalid_good")
|
||||
set(CPACK_EXT_REQUESTED_VERSIONS "1;1.0")
|
||||
elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "invalid_bad")
|
||||
set(CPACK_EXT_REQUESTED_VERSIONS "1")
|
||||
endif()
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f1.txt" test1)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f2.txt" test2)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f3.txt" test3)
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f4.txt" test4)
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/f1.txt" DESTINATION share/cpack-test COMPONENT f1)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/f2.txt" DESTINATION share/cpack-test COMPONENT f2)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/f3.txt" DESTINATION share/cpack-test COMPONENT f3)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/f4.txt" DESTINATION share/cpack-test COMPONENT f4)
|
||||
|
||||
cpack_add_component(f1
|
||||
DISPLAY_NAME "File 1"
|
||||
DESCRIPTION "Component for file 1"
|
||||
GROUP f12
|
||||
INSTALL_TYPES full f12
|
||||
)
|
||||
|
||||
cpack_add_component(f2
|
||||
DISPLAY_NAME "File 2"
|
||||
DESCRIPTION "Component for file 2"
|
||||
GROUP f12
|
||||
DEPENDS f1
|
||||
INSTALL_TYPES full f12
|
||||
)
|
||||
|
||||
cpack_add_component(f3
|
||||
DISPLAY_NAME "File 3"
|
||||
DESCRIPTION "Component for file 3"
|
||||
GROUP f34
|
||||
DEPENDS f1 f2
|
||||
INSTALL_TYPES full
|
||||
)
|
||||
|
||||
cpack_add_component(f4
|
||||
DISPLAY_NAME "File 4"
|
||||
DESCRIPTION "Component for file 4"
|
||||
GROUP f34
|
||||
DEPENDS f2 f3 f1
|
||||
INSTALL_TYPES full
|
||||
)
|
||||
|
||||
cpack_add_component_group(f12
|
||||
DISPLAY_NAME "Files 1 and 2"
|
||||
DESCRIPTION "Component group for files 1 and 2"
|
||||
PARENT_GROUP f1234
|
||||
)
|
||||
|
||||
cpack_add_component_group(f34
|
||||
DISPLAY_NAME "Files 3 and 4"
|
||||
DESCRIPTION "Component group for files 3 and 4"
|
||||
PARENT_GROUP f1234
|
||||
)
|
||||
|
||||
cpack_add_component_group(f1234
|
||||
DISPLAY_NAME "Files 1-4"
|
||||
DESCRIPTION "Component group for all files"
|
||||
)
|
||||
|
||||
cpack_add_install_type(full
|
||||
DISPLAY_NAME "Full installation"
|
||||
)
|
||||
|
||||
cpack_add_install_type(f12
|
||||
DISPLAY_NAME "Only files 1 and 2"
|
||||
)
|
||||
Reference in New Issue
Block a user