From 957f4f45caa6399c4c7a900cccb0fadfeab6878c Mon Sep 17 00:00:00 2001 From: John Haugabook Date: Thu, 24 Jul 2025 02:49:51 +0100 Subject: [PATCH setup v2] add --build-depend option add --build-depend option --- Makefile.am | 2 + build_depends.cc | 145 +++++++++++++++++++++++++++++++++++++++++++++++ build_depends.h | 36 ++++++++++++ package_meta.cc | 14 ++++- res/en/res.rc | 1 + resource.h | 1 + 6 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 build_depends.cc create mode 100644 build_depends.h diff --git a/Makefile.am b/Makefile.am index 4046d37..daf1609 100644 --- a/Makefile.am +++ b/Makefile.am @@ -136,6 +136,8 @@ endif archive_tar.cc \ archive_tar.h \ archive_tar_file.cc \ + build_depends.h \ + build_depends.cc \ choose.cc \ choose.h \ compactos.cc \ diff --git a/build_depends.cc b/build_depends.cc new file mode 100644 index 0000000..d1e4684 --- /dev/null +++ b/build_depends.cc @@ -0,0 +1,145 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + */ + +#include "build_depends.h" + +#include +#include +#include +#include +#include +#include + +#include "io_stream.h" +#include "ini.h" +#include "resource.h" +#include "site.h" +#include "state.h" +#include "csu_util/rfc1738.h" +#include "package_meta.h" +#include "getopt++/StringArrayOption.h" + +// Forward declare class for ==build-depend option. +StringOption BuildDependsOption ("", '\0', "build-depend", IDS_HELPTEXT_BUILD_DEPENDS, false); + +/* Used in package_meta to redefine PackageOption so output from +build-depend can be substituted. */ +bool buildDependPackage; + +// Add extern declarations for variables from ini.cc +extern std::string local_dir; +extern SiteList site_list; + +// Add extern declaration for PackageOption from package_meta.cc +extern StringArrayOption PackageOption; + +std::string +build_depend(std::string pkg_search) +{ + // Use option passed as argument. + std::string target_pkg = pkg_search; + + // Mark and property for identifying package and extracting value. + std::string pkg_marker = "@"; + std::string key = "build-depends:"; + + std::string depend_packages; // for final output + + // Use the cached setup.ini file created by ini.cc instead of parameter + std::string cached_ini_path = local_dir + "/" + + rfc1738_escape_part(site_list.begin()->url) + + "/" + SetupArch() + "/" + SetupBaseName() + ".ini"; + + std::ifstream infile(cached_ini_path); + + // Ensure setup.ini was identified + if (!infile) { + depend_packages = "Error opening cached setup.ini"; + return depend_packages; + } + + // Start process of reading setup. + std::string line; + bool inPkg = false; + while (std::getline(infile, line)) { + std::istringstream iss(line); + std::string first, second; + iss >> first >> second; + + // For each pkg_marker check if name matches option. + if (first == pkg_marker) + { + if (second == target_pkg) + { + // Package found, handle next lines accordingly. + inPkg = true; + continue; + } + else + { + inPkg = false; + continue; + } + } + + // If package found and has property build-depends. + if (inPkg && line.find(key) == 0) { + /* Extract by property length, then remove space character + using ASCII encoding. */ + depend_packages = line.substr(key.size()); + + // Trim leading whitespace. + depend_packages.erase(0, depend_packages.find_first_not_of(" \t")); + depend_packages.erase(depend_packages.find_last_not_of(" \t") + 1); + + // Set condition to use build-depend output in package_meta.cc. + buildDependPackage = true; + + // Output to PackageOption. + return depend_packages; + } + } + // Output package passed to variable if none found. + buildDependPackage = false; + return target_pkg; +} + +// Process build_depend() output and use to create PackageOption class. +void +process_build_depends_to_package_option(std::string pkg_search) +{ + // Get build dependencies from build_depend function using the passed parameter. + std::string build_deps_result = build_depend(pkg_search); + + // Ensure results are returned. + if (build_deps_result != "no-build-depends-found" && + build_deps_result != "Error opening cached setup.ini" && + !build_deps_result.empty()) + { + // Also parse individual dependencies for PackageOption. + std::istringstream deps_stream(build_deps_result); + std::string dep_name; + + while (std::getline(deps_stream, dep_name, ',')) + { + // Trim whitespace. + dep_name.erase(0, dep_name.find_first_not_of(" \t")); + dep_name.erase(dep_name.find_last_not_of(" \t") + 1); + + if (!dep_name.empty()) + { + /* Add the entire dependency string to PackageOption as one entry + This simulates: ./setup -P package1,package2,etc... */ + PackageOption.Process(dep_name.c_str(), 0); + } + } + } +} diff --git a/build_depends.h b/build_depends.h new file mode 100644 index 0000000..cd83c3a --- /dev/null +++ b/build_depends.h @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + */ + +#ifndef USE_BUILD_DEPENDS_H +#define USE_BUILD_DEPENDS_H + +#include "getopt++/StringOption.h" +#include "getopt++/StringArrayOption.h" +#include "resource.h" + +// Declare as extern in header - actual definition should be in build_depends.cc +extern StringOption BuildDependsOption; + +extern std::vector BuildDependPackages; + +// Use to pass build-depends packages in package_meta.cc +extern bool buildDependPackage; + +// Forward declare external PackageOption from package_meta.cc +extern StringArrayOption PackageOption; + +// Forward declare function for use. +std::string build_depend(std::string pkg_search); + +// Forward declare function to process build-depends values and pass to PackageOption. +void process_build_depends_to_package_option(std::string pkg_search); + +#endif /* USE_BUILD_DEPENDS_H */ diff --git a/package_meta.cc b/package_meta.cc index 3daa970..97bd32c 100644 --- a/package_meta.cc +++ b/package_meta.cc @@ -26,6 +26,7 @@ #include "io_stream.h" #include "compress.h" +#include "build_depends.h" #include "filemanip.h" #include "LogSingleton.h" @@ -47,7 +48,7 @@ static StringArrayOption DeletePackageOption ('x', "remove-packages", IDS_HELPTEXT_REMOVE_PACKAGES); static StringArrayOption DeleteCategoryOption ('c', "remove-categories", IDS_HELPTEXT_REMOVE_CATEGORIES); -static StringArrayOption PackageOption ('P', "packages", IDS_HELPTEXT_PACKAGES); +StringArrayOption PackageOption ('P', "packages", IDS_HELPTEXT_PACKAGES); static StringArrayOption CategoryOption ('C', "categories", IDS_HELPTEXT_CATEGORIES); bool hasManualSelections = 0; @@ -342,6 +343,15 @@ bool packagemeta::isManuallyWanted(packageversion &version) const option string and store them away in an STL set. */ if (!parsed_yet) { + // Check --build-depend first and process it into PackageOption. + std::string build_depends_options = BuildDependsOption; + if (!build_depends_options.empty()) + { + // Process build depends and add directly to PackageOption + process_build_depends_to_package_option(build_depends_options); + } + + // Now use PackageOption for all processing. std::vector packages_options = PackageOption; std::vector categories_options = CategoryOption; @@ -845,7 +855,7 @@ packagemeta::scan (const packageversion &pkg, bool mirror_mode) && ::source == IDC_SOURCE_LOCALDIR) return false; } - catch (Exception * e) + catch (Exception * e) { // We can ignore these, since we're clearing the source list anyway if (e->errNo () == APPERR_CORRUPT_PACKAGE) diff --git a/res/en/res.rc b/res/en/res.rc index 0bdd4c7..d8b2298 100644 --- a/res/en/res.rc +++ b/res/en/res.rc @@ -656,6 +656,7 @@ BEGIN IDS_HELPTEXT_ALLOW_UNSUPPORTED_WINDOWS "Allow old, unsupported Windows versions" IDS_HELPTEXT_ARCH "Architecture to install (x86_64 or x86)" IDS_HELPTEXT_CATEGORIES "Specify categories to install" + IDS_HELPTEXT_BUILD_DEPENDS "Install the build requirements of a package" IDS_HELPTEXT_COMPACTOS "Compress installed files with Compact OS (xpress4k, xpress8k, xpress16k, lzx)" IDS_HELPTEXT_DELETE_ORPHANS "Remove orphaned packages" IDS_HELPTEXT_DISABLE_ANTIVIRUS "Disable known or suspected buggy anti virus software packages during execution" diff --git a/resource.h b/resource.h index a08489c..11fef73 100644 --- a/resource.h +++ b/resource.h @@ -158,6 +158,7 @@ #define IDS_HELPTEXT_HEADER 1546 #define IDS_HELPTEXT_FOOTER 1547 #define IDS_HELPTEXT_NO_WRITE_REGISTRY 1548 +#define IDS_HELPTEXT_BUILD_DEPENDS 1549 // Dialogs -- 2.49.0.windows.1