فهرست منبع

file(ARCHIVE_CREATE): add WORKING_DIRECTORY option

Fixes: #25260
Issue: #21653
Yuri Witte 1 سال پیش
والد
کامیت
d8a9aabd24

+ 9 - 0
Help/command/file.rst

@@ -903,6 +903,7 @@ Archiving
     [COMPRESSION <compression>
     [COMPRESSION_LEVEL <compression-level>]]
     [MTIME <mtime>]
+    [WORKING_DIRECTORY <dir>]
     [VERBOSE])
   :target: ARCHIVE_CREATE
   :break: verbatim
@@ -946,6 +947,14 @@ Archiving
   ``MTIME <mtime>``
     Specify the modification time recorded in tarball entries.
 
+  ``WORKING_DIRECTORY <dir>``
+    .. versionadded:: 3.31
+
+    Specify the directory in which the archive creation operation will
+    be executed.  Paths in the ``<paths>`` argument can be relative to
+    this directory.  If this option is not provided, the current working
+    directory will be used by default.
+
   ``VERBOSE``
     Enable verbose output from the archive operation.
 

+ 5 - 0
Help/release/dev/file-archive-workdir.rst

@@ -0,0 +1,5 @@
+file-archive-workdir
+--------------------
+
+* The :command:`file(ARCHIVE_CREATE)` command gained a ``WORKING_DIRECTORY``
+  option to specify a working directory for the archiving process.

+ 2 - 2
Source/cmCTest.cxx

@@ -1646,8 +1646,8 @@ std::string cmCTest::Base64GzipEncodeFile(std::string const& file)
   std::vector<std::string> files;
   files.push_back(file);
 
