summaryrefslogtreecommitdiff
path: root/devel/cmake/files/patch-cmake-issue-18031
blob: 4185603c947ee3ebc1cfe2b1deb3ed92a0628b48 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
diff --git Modules/Internal/CPack/CPackFreeBSD.cmake Modules/Internal/CPack/CPackFreeBSD.cmake
index ae40532017..c35089cbcf 100644
--- Modules/Internal/CPack/CPackFreeBSD.cmake
+++ Modules/Internal/CPack/CPackFreeBSD.cmake
@@ -34,7 +34,7 @@ function(_cpack_freebsd_fallback_var OUTPUT_VAR_NAME)
     endif()
   endforeach()
   if(NOT VALUE)
-    message(WARNING "Variable ${OUTPUT_VAR_NAME} could not be given a fallback value from any variable ${FALLBACK_VAR_NAMES}.")
+    message(WARNING "Variable ${OUTPUT_VAR_NAME} could not be given a fallback value from (any of) ${FALLBACK_VAR_NAMES}.")
   endif()
 endfunction()
 
diff --git Source/CPack/cmCPackFreeBSDGenerator.cxx Source/CPack/cmCPackFreeBSDGenerator.cxx
index 39ec3c83ed..c09989ceed 100644
--- Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -21,8 +21,15 @@
 
 #include <sys/stat.h>
 
+// Suffix used to tell libpkg what compression to use
+static const char FreeBSDPackageCompression[] = "txz";
+// Resulting package file-suffix, for < 1.17 and >= 1.17 versions of libpkg
+static const char FreeBSDPackageSuffix_10[] = ".txz";
+static const char FreeBSDPackageSuffix_17[] = ".pkg";
+
 cmCPackFreeBSDGenerator::cmCPackFreeBSDGenerator()
-  : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", ".txz")
+  : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr",
+                            FreeBSDPackageSuffix_17 /* old-style, updated if an old-style package is created */)
 {
 }
 
@@ -35,6 +42,56 @@ int cmCPackFreeBSDGenerator::InitializeInternal()
 
 cmCPackFreeBSDGenerator::~cmCPackFreeBSDGenerator() = default;
 
+// This is a wrapper for struct pkg_create and pkg_create()
+//
+// Instantiate this class with suitable parameters, then
+// check isValid() to check if it's ok. Afterwards, call
+// Create() to do the actual work. This will leave a package
+// in the given `output_dir`.
+//
+// This wrapper cleans up the struct pkg_create.
+class PkgCreate
+{
+public:
+  PkgCreate()
+    : d(nullptr)
+  {
+  }
+  PkgCreate(const std::string& output_dir, const std::string& toplevel_dir,
+            const std::string& manifest_name)
+    : d(pkg_create_new())
+    , manifest(manifest_name)
+
+  {
+    if (d) {
+      pkg_create_set_format(d, FreeBSDPackageCompression); // Skip over the '.'
+      pkg_create_set_compression_level(d, 0); // Explicitly set default
+      pkg_create_set_overwrite(d, false);
+      pkg_create_set_rootdir(d, toplevel_dir.c_str());
+      pkg_create_set_output_dir(d, output_dir.c_str());
+    }
+  }
+  ~PkgCreate()
+  {
+    if (d)
+      pkg_create_free(d);
+  }
+
+  bool isValid() const { return d; }
+
+  bool Create()
+  {
+    if (!isValid())
+      return false;
+    int r = pkg_create(d, manifest.c_str(), nullptr, false);
+    return r == 0;
+  }
+
+private:
+  struct pkg_create* d;
+  std::string manifest;
+};
+
 // This is a wrapper, for use only in stream-based output,
 // that will output a string in UCL escaped fashion (in particular,
 // quotes and backslashes are escaped). The list of characters
@@ -271,7 +328,7 @@ void write_manifest_files(cmGeneratedFileStream& s,
   s << "\"files\": {\n";
   for (std::string const& file : files) {
     s << "  \"/" << cmSystemTools::RelativePath(toplevel, file) << "\": \""
-      << "<sha256>"
+      << "<sha256>" // this gets replaced by libpkg by the actual SHA256
       << "\",\n";
   }
   s << "  },\n";
@@ -281,11 +338,10 @@ int cmCPackFreeBSDGenerator::PackageFiles()
 {
   if (!this->ReadListFile("Internal/CPack/CPackFreeBSD.cmake")) {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
-                  "Error while execution CPackFreeBSD.cmake" << std::endl);
+                  "Error while executing CPackFreeBSD.cmake" << std::endl);
     return 0;
   }
 
