diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2021-04-07 11:33:05 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2021-04-07 11:43:04 +0200 |
commit | e9f69e067da3e096e1e64be70ec2b6de30f71d2c (patch) | |
tree | 478c9f0ec86a225398424bcc9305270ca6800339 /libbuild2/config/utility.hxx | |
parent | 5e51d523e71231cb190e9ed981962df527f4ee7e (diff) |
Register environment variables for hermetic build configurations
Diffstat (limited to 'libbuild2/config/utility.hxx')
-rw-r--r-- | libbuild2/config/utility.hxx | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/libbuild2/config/utility.hxx b/libbuild2/config/utility.hxx index 45fdaba..382c22f 100644 --- a/libbuild2/config/utility.hxx +++ b/libbuild2/config/utility.hxx @@ -36,6 +36,9 @@ namespace build2 (*config_save_variable) (scope&, const variable&, optional<uint64_t>); LIBBUILD2_SYMEXPORT extern void + (*config_save_environment) (scope&, const char*); + + LIBBUILD2_SYMEXPORT extern void (*config_save_module) (scope&, const char*, int); LIBBUILD2_SYMEXPORT extern const string& @@ -53,7 +56,7 @@ namespace build2 namespace config { - // Mark the variable to be saved during configuration. + // Mark a variable to be saved during configuration. // const uint64_t save_default_commented = 0x01; // Based on value::extra. const uint64_t save_null_omitted = 0x02; // Treat NULL as undefined. @@ -67,7 +70,7 @@ namespace build2 config_save_variable (rs, var, flags); } - // Mark the variable as "unsaved" (always transient). + // Mark a variable as "unsaved" (always transient). // // Such variables are not very common and are usually used to control the // process of configuration itself. @@ -79,6 +82,82 @@ namespace build2 config_save_variable (rs, var, nullopt); } + // Mark an environment variable to be saved during hermetic configuration. + // + // Some notes/suggestions on saving environment variables for tools (e.g., + // compilers, etc): + // + // 1. We want to save variables that affect the result (e.g., build + // output) rather than byproducts (e.g., diagnostics). + // + // 2. Environment variables are often poorly documented (and not always in + // the ENVIRONMENT section; sometimes they are mentioned together with + // the corresponding option). A sensible approach in this case is to + // save documented (and perhaps well-known undocumented) variables -- + // the user can always save additional variables if necessary. The way + // to discover undocumented environment variables is to grep the source + // code. + // + // 3. Sometime environment variables only affect certain modes of a tool. + // If such modes are not used, then there is no need to save the + // corresponding variables. + // + // 4. Finally, there could be environment variables that are incompatible + // with what we are doing (e.g., they change the mode of operation or + // some such; see GCC's DEPENDENCIES_OUTPUT for example). While they + // can be cleared for each invocation, this is burdensome and it is + // often easier to just unset them for the entire build system process + // if we can be reasonable sure that there can be no plausible use for + // this variable (e.g., by another module or by the buildfile + // directly). The module's load() function is a natural place to do + // that. + // + inline void + save_environment (scope& rs, const string& var) + { + if (config_save_environment != nullptr) + config_save_environment (rs, var.c_str ()); + } + + inline void + save_environment (scope& rs, const char* var) + { + if (config_save_environment != nullptr) + config_save_environment (rs, var); + } + + inline void + save_environment (scope& rs, initializer_list<const char*> vars) + { + if (config_save_environment != nullptr) + { + for (const char* var: vars) + config_save_environment (rs, var); + } + } + + inline void + save_environment (scope& rs, const strings& vars) + { + if (config_save_environment != nullptr) + { + for (const string& var: vars) + config_save_environment (rs, var.c_str ()); + } + } + + // A NULL-terminated list of variables. + // + inline void + save_environment (scope& rs, const char* const* vars) + { + if (vars != nullptr && config_save_environment != nullptr) + { + for (; *vars != nullptr; ++vars) + config_save_environment (rs, *vars); + } + } + // Establish module save order/priority with INT32_MIN being the highest. // Modules with the same priority are saved in the order inserted. // |