-  if (!cmSystemTools::CreateTar(tarFile, files, cmSystemTools::TarCompressGZip,
-                                false)) {
+  if (!cmSystemTools::CreateTar(tarFile, files, {},
+                                cmSystemTools::TarCompressGZip, false)) {
     cmCTestLog(this, ERROR_MESSAGE,
                "Error creating tar while "
                "encoding file: "

+ 4 - 1
Source/cmFileCommand.cxx

@@ -3607,6 +3607,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
     // accepted without one and treated as if an empty value were given.
     // Fixing this would require a policy.
     ArgumentParser::Maybe<std::string> MTime;
+    std::string WorkingDirectory;
     bool Verbose = false;
     // "PATHS" requires at least one value, but use a custom check below.
     ArgumentParser::MaybeEmpty<std::vector<std::string>> Paths;
@@ -3619,6 +3620,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
       .Bind("COMPRESSION"_s, &Arguments::Compression)
       .Bind("COMPRESSION_LEVEL"_s, &Arguments::CompressionLevel)
       .Bind("MTIME"_s, &Arguments::MTime)
+      .Bind("WORKING_DIRECTORY"_s, &Arguments::WorkingDirectory)
       .Bind("VERBOSE"_s, &Arguments::Verbose)
       .Bind("PATHS"_s, &Arguments::Paths);
 
@@ -3718,7 +3720,8 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  if (!cmSystemTools::CreateTar(parsedArgs.Output, parsedArgs.Paths, compress,
+  if (!cmSystemTools::CreateTar(parsedArgs.Output, parsedArgs.Paths,
+                                parsedArgs.WorkingDirectory, compress,
                                 parsedArgs.Verbose, parsedArgs.MTime,
                                 parsedArgs.Format, compressionLevel)) {
     status.SetError(cmStrCat("failed to compress: ", parsedArgs.Output));

+ 8 - 1
Source/cmSystemTools.cxx

@@ -36,6 +36,7 @@
 #include "cmUVProcessChain.h"
 #include "cmUVStream.h"
 #include "cmValue.h"
+#include "cmWorkingDirectory.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
 #  include <cm3p/archive.h>
@@ -1867,12 +1868,18 @@ bool cmSystemTools::IsPathToMacOSSharedLibrary(const std::string& path)
 
 bool cmSystemTools::CreateTar(const std::string& outFileName,
                               const std::vector<std::string>& files,
+                              const std::string& workingDirectory,
                               cmTarCompression compressType, bool verbose,
                               std::string const& mtime,
                               std::string const& format, int compressionLevel)
 {
 #if !defined(CMAKE_BOOTSTRAP)
-  std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+  cmWorkingDirectory workdir(cmSystemTools::GetCurrentWorkingDirectory());
+  if (!workingDirectory.empty()) {
+    workdir.SetDirectory(workingDirectory);
+  }
+
+  const std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
   cmsys::ofstream fout(outFileName.c_str(), std::ios::out | std::ios::binary);
   if (!fout) {
     std::string e = cmStrCat("Cannot open output file \"", outFileName,

+ 1 - 0
Source/cmSystemTools.h

@@ -497,6 +497,7 @@ public:
                       const std::vector<std::string>& files, bool verbose);
   static bool CreateTar(const std::string& outFileName,
                         const std::vector<std::string>& files,
+                        const std::string& workingDirectory,
                         cmTarCompression compressType, bool verbose,
                         std::string const& mtime = std::string(),
                         std::string const& format = std::string(),

+ 2 - 2
Source/cmcmd.cxx

@@ -1550,8 +1550,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
         if (files.empty()) {
           std::cerr << "tar: No files or directories specified\n";
         }
-        if (!cmSystemTools::CreateTar(outFile, files, compress, verbose, mtime,
-                                      format)) {
+        if (!cmSystemTools::CreateTar(outFile, files, {}, compress, verbose,
+                                      mtime, format)) {
           cmSystemTools::Error("Problem creating tar: " + outFile);
           return 1;
         }

+ 2 - 0
Tests/RunCMake/File_Archive/RunCMakeTest.cmake

@@ -10,6 +10,8 @@ run_cmake(paxr)
 run_cmake(paxr-bz2)
 run_cmake(zip)
 
+run_cmake(working-directory)
+
 # Extracting only selected files or directories
 run_cmake(zip-filtered)
 

+ 4 - 3
Tests/RunCMake/File_Archive/roundtrip.cmake

@@ -39,8 +39,9 @@ file(ARCHIVE_CREATE
   OUTPUT ${FULL_OUTPUT_NAME}
   FORMAT "${ARCHIVE_FORMAT}"
   COMPRESSION "${COMPRESSION_TYPE}"
+  WORKING_DIRECTORY "${WORKING_DIRECTORY}"
   VERBOSE
-  PATHS ${COMPRESS_DIR})
+  PATHS ${FULL_COMPRESS_DIR})
 
 file(ARCHIVE_EXTRACT
   INPUT ${FULL_OUTPUT_NAME}
@@ -54,10 +55,10 @@ endif()
 
 foreach(file ${CHECK_FILES})
   set(input ${FULL_COMPRESS_DIR}/${file})
-  set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file})
+  set(output ${FULL_DECOMPRESS_DIR}/${CUSTOM_OUTPUT_DIRECTORY}/${COMPRESS_DIR}/${file})
 
   if(NOT EXISTS ${input})
-    message(SEND_ERROR "Cannot find input file ${output}")
+    message(SEND_ERROR "Cannot find input file ${input}")
   endif()
 
   if(NOT EXISTS ${output})

+ 12 - 0
Tests/RunCMake/File_Archive/working-directory.cmake

@@ -0,0 +1,12 @@
+set(OUTPUT_NAME "test.zip")
+
+set(ARCHIVE_FORMAT zip)
+
+get_filename_component(CURRENT_FILE_NAME ${CMAKE_CURRENT_LIST_FILE} NAME_WE)
+set(CUSTOM_OUTPUT_DIRECTORY "${CURRENT_FILE_NAME}-build")
+
+set(WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../")
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("504b0304" LIMIT 4 HEX)