From 40863a594372ede117533d5c0970a96d60e34371 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 22 Apr 2021 10:10:34 +0200 Subject: Incorporate project environment checksum into cc::compiler_info cache key --- libbuild2/bin/guess.cxx | 12 ++++++++++++ libbuild2/bin/guess.hxx | 9 +++++++++ libbuild2/cc/guess.cxx | 17 +++++++++++++++++ libbuild2/cc/guess.hxx | 4 ++++ libbuild2/cc/module.cxx | 4 +++- libbuild2/config/init.cxx | 8 +++++++- libbuild2/file.cxx | 3 ++- libbuild2/scope.hxx | 6 ++++++ 8 files changed, 60 insertions(+), 3 deletions(-) diff --git a/libbuild2/bin/guess.cxx b/libbuild2/bin/guess.cxx index 219b8e8..8dd3cb6 100644 --- a/libbuild2/bin/guess.cxx +++ b/libbuild2/bin/guess.cxx @@ -363,6 +363,9 @@ namespace build2 // will need to figure out what's important (some of them are clearly // for debugging of ld itself). // + // See also the note on environment and caching below if adding any new + // variables. + // static const char* gnu_ld_env[] = { "LD_RUN_PATH", "GNUTARGET", "LDEMULATION", "COLLECT_NO_DEMANGLE", nullptr}; @@ -381,6 +384,9 @@ namespace build2 // First check the cache. // + // Note that none of the information that we cache can be affected by + // the environment. + // string key; { sha256 cs; @@ -569,6 +575,9 @@ namespace build2 // Resource compiler environment variables. // + // See also the note on environment and caching below if adding any new + // variables. + // static const char* msvc_rc_env[] = {"INCLUDE", nullptr}; // Extracting rc information requires running it which can become @@ -583,6 +592,9 @@ namespace build2 // First check the cache. // + // Note that none of the information that we cache can be affected by + // the environment. + // string key; { sha256 cs; diff --git a/libbuild2/bin/guess.hxx b/libbuild2/bin/guess.hxx index e5da263..3307999 100644 --- a/libbuild2/bin/guess.hxx +++ b/libbuild2/bin/guess.hxx @@ -31,6 +31,9 @@ namespace build2 // The environment is an optional list of environment variables that // affect ar/ranlib result. // + // Watch out for the environment not to affect any of the extracted + // information since we cache it. + // struct ar_info { process_path ar_path; @@ -80,6 +83,9 @@ namespace build2 // The environment is an optional list of environment variables that // affect the linker result. // + // Watch out for the environment not to affect any of the extracted + // information since we cache it. + // // Note that for now the version is extracted only for some linkers. Once // it's done for all of them, we should drop optional. // @@ -113,6 +119,9 @@ namespace build2 // The environment is an optional list of environment variables that // affect the resource compiler result. // + // Watch out for the environment not to affect any of the extracted + // information since we cache it. + // struct rc_info { process_path path; diff --git a/libbuild2/cc/guess.cxx b/libbuild2/cc/guess.cxx index 839bf20..ff96466 100644 --- a/libbuild2/cc/guess.cxx +++ b/libbuild2/cc/guess.cxx @@ -1577,6 +1577,9 @@ namespace build2 // but we include them in case linking is done via the compiler without // loading bin.ld. BTW, the same applies to rc.exe INCLUDE. // + // See also the note on environment and caching below if adding any new + // variables. + // static const char* msvc_env[] = {"INCLUDE", "IFCPATH", "CL", "_CL_", "LIB", "LINK", "_LINK_", nullptr}; @@ -1822,6 +1825,9 @@ namespace build2 // would need to detect which linker is being used at which point we might // as well load bin.ld). // + // See also the note on environment and caching below if adding any new + // variables. + // static const char* gcc_c_env[] = { "CPATH", "C_INCLUDE_PATH", "LIBRARY_PATH", "LD_RUN_PATH", @@ -2275,6 +2281,8 @@ namespace build2 // These are derived from gcc_* plus the sparse documentation (clang(1)) // and source code. // + // See also the note on environment and caching below if adding any new + // variables. // static const char* clang_c_env[] = { "CPATH", "C_INCLUDE_PATH", @@ -3064,6 +3072,7 @@ namespace build2 const compiler_info& guess (const char* xm, lang xl, + const string& ec, const path& xc, const string* xis, const string* xv, @@ -3075,6 +3084,13 @@ namespace build2 { // First check the cache. // + // Note that in case of MSVC (and Clang targeting MSVC) sys_*_dirs can + // be affected by the environment (INCLUDE, LIB, and IFCPATH) which is + // project-specific. So we have to include those into the key. But we + // don't know yet know whether it's those compilers/targets. So it seems + // we have no better choice than to include the project environment if + // overridden. + // // @@ We currently include config.{cc,x}.[pc]options into the key which // means any project-specific tweaks to these result in a different // key. Perhaps we should assume that any options that can affect the @@ -3087,6 +3103,7 @@ namespace build2 sha256 cs; cs.append (static_cast (xl)); cs.append (xc.string ()); + if (!ec.empty ()) cs.append (ec); if (xis != nullptr) cs.append (*xis); append_options (cs, x_mo); if (c_po != nullptr) append_options (cs, *c_po); diff --git a/libbuild2/cc/guess.hxx b/libbuild2/cc/guess.hxx index 6bab649..0180c97 100644 --- a/libbuild2/cc/guess.hxx +++ b/libbuild2/cc/guess.hxx @@ -173,6 +173,9 @@ namespace build2 // search paths (similar to the PATH environment variable), in which case // it will end with a directory separator but will not contain '*'. // + // Watch out for the environment variables affecting any of the extracted + // information (like sys_*_dirs) since we cache it. + // struct compiler_info { process_path path; @@ -252,6 +255,7 @@ namespace build2 const compiler_info& guess (const char* xm, // Module (for var names in diagnostics). lang xl, // Language. + const string& ec, // Environment checksum. const path& xc, // Compiler path. const string* xi, // Compiler id (optional). const string* xv, // Compiler version (optional). diff --git a/libbuild2/cc/module.cxx b/libbuild2/cc/module.cxx index 98e0451..44f1943 100644 --- a/libbuild2/cc/module.cxx +++ b/libbuild2/cc/module.cxx @@ -154,7 +154,9 @@ namespace build2 // we are now folding *.std options into mode options. // x_info = &build2::cc::guess ( - x, x_lang, move (xc), + x, x_lang, + rs.root_extra->environment_checksum, + move (xc), cast_null (lookup_config (rs, config_x_id)), cast_null (lookup_config (rs, config_x_version)), cast_null (lookup_config (rs, config_x_target)), diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx index 7b810bd..87b492c 100644 --- a/libbuild2/config/init.cxx +++ b/libbuild2/config/init.cxx @@ -455,13 +455,15 @@ namespace build2 rs.vars.erase (c_e); // Undefine. } - // Copy config.config.environment to scope::root_extra::environment. + // Copy config.config.environment to scope::root_extra::environment and + // calculate its checksum. // // Note that we store shallow copies that point to the c.c.environment // value which means it should not change. // if (const strings* src = cast_null (rs[c_e])) { + sha256 cs; vector& dst (rs.root_extra->environment); // The idea is to only copy entries that are effective, that is those @@ -511,10 +513,14 @@ namespace build2 } dst.push_back (v.c_str ()); + cs.append (v); } if (!dst.empty ()) + { dst.push_back (nullptr); + rs.root_extra->environment_checksum = cs.string (); + } } // Register alias and fallback rule for the configure meta-operation. diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index 02ad71d..8bc84e2 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -610,7 +610,8 @@ namespace build2 {}, /* modules */ {}, /* override_cache */ {}, /* target_types */ - {}} /* environment */); + {}, /* environment */ + ""} /* environment_checksum */); // Enter built-in meta-operation and operation names. Loading of // modules (via the src bootstrap; see below) can result in diff --git a/libbuild2/scope.hxx b/libbuild2/scope.hxx index 9f88dc9..f78a565 100644 --- a/libbuild2/scope.hxx +++ b/libbuild2/scope.hxx @@ -501,6 +501,12 @@ namespace build2 // See also auto_project_env below. // vector environment; + + // A checksum of the above environment variables (empty if there are + // none). This can be used to take into account project environment + // when, for example, caching environment-sensitive information. + // + string environment_checksum; }; unique_ptr root_extra; -- cgit v1.1