From e9f69e067da3e096e1e64be70ec2b6de30f71d2c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 7 Apr 2021 11:33:05 +0200 Subject: Register environment variables for hermetic build configurations --- libbuild2/bin/guess.cxx | 51 ++++++++++++++++++++++++++++++++++++++++++++++--- libbuild2/bin/guess.hxx | 14 +++++++++++++- libbuild2/bin/init.cxx | 8 ++++++++ 3 files changed, 69 insertions(+), 4 deletions(-) (limited to 'libbuild2/bin') diff --git a/libbuild2/bin/guess.cxx b/libbuild2/bin/guess.cxx index 9f15030..219b8e8 100644 --- a/libbuild2/bin/guess.cxx +++ b/libbuild2/bin/guess.cxx @@ -326,6 +326,9 @@ namespace build2 fail << "unable to guess " << *rl << " signature"; } + // None of the ar/ranlib implementations we recognize seem to use + // environment variables (not even Microsoft lib.exe). + // return ar_cache.insert (move (key), ar_info { move (arp), @@ -333,13 +336,39 @@ namespace build2 move (arr.signature), move (arr.checksum), move (*arr.version), + nullptr, move (rlp), move (rlr.id), move (rlr.signature), - move (rlr.checksum)}); + move (rlr.checksum), + nullptr}); } + // Linker environment variables (see also the cc module which duplicates + // some of these). + // + // Notes: + // + // - GNU linkers search in LD_LIBRARY_PATH in addition to LD_RUN_PATH but + // we assume the former is part of the built-in list. Interestingly, + // LLD does not search in either. + // + // - The LLD family of linkers have a bunch of undocumented, debugging- + // related variables (LLD_REPRODUCE, LLD_VERSION, LLD_IN_TEST) that we + // ignore. + // + // - ld64 uses a ton of environment variables (according to the source + // code) but none of them are documented in the man pages. So someone + // will need to figure out what's important (some of them are clearly + // for debugging of ld itself). + // + static const char* gnu_ld_env[] = { + "LD_RUN_PATH", "GNUTARGET", "LDEMULATION", "COLLECT_NO_DEMANGLE", nullptr}; + + static const char* msvc_ld_env[] = { + "LIB", "LINK", "_LINK_", nullptr}; + // Extracting ld information requires running it which can become // expensive if done repeatedly. So we cache the result. // @@ -522,15 +551,26 @@ namespace build2 if (r.empty ()) fail << "unable to guess " << ld << " signature"; + const char* const* ld_env ((r.id == "gnu" || + r.id == "gnu-gold") ? gnu_ld_env : + (r.id == "msvc" || + r.id == "msvc-lld") ? msvc_ld_env : + nullptr); + return ld_cache.insert (move (key), ld_info { move (pp), move (r.id), move (r.signature), move (r.checksum), - move (r.version)}); + move (r.version), + ld_env}); } + // Resource compiler environment variables. + // + static const char* msvc_rc_env[] = {"INCLUDE", nullptr}; + // Extracting rc information requires running it which can become // expensive if done repeatedly. So we cache the result. // @@ -632,12 +672,17 @@ namespace build2 if (r.empty ()) fail << "unable to guess " << rc << " signature"; + const char* const* rc_env ((r.id == "msvc" || + r.id == "msvc-llvm") ? msvc_rc_env : + nullptr); + return rc_cache.insert (move (key), rc_info { move (pp), move (r.id), move (r.signature), - move (r.checksum)}); + move (r.checksum), + rc_env}); } } } diff --git a/libbuild2/bin/guess.hxx b/libbuild2/bin/guess.hxx index 9a63fa1..e5da263 100644 --- a/libbuild2/bin/guess.hxx +++ b/libbuild2/bin/guess.hxx @@ -28,6 +28,9 @@ namespace build2 // a toolchain-specific manner (usually the output of --version/-V) and // is not bulletproof. // + // The environment is an optional list of environment variables that + // affect ar/ranlib result. + // struct ar_info { process_path ar_path; @@ -35,11 +38,13 @@ namespace build2 string ar_signature; string ar_checksum; semantic_version ar_version; + const char* const* ar_environment; process_path ranlib_path; string ranlib_id; string ranlib_signature; string ranlib_checksum; + const char* const* ranlib_environment; }; // The ranlib path can be NULL, in which case no ranlib guessing will be @@ -72,6 +77,9 @@ namespace build2 // toolchain-specific manner (usually the output of --version/-version/-v) // and is not bulletproof. // + // The environment is an optional list of environment variables that + // affect the linker result. + // // Note that for now the version is extracted only for some linkers. Once // it's done for all of them, we should drop optional. // @@ -81,8 +89,8 @@ namespace build2 string id; string signature; string checksum; - optional version; + const char* const* environment; }; const ld_info& @@ -102,12 +110,16 @@ namespace build2 // toolchain-specific manner (usually the output of --version) and is not // bulletproof. // + // The environment is an optional list of environment variables that + // affect the resource compiler result. + // struct rc_info { process_path path; string id; string signature; string checksum; + const char* const* environment; }; const rc_info& diff --git a/libbuild2/bin/init.cxx b/libbuild2/bin/init.cxx index 51066cb..62c7bcf 100644 --- a/libbuild2/bin/init.cxx +++ b/libbuild2/bin/init.cxx @@ -740,6 +740,8 @@ namespace build2 rs.assign ("bin.ar.version.build") = v.build; } + config::save_environment (rs, ari.ar_environment); + if (ranlib != nullptr) { rs.assign ("bin.ranlib.path") = @@ -747,6 +749,8 @@ namespace build2 rs.assign ("bin.ranlib.id") = ari.ranlib_id; rs.assign ("bin.ranlib.signature") = ari.ranlib_signature; rs.assign ("bin.ranlib.checksum") = ari.ranlib_checksum; + + config::save_environment (rs, ari.ranlib_environment); } } @@ -871,6 +875,8 @@ namespace build2 rs.assign ("bin.ld.version.patch") = v.patch; rs.assign ("bin.ld.version.build") = v.build; } + + config::save_environment (rs, ldi.environment); } return true; @@ -995,6 +1001,8 @@ namespace build2 rs.assign ("bin.rc.id") = rci.id; rs.assign ("bin.rc.signature") = rci.signature; rs.assign ("bin.rc.checksum") = rci.checksum; + + config::save_environment (rs, rci.environment); } return true; -- cgit v1.1