diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2020-12-15 09:25:19 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2020-12-15 09:31:59 +0200 |
commit | f7a245b2b6091ef3a5e1193423c7fbbd6fe6a538 (patch) | |
tree | 28b3006840b718084f229820e0408b0712674232 /libbuild2/cc/module.cxx | |
parent | 8c9b0fb944a60d8193d8ac3dbac4e8e15f81bf57 (diff) |
Cache more results of executing programs (compilers, etc)
Diffstat (limited to 'libbuild2/cc/module.cxx')
-rw-r--r-- | libbuild2/cc/module.cxx | 85 |
1 files changed, 65 insertions, 20 deletions
diff --git a/libbuild2/cc/module.cxx b/libbuild2/cc/module.cxx index 14182a2..8241a01 100644 --- a/libbuild2/cc/module.cxx +++ b/libbuild2/cc/module.cxx @@ -338,6 +338,17 @@ namespace build2 # endif #endif + // Extracting search dirs can be expensive (we may need to run the + // compiler several times) so we cache the result. + // + struct search_dirs + { + pair<dir_paths, size_t> lib; + pair<dir_paths, size_t> inc; + }; + + static global_cache<search_dirs> dirs_cache; + void config_module:: init (scope& rs, const location& loc, const variable_map&) { @@ -440,33 +451,67 @@ namespace build2 pair<dir_paths, size_t> inc_dirs; const optional<pair<dir_paths, size_t>>& mod_dirs (xi.sys_mod_dirs); - if (xi.sys_lib_dirs) + if (xi.sys_lib_dirs && xi.sys_inc_dirs) + { lib_dirs = *xi.sys_lib_dirs; + inc_dirs = *xi.sys_inc_dirs; + } else { - switch (xi.class_) + string key; { - case compiler_class::gcc: - lib_dirs = gcc_library_search_dirs (xi.path, rs); - break; - case compiler_class::msvc: - lib_dirs = msvc_library_search_dirs (xi.path, rs); - break; + sha256 cs; + cs.append (static_cast<size_t> (x_lang)); + cs.append (xi.path.effect_string ()); + append_options (cs, mode); + key = cs.string (); } - } - if (xi.sys_inc_dirs) - inc_dirs = *xi.sys_inc_dirs; - else - { - switch (xi.class_) + // Because the compiler info (xi) is also cached, we can assume that + // if dirs come from there, then they do so consistently. + // + const search_dirs* sd (dirs_cache.find (key)); + + if (xi.sys_lib_dirs) + lib_dirs = *xi.sys_lib_dirs; + else if (sd != nullptr) + lib_dirs = sd->lib; + else + { + switch (xi.class_) + { + case compiler_class::gcc: + lib_dirs = gcc_library_search_dirs (xi.path, rs); + break; + case compiler_class::msvc: + lib_dirs = msvc_library_search_dirs (xi.path, rs); + break; + } + } + + if (xi.sys_inc_dirs) + inc_dirs = *xi.sys_inc_dirs; + else if (sd != nullptr) + inc_dirs = sd->inc; + else + { + switch (xi.class_) + { + case compiler_class::gcc: + inc_dirs = gcc_header_search_dirs (xi.path, rs); + break; + case compiler_class::msvc: + inc_dirs = msvc_header_search_dirs (xi.path, rs); + break; + } + } + + if (sd == nullptr) { - case compiler_class::gcc: - inc_dirs = gcc_header_search_dirs (xi.path, rs); - break; - case compiler_class::msvc: - inc_dirs = msvc_header_search_dirs (xi.path, rs); - break; + search_dirs sd; + if (!xi.sys_lib_dirs) sd.lib = lib_dirs; + if (!xi.sys_inc_dirs) sd.inc = inc_dirs; + dirs_cache.insert (move (key), move (sd)); } } |