aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc/module.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-12-15 09:25:19 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-12-15 09:31:59 +0200
commitf7a245b2b6091ef3a5e1193423c7fbbd6fe6a538 (patch)
tree28b3006840b718084f229820e0408b0712674232 /libbuild2/cc/module.cxx
parent8c9b0fb944a60d8193d8ac3dbac4e8e15f81bf57 (diff)
Cache more results of executing programs (compilers, etc)
Diffstat (limited to 'libbuild2/cc/module.cxx')
-rw-r--r--libbuild2/cc/module.cxx85
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));
}
}