diff options
-rw-r--r-- | Help/cpack_gen/external.rst | 54 | ||||
-rw-r--r-- | Source/CPack/cmCPackExtGenerator.cxx | 70 | ||||
-rw-r--r-- | Source/CPack/cmCPackExtGenerator.h | 2 | ||||
-rw-r--r-- | Source/CPack/cmCPackGenerator.h | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CPack/RunCMakeTest.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/CPack/tests/EXT/ExpectedFiles.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CPack/tests/EXT/create_package.cmake | 24 | ||||
-rw-r--r-- | Tests/RunCMake/CPack/tests/EXT/stage_and_package-stderr.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CPack/tests/EXT/test.cmake | 3 |
9 files changed, 127 insertions, 33 deletions
diff --git a/Help/cpack_gen/external.rst b/Help/cpack_gen/external.rst index a69866d..f98e1c9 100644 --- a/Help/cpack_gen/external.rst +++ b/Help/cpack_gen/external.rst @@ -10,19 +10,32 @@ 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 +Integration with External Packaging Tools +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The CPack External generator generates a .json file containing the +CPack internal metadata, which gives external software information +on how to package the software. External packaging software may itself +invoke CPack, consume the generated metadata, +install and package files as required. + +Alternatively CPack can invoke an external packaging software +through an optional custom CMake script in +:variable:`CPACK_EXT_PACKAGE_SCRIPT` instead. + +Staging of installation files may also optionally be +taken care of by the generator when enabled through the +:variable:`CPACK_EXT_ENABLE_STAGING` variable. + +JSON Format +^^^^^^^^^^^ + +The JSON 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: +The JSON's 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) @@ -247,3 +260,24 @@ Variables specific to CPack External generator 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. + +.. variable:: CPACK_EXT_ENABLE_STAGING + + This variable can be set to true to enable optional installation + into a temporary staging area which can then be picked up + and packaged by an external packaging tool. + The top level directory used by CPack for the current packaging + task is contained in ``CPACK_TOPLEVEL_DIRECTORY``. + It is automatically cleaned up on each run before packaging is initiated + and can be used for custom temporary files required by + the external packaging tool. + It also contains the staging area ``CPACK_TEMPORARY_DIRECTORY`` + into which CPack performs the installation when staging is enabled. + +.. variable:: CPACK_EXT_PACKAGE_SCRIPT + + This variable can optionally specify the full path to + a CMake script file to be run as part of the CPack invocation. + It is invoked after (optional) staging took place and may + run an external packaging tool. The script has access to + the variables defined by the CPack config file. diff --git a/Source/CPack/cmCPackExtGenerator.cxx b/Source/CPack/cmCPackExtGenerator.cxx index c36b098..4c560b9 100644 --- a/Source/CPack/cmCPackExtGenerator.cxx +++ b/Source/CPack/cmCPackExtGenerator.cxx @@ -5,6 +5,7 @@ #include "cmAlgorithms.h" #include "cmCPackComponentGroup.h" #include "cmCPackLog.h" +#include "cmMakefile.h" #include "cmSystemTools.h" #include "cm_jsoncpp_value.h" @@ -56,6 +57,23 @@ int cmCPackExtGenerator::PackageFiles() return 0; } + const char* packageScript = this->GetOption("CPACK_EXT_PACKAGE_SCRIPT"); + if (packageScript && *packageScript) { + if (!cmSystemTools::FileIsFullPath(packageScript)) { + cmCPackLogger( + cmCPackLog::LOG_ERROR, + "CPACK_EXT_PACKAGE_SCRIPT does not contain a full file path" + << std::endl); + return 0; + } + + int res = this->MakefileMap->ReadListFile(packageScript); + + if (cmSystemTools::GetErrorOccuredFlag() || !res) { + return 0; + } + } + return 1; } @@ -67,16 +85,22 @@ bool cmCPackExtGenerator::SupportsComponentInstallation() const int cmCPackExtGenerator::InstallProjectViaInstallCommands( bool setDestDir, const std::string& tempInstallDirectory) { - (void)setDestDir; - (void)tempInstallDirectory; + if (this->StagingEnabled()) { + return cmCPackGenerator::InstallProjectViaInstallCommands( + setDestDir, tempInstallDirectory); + } + return 1; } int cmCPackExtGenerator::InstallProjectViaInstallScript( bool setDestDir, const std::string& tempInstallDirectory) { - (void)setDestDir; - (void)tempInstallDirectory; + if (this->StagingEnabled()) { + return cmCPackGenerator::InstallProjectViaInstallScript( + setDestDir, tempInstallDirectory); + } + return 1; } @@ -84,9 +108,11 @@ int cmCPackExtGenerator::InstallProjectViaInstalledDirectories( bool setDestDir, const std::string& tempInstallDirectory, const mode_t* default_dir_mode) { - (void)setDestDir; - (void)tempInstallDirectory; - (void)default_dir_mode; + if (this->StagingEnabled()) { + return cmCPackGenerator::InstallProjectViaInstalledDirectories( + setDestDir, tempInstallDirectory, default_dir_mode); + } + return 1; } @@ -94,10 +120,11 @@ 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; + if (this->StagingEnabled()) { + return cmCPackGenerator::RunPreinstallTarget( + installProjectName, installDirectory, globalGenerator, buildConfig); + } + return 1; } @@ -108,18 +135,21 @@ int cmCPackExtGenerator::InstallCMakeProject( 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; + if (this->StagingEnabled()) { + return cmCPackGenerator::InstallCMakeProject( + setDestDir, installDirectory, baseTempInstallDirectory, default_dir_mode, + component, componentInstall, installSubDirectory, buildConfig, + absoluteDestFiles); + } + return 1; } +bool cmCPackExtGenerator::StagingEnabled() const +{ + return !cmSystemTools::IsOff(this->GetOption("CPACK_EXT_ENABLE_STAGING")); +} + cmCPackExtGenerator::cmCPackExtVersionGenerator::cmCPackExtVersionGenerator( cmCPackExtGenerator* parent) : Parent(parent) diff --git a/Source/CPack/cmCPackExtGenerator.h b/Source/CPack/cmCPackExtGenerator.h index fa12d7f..103e56d 100644 --- a/Source/CPack/cmCPackExtGenerator.h +++ b/Source/CPack/cmCPackExtGenerator.h @@ -52,6 +52,8 @@ protected: std::string& absoluteDestFiles) override; private: + bool StagingEnabled() const; + class cmCPackExtVersionGenerator { public: diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index c13c649..4755f94 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -321,7 +321,6 @@ protected: bool Trace; bool TraceExpand; -private: cmMakefile* MakefileMap; }; diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake index b273c1e..91fed3e 100644 --- a/Tests/RunCMake/CPack/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake @@ -35,4 +35,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") +run_cpack_test_subtests(EXT "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "Ext" false "MONOLITHIC;COMPONENT") diff --git a/Tests/RunCMake/CPack/tests/EXT/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/EXT/ExpectedFiles.cmake index 2634111..91608c9 100644 --- a/Tests/RunCMake/CPack/tests/EXT/ExpectedFiles.cmake +++ b/Tests/RunCMake/CPack/tests/EXT/ExpectedFiles.cmake @@ -1,4 +1,5 @@ -if(RunCMake_SUBTEST_SUFFIX MATCHES "^(none|good(_multi)?|invalid_good)$") +if(RunCMake_SUBTEST_SUFFIX MATCHES "^(none|good(_multi)?|invalid_good)$" + OR RunCMake_SUBTEST_SUFFIX STREQUAL "stage_and_package") 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() diff --git a/Tests/RunCMake/CPack/tests/EXT/create_package.cmake b/Tests/RunCMake/CPack/tests/EXT/create_package.cmake new file mode 100644 index 0000000..e308ccb --- /dev/null +++ b/Tests/RunCMake/CPack/tests/EXT/create_package.cmake @@ -0,0 +1,24 @@ +message("This script could run an external packaging tool") + +function(expect_variable VAR) + if(NOT ${VAR}) + message(FATAL_ERROR "${VAR} is unexpectedly not set") + endif() +endfunction() + +function(expect_file FILE) + if(NOT EXISTS "${FILE}") + message(FATAL_ERROR "${FILE} is unexpectedly missing") + endif() +endfunction() + +expect_variable(CPACK_COMPONENTS_ALL) +expect_variable(CPACK_TOPLEVEL_DIRECTORY) +expect_variable(CPACK_TEMPORARY_DIRECTORY) +expect_variable(CPACK_PACKAGE_DIRECTORY) +expect_variable(CPACK_PACKAGE_FILE_NAME) + +expect_file(${CPACK_TEMPORARY_DIRECTORY}/f1/share/cpack-test/f1.txt) +expect_file(${CPACK_TEMPORARY_DIRECTORY}/f2/share/cpack-test/f2.txt) +expect_file(${CPACK_TEMPORARY_DIRECTORY}/f3/share/cpack-test/f3.txt) +expect_file(${CPACK_TEMPORARY_DIRECTORY}/f4/share/cpack-test/f4.txt) diff --git a/Tests/RunCMake/CPack/tests/EXT/stage_and_package-stderr.txt b/Tests/RunCMake/CPack/tests/EXT/stage_and_package-stderr.txt new file mode 100644 index 0000000..40f2743 --- /dev/null +++ b/Tests/RunCMake/CPack/tests/EXT/stage_and_package-stderr.txt @@ -0,0 +1 @@ +^This script could run an external packaging tool$ diff --git a/Tests/RunCMake/CPack/tests/EXT/test.cmake b/Tests/RunCMake/CPack/tests/EXT/test.cmake index 6bd3cb8..976cb6a 100644 --- a/Tests/RunCMake/CPack/tests/EXT/test.cmake +++ b/Tests/RunCMake/CPack/tests/EXT/test.cmake @@ -14,6 +14,9 @@ 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") +elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "stage_and_package") + set(CPACK_EXT_ENABLE_STAGING 1) + set(CPACK_EXT_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/create_package.cmake") endif() file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/f1.txt" test1) |