-  std::vector<std::string>::const_iterator fileIt;
   cmWorkingDirectory wd(toplevel);
 
   files.erase(std::remove_if(files.begin(), files.end(), ignore_file),
@@ -317,20 +373,79 @@ int cmCPackFreeBSDGenerator::PackageFiles()
                              ONE_PACKAGE_PER_COMPONENT);
   }
 
+  // There should be one name in the packageFileNames (already, see comment
+  // in cmCPackGenerator::DoPackage(), which holds what CPack guesses
+  // will be the package filename. libpkg does something else, though,
+  // so update the single filename to what we know will be right.
+  if (this->packageFileNames.size() == 1) {
+    std::string currentPackage = this->packageFileNames[0];
+    int lastSlash = currentPackage.rfind('/');
+
+    // If there is a pathname, preserve that; libpkg will write out
+    // a file with the package name and version as specified in the
+    // manifest, so we look those up (again). lastSlash is the slash
+    // itself, we need that as path separator to the calculated package name.
+    std::string actualPackage =
+      ((lastSlash != std::string::npos)
+         ? std::string(currentPackage, 0, lastSlash + 1)
+         : std::string()) +
+      var_lookup("CPACK_FREEBSD_PACKAGE_NAME") + '-' +
+      var_lookup("CPACK_FREEBSD_PACKAGE_VERSION") + FreeBSDPackageSuffix_17;
+
+    this->packageFileNames.clear();
+    this->packageFileNames.emplace_back(actualPackage);
+
+    cmCPackLogger(cmCPackLog::LOG_DEBUG,
+                  "Real filename:" << this->packageFileNames[0] << std::endl);
+  }
+
+  if (!pkg_initialized() && pkg_init(NULL, NULL) != EPKG_OK) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Can not initialize FreeBSD libpkg." << std::endl);
+    return 0;
+  }
+
   std::string output_dir = cmSystemTools::CollapseFullPath("../", toplevel);
-  pkg_create_from_manifest(output_dir.c_str(), ::TXZ, toplevel.c_str(),
-                           manifestname.c_str(), nullptr);
+  PkgCreate package(output_dir, toplevel, manifestname);
+  if (package.isValid()) {
+    if (!package.Create()) {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Error during pkg_create()" << std::endl);
+      return 0;
+    }
+  } else {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Error before pkg_create()" << std::endl);
+    return 0;
+  }
 
-  std::string broken_suffix =
-    cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), ".txz");
+  // Specifically looking for packages suffixed with the TAG, either extension
+  std::string broken_suffix_10 =
+    cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), FreeBSDPackageSuffix_10);
+  std::string broken_suffix_17 =
+    cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), FreeBSDPackageSuffix_17);
   for (std::string& name : packageFileNames) {
     cmCPackLogger(cmCPackLog::LOG_DEBUG, "Packagefile " << name << std::endl);
-    if (cmHasSuffix(name, broken_suffix)) {
-      name.replace(name.size() - broken_suffix.size(), std::string::npos,
-                   ".txz");
+    if (cmHasSuffix(name, broken_suffix_10)) {
+      name.replace(name.size() - broken_suffix_10.size(), std::string::npos,
+                   FreeBSDPackageSuffix_10);
+      break;
+    }
+    if (cmHasSuffix(name, broken_suffix_17)) {
+      name.replace(name.size() - broken_suffix_17.size(), std::string::npos,
+                   FreeBSDPackageSuffix_17);
       break;
     }
   }
+  // If the name uses a *new* style name, which doesn't exist, but there
+  // is an *old* style name, then use that instead. This indicates we used
+  // an older libpkg, which still creates .txz instead of .pkg files.
+  for (std::string& name : packageFileNames) {
+    if (cmHasSuffix(name, FreeBSDPackageSuffix_17) && !cmSystemTools::FileExists(name)) {
+      const std::string suffix(FreeBSDPackageSuffix_17);
+      name.replace(name.size() - suffix.size(), std::string::npos, suffix);
+    }
+  }
 
   return 1;
 }