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/cc/compile-rule.cxx | 2 +- libbuild2/cc/guess.cxx | 107 ++++++++++++++++++++++++++++++++++++++++-- libbuild2/cc/guess.hxx | 6 +++ libbuild2/cc/module.cxx | 3 ++ 4 files changed, 112 insertions(+), 6 deletions(-) (limited to 'libbuild2/cc') diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx index a27530a..b5016bc 100644 --- a/libbuild2/cc/compile-rule.cxx +++ b/libbuild2/cc/compile-rule.cxx @@ -6596,7 +6596,7 @@ namespace build2 if (getenv ("IFCPATH")) { // VC's IFCPATH takes precedence over /module:stdIfcDir so unset it if - // we are using our own std modules. + // we are using our own std modules. Note: IFCPATH saved in guess.cxx. // if (!stdifc.empty ()) env.push_back ("IFCPATH"); diff --git a/libbuild2/cc/guess.cxx b/libbuild2/cc/guess.cxx index d80fd17..82be591 100644 --- a/libbuild2/cc/guess.cxx +++ b/libbuild2/cc/guess.cxx @@ -829,7 +829,9 @@ namespace build2 // // The main drawback of the latter, of course, is that the commands we // print are no longer re-runnable (even though we may have supplied - // the rest of the "environment" explicitly on the command line). + // the rest of the "environment" explicitly on the command line). Plus + // we would need to save whatever environment variables we used to + // form the fallback path in case of hermetic configuration. // // An alternative strategy is to try and obtain the corresponding // "environment" in case of the effective (absolute) path similar to @@ -1571,6 +1573,13 @@ namespace build2 const char* msvc_cpu (const string&); // msvc.cxx + // Note that LIB, LINK, and _LINK_ are technically link.exe's variables + // but we include them in case linking is done via the compiler without + // loading bin.ld. BTW, the same applies to rc.exe INCLUDE. + // + static const char* msvc_env[] = {"INCLUDE", "IFCPATH", "CL", "_CL_", + "LIB", "LINK", "_LINK_", nullptr}; + static compiler_info guess_msvc (const char* xm, lang xl, @@ -1796,9 +1805,41 @@ namespace build2 move (xsl), move (lib_dirs), move (inc_dirs), - move (mod_dirs)}; + move (mod_dirs), + msvc_env, + nullptr}; } + // See "Environment Variables Affecting GCC". + // + // @@ TODO: Yt feels like we should unset the following variables: + // + // DEPENDENCIES_OUTPUT + // SUNPRO_DEPENDENCIES + // + // Note also that we include (some) linker's variables in case linking is + // done via the compiler without loading bin.ld (to do this precisely we + // would need to detect which linker is being used at which point we might + // as well load bin.ld). + // + static const char* gcc_c_env[] = { + "CPATH", "C_INCLUDE_PATH", + "LIBRARY_PATH", "LD_RUN_PATH", + "SOURCE_DATE_EPOCH", "GCC_EXEC_PREFIX", "COMPILER_PATH", + nullptr}; + + static const char* gcc_cxx_env[] = { + "CPATH", "CPLUS_INCLUDE_PATH", + "LIBRARY_PATH", "LD_RUN_PATH", + "SOURCE_DATE_EPOCH", "GCC_EXEC_PREFIX", "COMPILER_PATH", + nullptr}; + + // Note that Clang recognizes a whole family of *_DEPLOYMENT_TARGET + // variables. + // + static const char* macos_env[] = { + "SDKROOT", "MACOSX_DEPLOYMENT_TARGET", nullptr}; + static compiler_info guess_gcc (const char* xm, lang xl, @@ -1979,6 +2020,17 @@ namespace build2 } } + // Environment. + // + const char* const* c_env (nullptr); + switch (xl) + { + case lang::c: c_env = gcc_c_env; break; + case lang::cxx: c_env = gcc_cxx_env; break; + } + + const char* const* p_env (tt.system == "darwin" ? macos_env : nullptr); + return compiler_info { move (gr.path), move (gr.id), @@ -1996,7 +2048,9 @@ namespace build2 move (xsl), nullopt, nullopt, - nullopt}; + nullopt, + c_env, + p_env}; } struct clang_msvc_info: msvc_info @@ -2218,6 +2272,22 @@ namespace build2 return r; } + // These are derived from gcc_* plus the sparse documentation (clang(1)) + // and source code. + // + // + static const char* clang_c_env[] = { + "CPATH", "C_INCLUDE_PATH", + "LIBRARY_PATH", "LD_RUN_PATH", + "COMPILER_PATH", + nullptr}; + + static const char* clang_cxx_env[] = { + "CPATH", "CPLUS_INCLUDE_PATH", + "LIBRARY_PATH", "LD_RUN_PATH", + "COMPILER_PATH", + nullptr}; + static compiler_info guess_clang (const char* xm, lang xl, @@ -2624,6 +2694,29 @@ namespace build2 } } + // Environment. + // + // Note that "Emscripten Compiler Frontend (emcc)" has a long list of + // environment variables with little explanation. So someone will need + // to figure out what's important (some of them are clearly for + // debugging of emcc itself). + // + const char* const* c_env (nullptr); + const char* const* p_env (nullptr); + if (tt.system == "win32-msvc") + c_env = msvc_env; + else + { + switch (xl) + { + case lang::c: c_env = clang_c_env; break; + case lang::cxx: c_env = clang_cxx_env; break; + } + + if (tt.system == "darwin") + p_env = macos_env; + } + return compiler_info { move (gr.path), move (gr.id), @@ -2641,7 +2734,9 @@ namespace build2 move (xsl), move (lib_dirs), nullopt, - nullopt}; + nullopt, + c_env, + p_env}; } static compiler_info @@ -2956,7 +3051,9 @@ namespace build2 move (xsl), nullopt, nullopt, - nullopt}; + nullopt, + nullptr, /* TODO */ + nullptr}; } // Compiler checks can be expensive (we often need to run the compiler diff --git a/libbuild2/cc/guess.hxx b/libbuild2/cc/guess.hxx index a141fa3..6bab649 100644 --- a/libbuild2/cc/guess.hxx +++ b/libbuild2/cc/guess.hxx @@ -236,6 +236,12 @@ namespace build2 optional> sys_lib_dirs; optional> sys_inc_dirs; optional> sys_mod_dirs; + + // Optional list of environment variables that affect the compiler and + // its target platform. + // + const char* const* compiler_environment; + const char* const* platform_environment; }; // In a sense this is analagous to the language standard which we handle diff --git a/libbuild2/cc/module.cxx b/libbuild2/cc/module.cxx index 2300927..5bb3f60 100644 --- a/libbuild2/cc/module.cxx +++ b/libbuild2/cc/module.cxx @@ -706,6 +706,9 @@ namespace build2 rs.assign (x_sys_lib_dirs) = move (lib_dirs.first); rs.assign (x_sys_inc_dirs) = move (inc_dirs.first); + config::save_environment (rs, xi.compiler_environment); + config::save_environment (rs, xi.platform_environment); + // Load cc.core.config. // if (!cast_false (rs["cc.core.config.loaded"])) -- cgit v1.1