Hello, This patch adds an option --build-depend that, when called; installs the packages listed in the build-depends property. It is for someone who wants to build the binaries of a package themselves, enabling them to pass one string value to the setup command in lieu of an array of packages.
> On 18/07/2025, Jon Turney via Cygwin-apps [[PATCH setup] add --build-depend > option] wrote: >> If you take a look at >> IniDBBuilderPackage.cc:IniDBBuilderPackage::buildBeginBuildDepends(), >> you'll see where the current handling of build-requires data parsed from >> setup.ini stops. >> >> It should be relatively straightforward to add another "nodeList" here, >> to assemble the data parsed from build-requires: lines in setup.ini >> (identically to the existing handling of >> depends/obsoletes/provides/conflicts) It was straightforward, but I was not able to edit build_depend() in such a way as to implement this (believe I tried). Instead I had to use "local_dir" declared in state.h, using the definition from ini.cc to work as the setup.ini for build_depend() to iterate over and parse output from. If the parsed output from that is up-to-date, then from what I've loosely tested, the packages returned are as if -P was used to install. > On 18/07/2025, Jon Turney via Cygwin-apps [[PATCH setup] add --build-depend > option] wrote: >> In choose.cc:ChooserPage::applyCommandLinePackageSelection() there's an >> existing block of code which handles, uh, command line package selection. I was able to implement the redirect from the parsed output from build_depend() to define a class instance of PackageOption so choose.cc can work as if -P were used. NOTE - currently unsure of the file name (build_depends), and option name (--build-depend) as using the option builds one instance - hence singular usage; and the file build-depends (implied possessive) of packages (if that makes sense). Not attached to naming, and if maintainers want to move forward with this patch, then would like to use whatever naming they think is best. --- >From 957f4f45caa6399c4c7a900cccb0fadfeab6878c Mon Sep 17 00:00:00 2001 From: John Haugabook <johnhaugab...@gmail.com> 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 <fstream> +#include <algorithm> +#include <iostream> +#include <string> +#include <sstream> +#include <cstdio> + +#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<std::string> 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<std::string> packages_options = PackageOption; std::vector<std::string> 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 Take Care, John Haugabook
From 957f4f45caa6399c4c7a900cccb0fadfeab6878c Mon Sep 17 00:00:00 2001 From: John Haugabook <johnhaugabook@gmail.com> 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 <fstream> +#include <algorithm> +#include <iostream> +#include <string> +#include <sstream> +#include <cstdio> + +#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<std::string> 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<std::string> packages_options = PackageOption; std::vector<std::string> 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