aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/bin
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/bin
parent8c9b0fb944a60d8193d8ac3dbac4e8e15f81bf57 (diff)
Cache more results of executing programs (compilers, etc)
Diffstat (limited to 'libbuild2/bin')
-rw-r--r--libbuild2/bin/guess.cxx109
-rw-r--r--libbuild2/bin/guess.hxx6
-rw-r--r--libbuild2/bin/init.cxx51
3 files changed, 111 insertions, 55 deletions
diff --git a/libbuild2/bin/guess.cxx b/libbuild2/bin/guess.cxx
index 21936d9..9f15030 100644
--- a/libbuild2/bin/guess.cxx
+++ b/libbuild2/bin/guess.cxx
@@ -54,7 +54,7 @@ namespace build2
{
process_path r (
run_try_search (prog,
- true /* init */,
+ false /* init (cached) */,
dir_path () /* fallback */,
true /* path_only */,
paths));
@@ -80,14 +80,33 @@ namespace build2
dr << info << "use " << var << " to override";
});
- return run_search (prog, true, dir_path (), true);
+ return run_search (prog, false, dir_path (), true);
}
- ar_info
+ // Extracting ar/ranlib information requires running them which can become
+ // expensive if done repeatedly. So we cache the result.
+ //
+ static global_cache<ar_info> ar_cache;
+
+ const ar_info&
guess_ar (const path& ar, const path* rl, const char* paths)
{
tracer trace ("bin::guess_ar");
+ // First check the cache.
+ //
+ string key;
+ {
+ sha256 cs;
+ cs.append (ar.string ());
+ if (rl != nullptr) cs.append (rl->string ());
+ if (paths != nullptr) cs.append (paths);
+ key = cs.string ();
+
+ if (const ar_info* r = ar_cache.find (key))
+ return *r;
+ }
+
guess_result arr, rlr;
process_path arp (search (ar, paths, "config.bin.ar"));
@@ -307,24 +326,43 @@ namespace build2
fail << "unable to guess " << *rl << " signature";
}
- return ar_info {
- move (arp),
- move (arr.id),
- move (arr.signature),
- move (arr.checksum),
- move (*arr.version),
-
- move (rlp),
- move (rlr.id),
- move (rlr.signature),
- move (rlr.checksum)};
+ return ar_cache.insert (move (key),
+ ar_info {
+ move (arp),
+ move (arr.id),
+ move (arr.signature),
+ move (arr.checksum),
+ move (*arr.version),
+
+ move (rlp),
+ move (rlr.id),
+ move (rlr.signature),
+ move (rlr.checksum)});
}
- ld_info
+ // Extracting ld information requires running it which can become
+ // expensive if done repeatedly. So we cache the result.
+ //
+ static global_cache<ld_info> ld_cache;
+
+ const ld_info&
guess_ld (const path& ld, const char* paths)
{
tracer trace ("bin::guess_ld");
+ // First check the cache.
+ //
+ string key;
+ {
+ sha256 cs;
+ cs.append (ld.string ());
+ if (paths != nullptr) cs.append (paths);
+ key = cs.string ();
+
+ if (const ld_info* r = ld_cache.find (key))
+ return *r;
+ }
+
guess_result r;
process_path pp (search (ld, paths, "config.bin.ld"));
@@ -484,19 +522,38 @@ namespace build2
if (r.empty ())
fail << "unable to guess " << ld << " signature";
- return ld_info {
- move (pp),
- move (r.id),
- move (r.signature),
- move (r.checksum),
- move (r.version)};
+ return ld_cache.insert (move (key),
+ ld_info {
+ move (pp),
+ move (r.id),
+ move (r.signature),
+ move (r.checksum),
+ move (r.version)});
}
- rc_info
+ // Extracting rc information requires running it which can become
+ // expensive if done repeatedly. So we cache the result.
+ //
+ static global_cache<rc_info> rc_cache;
+
+ const rc_info&
guess_rc (const path& rc, const char* paths)
{
tracer trace ("bin::guess_rc");
+ // First check the cache.
+ //
+ string key;
+ {
+ sha256 cs;
+ cs.append (rc.string ());
+ if (paths != nullptr) cs.append (paths);
+ key = cs.string ();
+
+ if (const rc_info* r = rc_cache.find (key))
+ return *r;
+ }
+
guess_result r;
process_path pp (search (rc, paths, "config.bin.rc"));
@@ -575,8 +632,12 @@ namespace build2
if (r.empty ())
fail << "unable to guess " << rc << " signature";
- return rc_info {
- move (pp), move (r.id), move (r.signature), move (r.checksum)};
+ return rc_cache.insert (move (key),
+ rc_info {
+ move (pp),
+ move (r.id),
+ move (r.signature),
+ move (r.checksum)});
}
}
}
diff --git a/libbuild2/bin/guess.hxx b/libbuild2/bin/guess.hxx
index 27bb5ed..9a63fa1 100644
--- a/libbuild2/bin/guess.hxx
+++ b/libbuild2/bin/guess.hxx
@@ -45,7 +45,7 @@ namespace build2
// The ranlib path can be NULL, in which case no ranlib guessing will be
// attemplated and the returned ranlib_* members will be left empty.
//
- ar_info
+ const ar_info&
guess_ar (const path& ar, const path* ranlib, const char* paths);
// ld information.
@@ -85,7 +85,7 @@ namespace build2
optional<semantic_version> version;
};
- ld_info
+ const ld_info&
guess_ld (const path& ld, const char* paths);
// rc information.
@@ -110,7 +110,7 @@ namespace build2
string checksum;
};
- rc_info
+ const rc_info&
guess_rc (const path& rc, const char* paths);
}
}
diff --git a/libbuild2/bin/init.cxx b/libbuild2/bin/init.cxx
index 49ba518..6d2d2c2 100644
--- a/libbuild2/bin/init.cxx
+++ b/libbuild2/bin/init.cxx
@@ -683,7 +683,7 @@ namespace build2
nullptr,
config::save_default_commented)));
- ar_info ari (guess_ar (ar, ranlib, pat.paths));
+ const ar_info& ari (guess_ar (ar, ranlib, pat.paths));
// If this is a configuration with new values, then print the report
// at verbosity level 2 and up (-v).
@@ -723,33 +723,28 @@ namespace build2
}
rs.assign<process_path_ex> ("bin.ar.path") =
- process_path_ex (move (ari.ar_path), "ar", ari.ar_checksum);
- rs.assign<string> ("bin.ar.id") = move (ari.ar_id);
- rs.assign<string> ("bin.ar.signature") = move (ari.ar_signature);
- rs.assign<string> ("bin.ar.checksum") = move (ari.ar_checksum);
+ process_path_ex (ari.ar_path, "ar", ari.ar_checksum);
+ rs.assign<string> ("bin.ar.id") = ari.ar_id;
+ rs.assign<string> ("bin.ar.signature") = ari.ar_signature;
+ rs.assign<string> ("bin.ar.checksum") = ari.ar_checksum;
{
- semantic_version& v (ari.ar_version);
+ const semantic_version& v (ari.ar_version);
rs.assign<string> ("bin.ar.version") = v.string ();
rs.assign<uint64_t> ("bin.ar.version.major") = v.major;
rs.assign<uint64_t> ("bin.ar.version.minor") = v.minor;
rs.assign<uint64_t> ("bin.ar.version.patch") = v.patch;
- rs.assign<string> ("bin.ar.version.build") = move (v.build);
+ rs.assign<string> ("bin.ar.version.build") = v.build;
}
if (ranlib != nullptr)
{
rs.assign<process_path_ex> ("bin.ranlib.path") =
- process_path_ex (move (ari.ranlib_path),
- "ranlib",
- ari.ranlib_checksum);
- rs.assign<string> ("bin.ranlib.id") =
- move (ari.ranlib_id);
- rs.assign<string> ("bin.ranlib.signature") =
- move (ari.ranlib_signature);
- rs.assign<string> ("bin.ranlib.checksum") =
- move (ari.ranlib_checksum);
+ process_path_ex (ari.ranlib_path, "ranlib", ari.ranlib_checksum);
+ rs.assign<string> ("bin.ranlib.id") = ari.ranlib_id;
+ rs.assign<string> ("bin.ranlib.signature") = ari.ranlib_signature;
+ rs.assign<string> ("bin.ranlib.checksum") = ari.ranlib_checksum;
}
}
@@ -826,7 +821,7 @@ namespace build2
path (apply_pattern (ld_d, pat.pattern)),
config::save_default_commented)));
- ld_info ldi (guess_ld (ld, pat.paths));
+ const ld_info& ldi (guess_ld (ld, pat.paths));
// If this is a configuration with new values, then print the report
// at verbosity level 2 and up (-v).
@@ -859,20 +854,20 @@ namespace build2
}
rs.assign<process_path_ex> ("bin.ld.path") =
- process_path_ex (move (ldi.path), "ld", ldi.checksum);
- rs.assign<string> ("bin.ld.id") = move (ldi.id);
- rs.assign<string> ("bin.ld.signature") = move (ldi.signature);
- rs.assign<string> ("bin.ld.checksum") = move (ldi.checksum);
+ process_path_ex (ldi.path, "ld", ldi.checksum);
+ rs.assign<string> ("bin.ld.id") = ldi.id;
+ rs.assign<string> ("bin.ld.signature") = ldi.signature;
+ rs.assign<string> ("bin.ld.checksum") = ldi.checksum;
if (ldi.version)
{
- semantic_version& v (*ldi.version);
+ const semantic_version& v (*ldi.version);
rs.assign<string> ("bin.ld.version") = v.string ();
rs.assign<uint64_t> ("bin.ld.version.major") = v.major;
rs.assign<uint64_t> ("bin.ld.version.minor") = v.minor;
rs.assign<uint64_t> ("bin.ld.version.patch") = v.patch;
- rs.assign<string> ("bin.ld.version.build") = move (v.build);
+ rs.assign<string> ("bin.ld.version.build") = v.build;
}
}
@@ -979,7 +974,7 @@ namespace build2
path (apply_pattern (rc_d, pat.pattern)),
config::save_default_commented)));
- rc_info rci (guess_rc (rc, pat.paths));
+ const rc_info& rci (guess_rc (rc, pat.paths));
// If this is a configuration with new values, then print the report
// at verbosity level 2 and up (-v).
@@ -994,10 +989,10 @@ namespace build2
}
rs.assign<process_path_ex> ("bin.rc.path") =
- process_path_ex (move (rci.path), "rc", rci.checksum);
- rs.assign<string> ("bin.rc.id") = move (rci.id);
- rs.assign<string> ("bin.rc.signature") = move (rci.signature);
- rs.assign<string> ("bin.rc.checksum") = move (rci.checksum);
+ process_path_ex (rci.path, "rc", rci.checksum);
+ rs.assign<string> ("bin.rc.id") = rci.id;
+ rs.assign<string> ("bin.rc.signature") = rci.signature;
+ rs.assign<string> ("bin.rc.checksum") = rci.checksum;
}
return true;