From 0ac1ac798ebdbd717d1b6196465b0c1570a9f45c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 7 Oct 2020 16:22:31 +0200 Subject: FreeBSD: migrate to newer pkg_create(3) API The pkg_create_from_manifest() function was never really intended as stable API, and bapt@ has asked me to stop using it so the public API can be stabilized. Port to pkg_create() with its attendant settings struct. Since we already have a complete manifest file, we can hand that (including the embedded plist) to pkg_create(). While here, reintroduce pkg_init(), which lived in downstream patches for a while and then went away again. --- Source/CPack/cmCPackFreeBSDGenerator.cxx | 72 ++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index fcd5753..5876fb9 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -35,6 +35,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, "txz"); + 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 @@ -281,7 +331,7 @@ 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; } @@ -317,9 +367,25 @@ int cmCPackFreeBSDGenerator::PackageFiles() ONE_PACKAGE_PER_COMPONENT); } + 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"); -- cgit v0.12 From d5ae2f97545bb599151d0d6fa818d3e84867514f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 27 Feb 2021 17:35:56 +0100 Subject: FreeBSD: fix up the package name When using libpkg, the output filename is determined by libpkg itself, based on information in the manifest: package name and version, basically. This doesn't necessarily match the name that CMake has determined via CPACK_TEMPORARY_PACKAGE_FILE_NAME or CPACK_PACKAGE_FILE_NAME. So reset the CMake-determined list to match what libpkg will do. --- Modules/Internal/CPack/CPackFreeBSD.cmake | 2 +- Source/CPack/cmCPackFreeBSDGenerator.cxx | 41 ++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Modules/Internal/CPack/CPackFreeBSD.cmake b/Modules/Internal/CPack/CPackFreeBSD.cmake index ae40532..c35089c 100644 --- a/Modules/Internal/CPack/CPackFreeBSD.cmake +++ b/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 a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index 5876fb9..5e91214 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -21,8 +21,12 @@ #include +// Suffix including the '.', used to tell libpkg what compression to use +static const char FreeBSDPackageSuffix[] = ".txz"; + cmCPackFreeBSDGenerator::cmCPackFreeBSDGenerator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", ".txz") + : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", + FreeBSDPackageSuffix) { } @@ -57,7 +61,7 @@ public: { if (d) { - pkg_create_set_format(d, "txz"); + pkg_create_set_format(d, FreeBSDPackageSuffix + 1); // 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()); @@ -321,7 +325,7 @@ void write_manifest_files(cmGeneratedFileStream& s, s << "\"files\": {\n"; for (std::string const& file : files) { s << " \"/" << cmSystemTools::RelativePath(toplevel, file) << "\": \"" - << "" + << "" // this gets replaced by libpkg by the actual SHA256 << "\",\n"; } s << " },\n"; @@ -335,7 +339,6 @@ int cmCPackFreeBSDGenerator::PackageFiles() return 0; } - std::vector::const_iterator fileIt; cmWorkingDirectory wd(toplevel); files.erase(std::remove_if(files.begin(), files.end(), ignore_file), @@ -367,6 +370,32 @@ 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; + + 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); @@ -388,12 +417,12 @@ int cmCPackFreeBSDGenerator::PackageFiles() } std::string broken_suffix = - cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), ".txz"); + cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), FreeBSDPackageSuffix); 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"); + FreeBSDPackageSuffix); break; } } -- cgit v0.12 From a76f19d5e836aa271b4e8161497112d79572642c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Sep 2021 13:43:30 +0200 Subject: FreeBSD: handle new package-file-suffix --- Source/CPack/cmCPackFreeBSDGenerator.cxx | 42 +++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index 5e91214..bacb451 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -21,12 +21,14 @@ #include -// Suffix including the '.', used to tell libpkg what compression to use -static const char FreeBSDPackageSuffix[] = ".txz"; +// 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", - FreeBSDPackageSuffix) + : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", FreeBSDPackageSuffix_17 /* old-style, updated if an old-style package is created */) { } @@ -61,7 +63,7 @@ public: { if (d) { - pkg_create_set_format(d, FreeBSDPackageSuffix + 1); // Skip over the '.' + 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()); @@ -387,7 +389,7 @@ int cmCPackFreeBSDGenerator::PackageFiles() ? std::string(currentPackage, 0, lastSlash + 1) : std::string()) + var_lookup("CPACK_FREEBSD_PACKAGE_NAME") + '-' + - var_lookup("CPACK_FREEBSD_PACKAGE_VERSION") + FreeBSDPackageSuffix; + var_lookup("CPACK_FREEBSD_PACKAGE_VERSION") + FreeBSDPackageSuffix_17; this->packageFileNames.clear(); this->packageFileNames.emplace_back(actualPackage); @@ -416,15 +418,33 @@ int cmCPackFreeBSDGenerator::PackageFiles() return 0; } - std::string broken_suffix = - cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), FreeBSDPackageSuffix); + // 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, - FreeBSDPackageSuffix); + 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; -- cgit v0.12 From c3715e08e44ea42a8d823b909dcd849051eacc63 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Dec 2021 14:26:45 +0100 Subject: FreeBSD: tidy up - mismatched comments and code, - remove superfluous log of the "Real package" (which can still change! log the changed filename if it does), - the "fix up the package name" code was replacing the pkg 1.17 suffix by the pkg 1.17 suffix, so it wasn't really being useful. Whether **any** of the backwards- compatibility packaging code is useful is another thing. --- Source/CPack/cmCPackFreeBSDGenerator.cxx | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx index bacb451..b5d41fc 100644 --- a/Source/CPack/cmCPackFreeBSDGenerator.cxx +++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx @@ -28,7 +28,8 @@ static const char FreeBSDPackageSuffix_10[] = ".txz"; static const char FreeBSDPackageSuffix_17[] = ".pkg"; cmCPackFreeBSDGenerator::cmCPackFreeBSDGenerator() - : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", FreeBSDPackageSuffix_17 /* old-style, updated if an old-style package is created */) + : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", + FreeBSDPackageSuffix_17) { } @@ -63,7 +64,7 @@ public: { if (d) { - pkg_create_set_format(d, FreeBSDPackageCompression); // Skip over the '.' + pkg_create_set_format(d, FreeBSDPackageCompression); 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()); @@ -378,7 +379,7 @@ int cmCPackFreeBSDGenerator::PackageFiles() // 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('/'); + auto 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 @@ -393,9 +394,6 @@ int cmCPackFreeBSDGenerator::PackageFiles() 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) { @@ -442,8 +440,16 @@ int cmCPackFreeBSDGenerator::PackageFiles() 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); + const std::string badSuffix(FreeBSDPackageSuffix_17); + const std::string goodSuffix(FreeBSDPackageSuffix_10); + std::string repairedName(name); + repairedName.replace(repairedName.size() - badSuffix.size(), + std::string::npos, goodSuffix); + if (cmSystemTools::FileExists(repairedName)) { + name = repairedName; + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "Repaired packagefile " << name << std::endl); + } } } -- cgit v0.12