Merge topic 'export-refactor-more-for-cps'
[kiteware-cmake.git] / Source / CPack / cmCPackExternalGenerator.cxx
blob76cb876b99d65db2ec14b20b36d6b24811a82f69
1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmCPackExternalGenerator.h"
5 #include <map>
6 #include <utility>
7 #include <vector>
9 #include <cm/memory>
11 #include <cm3p/json/value.h>
12 #include <cm3p/json/writer.h>
14 #include "cmsys/FStream.hxx"
16 #include "cmCPackComponentGroup.h"
17 #include "cmCPackLog.h"
18 #include "cmGeneratedFileStream.h"
19 #include "cmList.h"
20 #include "cmMakefile.h"
21 #include "cmSystemTools.h"
22 #include "cmValue.h"
24 int cmCPackExternalGenerator::InitializeInternal()
26 this->SetOption("CPACK_EXTERNAL_KNOWN_VERSIONS", "1.0");
28 if (!this->ReadListFile("Internal/CPack/CPackExternal.cmake")) {
29 cmCPackLogger(cmCPackLog::LOG_ERROR,
30 "Error while executing CPackExternal.cmake" << std::endl);
31 return 0;
34 std::string major = this->GetOption("CPACK_EXTERNAL_SELECTED_MAJOR");
35 if (major == "1") {
36 this->Generator = cm::make_unique<cmCPackExternalVersion1Generator>(this);
39 return this->Superclass::InitializeInternal();
42 int cmCPackExternalGenerator::PackageFiles()
44 Json::StreamWriterBuilder builder;
45 builder["indentation"] = " ";
47 std::string filename = "package.json";
48 if (!this->packageFileNames.empty()) {
49 filename = this->packageFileNames[0];
53 cmGeneratedFileStream fout(filename);
54 std::unique_ptr<Json::StreamWriter> jout(builder.newStreamWriter());
56 Json::Value root(Json::objectValue);
58 if (!this->Generator->WriteToJSON(root)) {
59 return 0;
62 if (jout->write(root, &fout)) {
63 return 0;
67 cmValue packageScript = this->GetOption("CPACK_EXTERNAL_PACKAGE_SCRIPT");
68 if (cmNonempty(packageScript)) {
69 if (!cmSystemTools::FileIsFullPath(*packageScript)) {
70 cmCPackLogger(
71 cmCPackLog::LOG_ERROR,
72 "CPACK_EXTERNAL_PACKAGE_SCRIPT does not contain a full file path"
73 << std::endl);
74 return 0;
77 bool res = this->MakefileMap->ReadListFile(*packageScript);
79 if (cmSystemTools::GetErrorOccurredFlag() || !res) {
80 return 0;
83 cmValue builtPackages = this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
84 if (builtPackages) {
85 cmExpandList(builtPackages, this->packageFileNames);
89 return 1;
92 bool cmCPackExternalGenerator::SupportsComponentInstallation() const
94 return true;
97 int cmCPackExternalGenerator::InstallProjectViaInstallCommands(
98 bool setDestDir, const std::string& tempInstallDirectory)
100 if (this->StagingEnabled()) {
101 return this->cmCPackGenerator::InstallProjectViaInstallCommands(
102 setDestDir, tempInstallDirectory);
105 return 1;
108 int cmCPackExternalGenerator::InstallProjectViaInstallScript(
109 bool setDestDir, const std::string& tempInstallDirectory)
111 if (this->StagingEnabled()) {
112 return this->cmCPackGenerator::InstallProjectViaInstallScript(
113 setDestDir, tempInstallDirectory);
116 return 1;
119 int cmCPackExternalGenerator::InstallProjectViaInstalledDirectories(
120 bool setDestDir, const std::string& tempInstallDirectory,
121 const mode_t* default_dir_mode)
123 if (this->StagingEnabled()) {
124 return this->cmCPackGenerator::InstallProjectViaInstalledDirectories(
125 setDestDir, tempInstallDirectory, default_dir_mode);
128 return 1;
131 int cmCPackExternalGenerator::RunPreinstallTarget(
132 const std::string& installProjectName, const std::string& installDirectory,
133 cmGlobalGenerator* globalGenerator, const std::string& buildConfig)
135 if (this->StagingEnabled()) {
136 return this->cmCPackGenerator::RunPreinstallTarget(
137 installProjectName, installDirectory, globalGenerator, buildConfig);
140 return 1;
143 int cmCPackExternalGenerator::InstallCMakeProject(
144 bool setDestDir, const std::string& installDirectory,
145 const std::string& baseTempInstallDirectory, const mode_t* default_dir_mode,
146 const std::string& component, bool componentInstall,
147 const std::string& installSubDirectory, const std::string& buildConfig,
148 std::string& absoluteDestFiles)
150 if (this->StagingEnabled()) {
151 return this->cmCPackGenerator::InstallCMakeProject(
152 setDestDir, installDirectory, baseTempInstallDirectory, default_dir_mode,
153 component, componentInstall, installSubDirectory, buildConfig,
154 absoluteDestFiles);
157 return 1;
160 bool cmCPackExternalGenerator::StagingEnabled() const
162 return !this->GetOption("CPACK_EXTERNAL_ENABLE_STAGING").IsOff();
165 cmCPackExternalGenerator::cmCPackExternalVersionGenerator::
166 cmCPackExternalVersionGenerator(cmCPackExternalGenerator* parent)
167 : Parent(parent)
171 int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteVersion(
172 Json::Value& root)
174 root["formatVersionMajor"] = this->GetVersionMajor();
175 root["formatVersionMinor"] = this->GetVersionMinor();
177 return 1;
180 int cmCPackExternalGenerator::cmCPackExternalVersionGenerator::WriteToJSON(
181 Json::Value& root)
183 if (!this->WriteVersion(root)) {
184 return 0;
187 cmValue packageName = this->Parent->GetOption("CPACK_PACKAGE_NAME");
188 if (packageName) {
189 root["packageName"] = *packageName;
192 cmValue packageVersion = this->Parent->GetOption("CPACK_PACKAGE_VERSION");
193 if (packageVersion) {
194 root["packageVersion"] = *packageVersion;
197 cmValue packageDescriptionFile =
198 this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE");
199 if (packageDescriptionFile) {
200 root["packageDescriptionFile"] = *packageDescriptionFile;
203 cmValue packageDescriptionSummary =
204 this->Parent->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY");
205 if (packageDescriptionSummary) {
206 root["packageDescriptionSummary"] = *packageDescriptionSummary;
209 cmValue buildConfigCstr = this->Parent->GetOption("CPACK_BUILD_CONFIG");
210 if (buildConfigCstr) {
211 root["buildConfig"] = *buildConfigCstr;
214 cmValue defaultDirectoryPermissions =
215 this->Parent->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
216 if (cmNonempty(defaultDirectoryPermissions)) {
217 root["defaultDirectoryPermissions"] = *defaultDirectoryPermissions;
219 if (cmIsInternallyOn(this->Parent->GetOption("CPACK_SET_DESTDIR"))) {
220 root["setDestdir"] = true;
221 root["packagingInstallPrefix"] =
222 *this->Parent->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
223 } else {
224 root["setDestdir"] = false;
227 root["stripFiles"] = !this->Parent->GetOption("CPACK_STRIP_FILES").IsOff();
228 root["warnOnAbsoluteInstallDestination"] =
229 this->Parent->IsOn("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION");
230 root["errorOnAbsoluteInstallDestination"] =
231 this->Parent->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION");
233 Json::Value& projects = root["projects"] = Json::Value(Json::arrayValue);
234 for (auto& project : this->Parent->CMakeProjects) {
235 Json::Value jsonProject(Json::objectValue);
237 jsonProject["projectName"] = project.ProjectName;
238 jsonProject["component"] = project.Component;
239 jsonProject["directory"] = project.Directory;
240 jsonProject["subDirectory"] = project.SubDirectory;
242 Json::Value& installationTypes = jsonProject["installationTypes"] =
243 Json::Value(Json::arrayValue);
244 for (auto& installationType : project.InstallationTypes) {
245 installationTypes.append(installationType->Name);
248 Json::Value& components = jsonProject["components"] =
249 Json::Value(Json::arrayValue);
250 for (auto& component : project.Components) {
251 components.append(component->Name);
254 projects.append(jsonProject);
257 Json::Value& installationTypes = root["installationTypes"] =
258 Json::Value(Json::objectValue);
259 for (auto& installationType : this->Parent->InstallationTypes) {
260 Json::Value& jsonInstallationType =
261 installationTypes[installationType.first] =
262 Json::Value(Json::objectValue);
264 jsonInstallationType["name"] = installationType.second.Name;
265 jsonInstallationType["displayName"] = installationType.second.DisplayName;
266 jsonInstallationType["index"] = installationType.second.Index;
269 Json::Value& components = root["components"] =
270 Json::Value(Json::objectValue);
271 for (auto& component : this->Parent->Components) {
272 Json::Value& jsonComponent = components[component.first] =
273 Json::Value(Json::objectValue);
275 jsonComponent["name"] = component.second.Name;
276 jsonComponent["displayName"] = component.second.DisplayName;
277 if (component.second.Group) {
278 jsonComponent["group"] = component.second.Group->Name;
280 jsonComponent["isRequired"] = component.second.IsRequired;
281 jsonComponent["isHidden"] = component.second.IsHidden;
282 jsonComponent["isDisabledByDefault"] =
283 component.second.IsDisabledByDefault;
284 jsonComponent["isDownloaded"] = component.second.IsDownloaded;
285 jsonComponent["description"] = component.second.Description;
286 jsonComponent["archiveFile"] = component.second.ArchiveFile;
288 Json::Value& cmpInstallationTypes = jsonComponent["installationTypes"] =
289 Json::Value(Json::arrayValue);
290 for (auto& installationType : component.second.InstallationTypes) {
291 cmpInstallationTypes.append(installationType->Name);
294 Json::Value& dependencies = jsonComponent["dependencies"] =
295 Json::Value(Json::arrayValue);
296 for (auto& dep : component.second.Dependencies) {
297 dependencies.append(dep->Name);
301 Json::Value& groups = root["componentGroups"] =
302 Json::Value(Json::objectValue);
303 for (auto& group : this->Parent->ComponentGroups) {
304 Json::Value& jsonGroup = groups[group.first] =
305 Json::Value(Json::objectValue);
307 jsonGroup["name"] = group.second.Name;
308 jsonGroup["displayName"] = group.second.DisplayName;
309 jsonGroup["description"] = group.second.Description;
310 jsonGroup["isBold"] = group.second.IsBold;
311 jsonGroup["isExpandedByDefault"] = group.second.IsExpandedByDefault;
312 if (group.second.ParentGroup) {
313 jsonGroup["parentGroup"] = group.second.ParentGroup->Name;
316 Json::Value& subgroups = jsonGroup["subgroups"] =
317 Json::Value(Json::arrayValue);
318 for (auto& subgroup : group.second.Subgroups) {
319 subgroups.append(subgroup->Name);
322 Json::Value& groupComponents = jsonGroup["components"] =
323 Json::Value(Json::arrayValue);
324 for (auto& component : group.second.Components) {
325 groupComponents.append(component->Name);
329 return 1;