|
|
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
|
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
|
|
|
#include "cmCPackExternalGenerator.h"
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <cm/memory>
|
|
|
|
|
|
|
|
#include <cm3p/json/value.h>
|
|
|
|
#include <cm3p/json/writer.h>
|
|
|
|
|
|
|
|
#include "cmsys/FStream.hxx"
|
|
|
|
|
|
|
|
#include "cmCPackComponentGroup.h"
|
|
|
|
#include "cmCPackLog.h"
|
|
|
|
#include "cmMakefile.h"
|
|
|
|
#include "cmStringAlgorithms.h"
|
|
|
|
#include "cmSystemTools.h"
|
|
|
|
#include "cmValue.h"
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::InitializeInternal()
|
|
|
|
{
|
|
|
|
this->SetOption("CPACK_EXTERNAL_KNOWN_VERSIONS", "1.0");
|
|
|
|
|
|
|
|
if (!this->ReadListFile("Internal/CPack/CPackExternal.cmake")) {
|
|
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
|
|
"Error while executing CPackExternal.cmake" << std::endl);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string major = this->GetOption("CPACK_EXTERNAL_SELECTED_MAJOR");
|
|
|
|
if (major == "1") {
|
|
|
|
this->Generator = cm::make_unique<cmCPackExternalVersion1Generator>(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this->Superclass::InitializeInternal();
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::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;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmValue packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT");
|
|
|
|
if (cmNonempty(packageScript)) {
|
|
|
|
if (!cmSystemTools::FileIsFullPath(packageScript)) {
|
|
|
|
cmCPackLogger(
|
|
|
|
cmCPackLog::LOG_ERROR,
|
|
|
|
"CPACK_EXTERNAL_PACKAGE_SCRIPT does not contain a full file path"
|
|
|
|
<< std::endl);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool res = this->MakefileMap->ReadListFile(packageScript);
|
|
|
|
|
|
|
|
if (cmSystemTools::GetErrorOccurredFlag() || !res) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmValue builtPackages = this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
|
|
|
|
if (builtPackages) {
|
|
|
|
cmExpandList(builtPackages, this->packageFileNames, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cmCPackExternalGenerator::SupportsComponentInstallation() const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::InstallProjectViaInstallCommands(
|
|
|
|
bool setDestDir, const std::string& tempInstallDirectory)
|
|
|
|
{
|
|
|
|
if (this->StagingEnabled()) {
|
|
|
|
return this->cmCPackGenerator::InstallProjectViaInstallCommands(
|
|
|
|
setDestDir, tempInstallDirectory);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::InstallProjectViaInstallScript(
|
|
|
|
bool setDestDir, const std::string& tempInstallDirectory)
|
|
|
|
{
|
|
|
|
if (this->StagingEnabled()) {
|
|
|
|
return this->cmCPackGenerator::InstallProjectViaInstallScript(
|
|
|
|
setDestDir, tempInstallDirectory);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::InstallProjectViaInstalledDirectories(
|
|
|
|
bool setDestDir, const std::string& tempInstallDirectory,
|
|
|
|
const mode_t* default_dir_mode)
|
|
|
|
{
|
|
|
|
if (this->StagingEnabled()) {
|
|
|
|
return this->cmCPackGenerator::InstallProjectViaInstalledDirectories(
|
|
|
|
setDestDir, tempInstallDirectory, default_dir_mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::RunPreinstallTarget(
|
|
|
|
const std::string& installProjectName, const std::string& installDirectory,
|
|
|
|
cmGlobalGenerator* globalGenerator, const std::string& buildConfig)
|
|
|
|
{
|
|
|
|
if (this->StagingEnabled()) {
|
|
|
|
return this->cmCPackGenerator::RunPreinstallTarget(
|
|
|
|
installProjectName, installDirectory, globalGenerator, buildConfig);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::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)
|
|
|
|
{
|
|
|
|
if (this->StagingEnabled()) {
|
|
|
|
return this->cmCPackGenerator::InstallCMakeProject(
|
|
|
|
setDestDir, installDirectory, baseTempInstallDirectory, default_dir_mode,
|
|
|
|
component, componentInstall, installSubDirectory, buildConfig,
|
|
|
|
absoluteDestFiles);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cmCPackExternalGenerator::StagingEnabled() const
|
|
|
|
{
|
|
|
|
return !cmIsOff(this->GetOption("CPACK_EXTERNAL_ENABLE_STAGING"));
|
|
|
|
}
|
|
|
|
|
|
|
|
cmCPackExternalGenerator::cmCPackExternalVersionGenerator::
|
|
|
|
cmCPackExternalVersionGenerator(cmCPackExternalGenerator* parent)
|
|
|
|
: Parent(parent)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteVersion(
|
|
|
|
Json::Value& root)
|
|
|
|
{
|
|
|
|
root["formatVersionMajor"] = this->GetVersionMajor();
|
|
|
|
root["formatVersionMinor"] = this->GetVersionMinor();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON(
|
|
|
|
Json::Value& root)
|
|
|
|
{
|
|
|
|
if (!this->WriteVersion(root)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmValue packageName = this->Parent->GetOption("CPACK_PACKAGE_NAME");
|
|
|
|
if (packageName) {
|
|
|
|
root["packageName"] = *packageName;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmValue packageVersion = this->Parent->GetOption("CPACK_PACKAGE_VERSION");
|
|
|
|
if (packageVersion) {
|
|
|
|
root["packageVersion"] = *packageVersion;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmValue packageDescriptionFile =
|
|
|
|
this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE");
|
|
|
|
if (packageDescriptionFile) {
|
|
|
|
root["packageDescriptionFile"] = *packageDescriptionFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmValue packageDescriptionSummary =
|
|
|
|
this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY");
|
|
|
|
if (packageDescriptionSummary) {
|
|
|
|
root["packageDescriptionSummary"] = *packageDescriptionSummary;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmValue buildConfigCstr = this->Parent->GetOption("CPACK_BUILD_CONFIG");
|
|
|
|
if (buildConfigCstr) {
|
|
|
|
root["buildConfig"] = *buildConfigCstr;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmValue defaultDirectoryPermissions =
|
|
|
|
this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
|
|
|
|
if (cmNonempty(defaultDirectoryPermissions)) {
|
|
|
|
root["defaultDirectoryPermissions"] = *defaultDirectoryPermissions;
|
|
|
|
}
|
|
|
|
if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
|
|
|
|
root["setDestdir"] = true;
|
|
|
|
root["packagingInstallPrefix"] =
|
|
|
|
*this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
|
|
|
|
} else {
|
|
|
|
root["setDestdir"] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
root["stripFiles"] = !cmIsOff(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;
|
|
|
|
}
|