summaryrefslogtreecommitdiffstats
path: root/Source/CPack
diff options
context:
space:
mode:
authorClinton Stimpson <clinton@elemtech.com>2013-11-02 16:24:53 (GMT)
committerClinton Stimpson <clinton@elemtech.com>2016-06-03 20:41:57 (GMT)
commit2e3c67d1b636f752eea35ef407c5243a79742d63 (patch)
tree9398330039272daa72dbb35c18b0d480f01c3364 /Source/CPack
parent50a3d34005ec923db3d76d0a5d118437a7632617 (diff)
downloadCMake-2e3c67d1b636f752eea35ef407c5243a79742d63.zip
CMake-2e3c67d1b636f752eea35ef407c5243a79742d63.tar.gz
CMake-2e3c67d1b636f752eea35ef407c5243a79742d63.tar.bz2
productbuild: Add new productbuild cpack generator.
This cpack generator basically replaces the obsolete PackageMaker generator.
Diffstat (limited to 'Source/CPack')
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx5
-rw-r--r--Source/CPack/cmCPackPKGGenerator.cxx1
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx2
-rw-r--r--Source/CPack/cmCPackProductBuildGenerator.cxx260
-rw-r--r--Source/CPack/cmCPackProductBuildGenerator.h60
5 files changed, 327 insertions, 1 deletions
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index b17f52e..cf072bb 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -28,6 +28,7 @@
#include "cmCPackDragNDropGenerator.h"
#include "cmCPackOSXX11Generator.h"
#include "cmCPackPackageMakerGenerator.h"
+#include "cmCPackProductBuildGenerator.h"
#endif
#ifdef __CYGWIN__
@@ -122,6 +123,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("OSXX11", "Mac OSX X11 bundle",
cmCPackOSXX11Generator::CreateGenerator);
}
+ if (cmCPackProductBuildGenerator::CanGenerate()) {
+ this->RegisterGenerator("productbuild", "Mac OSX pkg",
+ cmCPackProductBuildGenerator::CreateGenerator);
+ }
#endif
#if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) && \
!defined(__HAIKU__)
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index 8282714..ff0fa8c 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -41,7 +41,6 @@ int cmCPackPKGGenerator::InitializeInternal()
{
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"cmCPackPKGGenerator::Initialize()" << std::endl);
- this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
return this->Superclass::InitializeInternal();
}
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index e50c2e6..5bb24c0 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -329,6 +329,8 @@ int cmCPackPackageMakerGenerator::PackageFiles()
int cmCPackPackageMakerGenerator::InitializeInternal()
{
+ this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
+
// Starting with Xcode 4.3, PackageMaker is a separate app, and you
// can put it anywhere you want. So... use a variable for its location.
// People who put it in unexpected places can use the variable to tell
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
new file mode 100644
index 0000000..c1f63cc
--- /dev/null
+++ b/Source/CPack/cmCPackProductBuildGenerator.cxx
@@ -0,0 +1,260 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmCPackProductBuildGenerator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackComponentGroup.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+
+cmCPackProductBuildGenerator::cmCPackProductBuildGenerator()
+{
+ this->componentPackageMethod = ONE_PACKAGE;
+}
+
+cmCPackProductBuildGenerator::~cmCPackProductBuildGenerator()
+{
+}
+
+int cmCPackProductBuildGenerator::PackageFiles()
+{
+ // TODO: Use toplevel
+ // It is used! Is this an obsolete comment?
+
+ std::string packageDirFileName
+ = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+
+ // Create the directory where component packages will be built.
+ std::string basePackageDir = packageDirFileName;
+ basePackageDir += "/Contents/Packages";
+ if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating component packages directory: "
+ << basePackageDir.c_str() << std::endl);
+ return 0;
+ }
+
+ if (!this->Components.empty())
+ {
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt)
+ {
+ std::string packageDir = toplevel;
+ packageDir += '/';
+ packageDir += compIt->first;
+ if (!this->GenerateComponentPackage(basePackageDir,
+ GetPackageName(compIt->second),
+ packageDir,
+ &compIt->second))
+ {
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ if(!this->GenerateComponentPackage(basePackageDir,
+ this->GetOption("CPACK_PACKAGE_NAME"),
+ toplevel, NULL))
+ {
+ return 0;
+ }
+ }
+
+ // Copy or create all of the resource files we need.
+ std::string resDir = packageDirFileName + "/Contents";
+ if ( !this->CopyCreateResourceFile("License", resDir.c_str())
+ || !this->CopyCreateResourceFile("ReadMe", resDir.c_str())
+ || !this->CopyCreateResourceFile("Welcome", resDir.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files"
+ << std::endl);
+ return 0;
+ }
+
+ // combine package(s) into a distribution
+ WriteDistributionFile(packageDirFileName.c_str());
+ std::ostringstream pkgCmd;
+
+ std::string version = this->GetOption("CPACK_PACKAGE_VERSION");
+ std::string productbuild = this->GetOption("CPACK_COMMAND_PRODUCTBUILD");
+
+ pkgCmd << productbuild
+ << " --distribution \"" << packageDirFileName
+ << "/Contents/distribution.dist\""
+ << " --package-path \"" << packageDirFileName << "/Contents/Packages" << "\""
+ << " --resources \"" << resDir << "\""
+ << " --version \"" << version << "\""
+ << " \"" << packageFileNames[0] << "\"";
+
+ // Run ProductBuild
+ return RunProductBuild(pkgCmd.str());
+}
+
+int cmCPackProductBuildGenerator::InitializeInternal()
+{
+ this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/Applications");
+
+ std::vector<std::string> no_paths;
+ std::string program =
+ cmSystemTools::FindProgram("pkgbuild", no_paths, false);
+ if (program.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find pkgbuild executable"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_COMMAND_PKGBUILD", program.c_str());
+
+
+ program = cmSystemTools::FindProgram("productbuild", no_paths, false);
+ if (program.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find productbuild executable"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_COMMAND_PRODUCTBUILD", program.c_str());
+
+ return this->Superclass::InitializeInternal();
+}
+
+
+bool cmCPackProductBuildGenerator::RunProductBuild(
+ const std::string& command)
+{
+ std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ tmpFile += "/ProductBuildOutput.log";
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << command << std::endl);
+ std::string output, error_output;
+ int retVal = 1;
+ bool res = cmSystemTools::RunSingleCommand(command.c_str(),
+ &output, &error_output, &retVal, 0, this->GeneratorVerbose, 0);
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running command"
+ << std::endl);
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(tmpFile.c_str());
+ ofs << "# Run command: " << command << std::endl
+ << "# Output:" << std::endl
+ << output.c_str() << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem running command: " << command
+ << std::endl << "Please check " << tmpFile.c_str() << " for errors"
+ << std::endl);
+ return false;
+ }
+ return true;
+}
+
+bool cmCPackProductBuildGenerator::GenerateComponentPackage(
+ const std::string& packageFileDir,
+ const std::string& packageFileName,
+ const std::string& packageDir,
+ const cmCPackComponent* component)
+{
+ std::string packageFile = packageFileDir;
+ packageFile += '/';
+ packageFile += packageFileName;
+
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Building component package: " <<
+ packageFile << std::endl);
+
+ const char* comp_name = component ? component->Name.c_str() : NULL;
+
+ const char* preflight = this->GetComponentScript("PREFLIGHT", comp_name);
+ const char* postflight = this->GetComponentScript("POSTFLIGHT", comp_name);
+
+ std::string resDir = packageFileDir;
+ if(component)
+ {
+ resDir += "/";
+ resDir += component->Name;
+ }
+ std::string scriptDir = resDir + "/scripts";
+
+ if ( !cmsys::SystemTools::MakeDirectory(scriptDir.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating installer directory: "
+ << scriptDir.c_str() << std::endl);
+ return 0;
+ }
+
+ // if preflight, postflight, or postupgrade are set
+ // then copy them into the script directory and make
+ // them executable
+ if(preflight)
+ {
+ this->CopyInstallScript(scriptDir.c_str(),
+ preflight,
+ "preinstall");
+ }
+ if(postflight)
+ {
+ this->CopyInstallScript(scriptDir.c_str(),
+ postflight,
+ "postinstall");
+ }
+
+
+ // The command that will be used to run ProductBuild
+ std::ostringstream pkgCmd;
+
+ std::string pkgId = "com.";
+ pkgId += this->GetOption("CPACK_PACKAGE_VENDOR");
+ pkgId += '.';
+ pkgId += this->GetOption("CPACK_PACKAGE_NAME");
+ if(component)
+ {
+ pkgId += '.';
+ pkgId += component->Name;
+ }
+
+ std::string version = this->GetOption("CPACK_PACKAGE_VERSION");
+ std::string pkgbuild = this->GetOption("CPACK_COMMAND_PKGBUILD");
+
+ pkgCmd << pkgbuild
+ << " --root \"" << packageDir << "\""
+ << " --identifier \"" << pkgId << "\""
+ << " --scripts \"" << scriptDir << "\""
+ << " --version \"" << version << "\""
+ << " --install-location \"/\""
+ << " \"" << packageFile << "\"";
+
+ // Run ProductBuild
+ return RunProductBuild(pkgCmd.str());
+}
+
+const char* cmCPackProductBuildGenerator::GetComponentScript(
+ const char* script,
+ const char* component_name)
+{
+ std::string scriptname = std::string("CPACK_") + script + "_";
+ if(component_name)
+ {
+ scriptname += cmSystemTools::UpperCase(component_name);
+ scriptname += "_";
+ }
+ scriptname += "SCRIPT";
+
+ return this->GetOption(scriptname);
+}
diff --git a/Source/CPack/cmCPackProductBuildGenerator.h b/Source/CPack/cmCPackProductBuildGenerator.h
new file mode 100644
index 0000000..0740f89
--- /dev/null
+++ b/Source/CPack/cmCPackProductBuildGenerator.h
@@ -0,0 +1,60 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc.
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef cmCPackProductBuildGenerator_h
+#define cmCPackProductBuildGenerator_h
+
+
+#include "cmCPackPKGGenerator.h"
+
+class cmCPackComponent;
+
+/** \class cmCPackProductBuildGenerator
+ * \brief A generator for ProductBuild files
+ *
+ */
+class cmCPackProductBuildGenerator : public cmCPackPKGGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackProductBuildGenerator, cmCPackPKGGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackProductBuildGenerator();
+ virtual ~cmCPackProductBuildGenerator();
+
+protected:
+ virtual int InitializeInternal();
+ int PackageFiles();
+ virtual const char* GetOutputExtension() { return ".pkg"; }
+
+ // Run ProductBuild with the given command line, which will (if
+ // successful) produce the given package file. Returns true if
+ // ProductBuild succeeds, false otherwise.
+ bool RunProductBuild(const std::string& command);
+
+ // Generate a package in the file packageFile for the given
+ // component. All of the files within this component are stored in
+ // the directory packageDir. Returns true if successful, false
+ // otherwise.
+ bool GenerateComponentPackage(const std::string& packageFileDir,
+ const std::string& packageFileName,
+ const std::string& packageDir,
+ const cmCPackComponent* component);
+
+ const char* GetComponentScript(const char* script,
+ const char* script_component);
+
+};
+
+#endif