diff options
41 files changed, 392 insertions, 219 deletions
diff --git a/build2/algorithm b/build2/algorithm index 5cd31fe..742b2e9 100644 --- a/build2/algorithm +++ b/build2/algorithm @@ -45,7 +45,7 @@ namespace build2 const dir_path& out, const string& name, const optional<string>& ext, - scope*, + const scope*, const optional<string>& proj = nullopt); // As above but specify the target type as template argument. @@ -56,14 +56,14 @@ namespace build2 const dir_path& out, const string& name, const optional<string>& ext, - scope*); + const scope*); // Search for a target identified by the name. The semantics is "as if" we // first created a prerequisite based on this name in exactly the same way // as the parser would and then searched based on this prerequisite. // target& - search (name, scope&); + search (name, const scope&); // As above but only search for an already existing target. Unlike the // above version, this one can be called during the execute phase. @@ -72,7 +72,9 @@ namespace build2 // unknown target types. // target* - search_existing (const name&, scope&, const dir_path& out = dir_path ()); + search_existing (const name&, + const scope&, + const dir_path& out = dir_path ()); // Match and apply a rule to the action/target with ambiguity detection. // Increment the target's dependents count, which means that you should call @@ -105,8 +107,9 @@ namespace build2 match_delegate (slock&, action, target&, const rule&); // The standard prerequisite search and match implementations. They call - // search_and_match_*() versions below passing non-empty directory for - // the clean operation. + // search() and then match() for each prerequisite in a loop omitting out of + // project prerequisites for the clean operation. If this target is a member + // of a group, then they first do this to the group's prerequisites. // void search_and_match_prerequisites (slock&, action, target&); @@ -117,20 +120,14 @@ namespace build2 void search_and_match_prerequisite_members (slock&, action, target&); - // The actual prerequisite search and match implementations. They call - // search() and then match() for each prerequisite in a loop. If this - // target is a member of a group, then they first do this to the group's - // prerequisites. - // - // If the directory argument is not empty, then they ignore (do not - // match) prerequisites that are not in the same or its subdirectory. + // As above but omit prerequisites that are not in the specified scope. // void - search_and_match_prerequisites (slock&, action, target&, const dir_path&); + search_and_match_prerequisites (slock&, action, target&, const scope&); void search_and_match_prerequisite_members ( - slock&, action, target&, const dir_path&); + slock&, action, target&, const scope&); // Unless already available, match, and, if necessary, execute the group // in order to obtain its members list. Note that even after that the diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx index 1e7a1b8..e8e7777 100644 --- a/build2/algorithm.cxx +++ b/build2/algorithm.cxx @@ -37,7 +37,7 @@ namespace build2 } target& - search (name n, scope& s) + search (name n, const scope& s) { assert (phase == run_phase::search_match); @@ -57,7 +57,7 @@ namespace build2 } target* - search_existing (const name& cn, scope& s, const dir_path& out) + search_existing (const name& cn, const scope& s, const dir_path& out) { assert (phase == run_phase::search_match || phase == run_phase::execute); @@ -116,7 +116,7 @@ namespace build2 // action ra (a.meta_operation (), io, o != oo ? 0 : oo); - scope& bs (t.base_scope ()); + const scope& bs (t.base_scope ()); for (auto tt (&t.type ()); tt != nullptr; tt = tt->base) { @@ -310,7 +310,10 @@ namespace build2 } void - search_and_match_prerequisites (slock& ml, action a, target& t, scope* s) + search_and_match_prerequisites (slock& ml, + action a, + target& t, + const scope* s) { for (prerequisite& p: group_prerequisites (t)) { @@ -325,8 +328,10 @@ namespace build2 } void - search_and_match_prerequisite_members ( - slock& ml, action a, target& t, scope* s) + search_and_match_prerequisite_members (slock& ml, + action a, + target& t, + const scope* s) { for (prerequisite_member p: group_prerequisite_members (ml, a, t)) { @@ -345,8 +350,8 @@ namespace build2 { tracer trace ("inject_fsdir"); - scope& bs (t.base_scope ()); - scope* rs (bs.root_scope ()); + const scope& bs (t.base_scope ()); + const scope* rs (bs.root_scope ()); // Handle the outside of any project case. Note that we also used to bail // our of this is the root of the project. But that proved not to be such diff --git a/build2/algorithm.ixx b/build2/algorithm.ixx index ec06ddf..365a5c4 100644 --- a/build2/algorithm.ixx +++ b/build2/algorithm.ixx @@ -33,7 +33,7 @@ namespace build2 const dir_path& out, const string& name, const optional<string>& ext, - scope* scope, + const scope* scope, const optional<string>& proj) { return search ( @@ -46,7 +46,7 @@ namespace build2 const dir_path& out, const string& name, const optional<string>& ext, - scope* scope) + const scope* scope) { return static_cast<T&> ( search (T::static_type, dir, out, name, ext, scope)); @@ -118,10 +118,10 @@ namespace build2 } void - search_and_match_prerequisites (slock&, action, target&, scope*); + search_and_match_prerequisites (slock&, action, target&, const scope*); void - search_and_match_prerequisite_members (slock&, action, target&, scope*); + search_and_match_prerequisite_members (slock&, action, target&, const scope*); inline void search_and_match_prerequisites (slock& ml, action a, target& t) @@ -147,14 +147,19 @@ namespace build2 } inline void - search_and_match_prerequisites (slock& ml, action a, target& t, scope& s) + search_and_match_prerequisites (slock& ml, + action a, + target& t, + const scope& s) { search_and_match_prerequisites (ml, a, t, &s); } inline void - search_and_match_prerequisite_members ( - slock& ml, action a, target& t, scope& s) + search_and_match_prerequisite_members (slock& ml, + action a, + target& t, + const scope& s) { search_and_match_prerequisite_members (ml, a, t, &s); } diff --git a/build2/b.cxx b/build2/b.cxx index 341554f..0ad404a 100644 --- a/build2/b.cxx +++ b/build2/b.cxx @@ -52,11 +52,21 @@ using namespace std; #include <build2/install/init> #include <build2/pkgconfig/init> -using namespace build2; +namespace build2 +{ + int + main (int argc, char* argv[]); +} int main (int argc, char* argv[]) { + return build2::main (argc, argv); +} + +int build2:: +main (int argc, char* argv[]) +{ // This is a little hack to make out baseutils for Windows work when called // with absolute path. In a nutshell, MSYS2's exec*p() doesn't search in the // parent's executable directory, only in PATH. And since we are running @@ -563,7 +573,7 @@ main (int argc, char* argv[]) // be of use to the bootstrap files (other than src-root.build, // which, BTW, doesn't need to exist if src_root == out_root). // - scope& rs (create_root (out_root, src_root)); + scope& rs (create_root (*scope::global_, out_root, src_root)); bool bootstrapped (build2::bootstrapped (rs)); @@ -980,7 +990,7 @@ main (int argc, char* argv[]) // building before we know how to for all the targets in this // operation batch. // - scope& bs (scopes.find (ts.out_base)); + const scope& bs (scopes.find (ts.out_base)); // Find the target type and extract the extension. // diff --git a/build2/buildfile b/build2/buildfile index 1ee7063..80d72a2 100644 --- a/build2/buildfile +++ b/build2/buildfile @@ -30,7 +30,7 @@ exe{b}: \ {hxx cxx}{ rule } \ {hxx }{ rule-map } \ {hxx txx cxx}{ scheduler } \ - {hxx cxx}{ scope } \ + {hxx ixx cxx}{ scope } \ {hxx cxx}{ search } \ {hxx cxx}{ spec } \ {hxx ixx txx cxx}{ target } \ diff --git a/build2/cc/common b/build2/cc/common index c11e733..06df4c3 100644 --- a/build2/cc/common +++ b/build2/cc/common @@ -184,7 +184,7 @@ namespace build2 // public: void - process_libraries (scope&, + process_libraries (const scope&, lorder, const dir_paths&, file&, @@ -210,7 +210,7 @@ namespace build2 private: file& - resolve_library (scope&, + resolve_library (const scope&, name, lorder, const dir_paths&, @@ -222,10 +222,10 @@ namespace build2 const prerequisite_key&) const; dir_paths - extract_library_dirs (scope&) const; + extract_library_dirs (const scope&) const; bool - pkgconfig_extract (scope&, + pkgconfig_extract (const scope&, bin::lib&, bin::liba*, bin::libs*, diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx index aa0a45b..e7b26a1 100644 --- a/build2/cc/common.cxx +++ b/build2/cc/common.cxx @@ -46,7 +46,7 @@ namespace build2 // void common:: process_libraries ( - scope& top_bs, + const scope& top_bs, lorder top_lo, const dir_paths& top_sysd, file& l, @@ -183,7 +183,7 @@ namespace build2 proc_lib (&l, p, s); } - scope& bs (t == nullptr || cc ? top_bs : l.base_scope ()); + const scope& bs (t == nullptr || cc ? top_bs : l.base_scope ()); optional<lorder> lo; // Calculate lazily. const dir_paths* sysd (nullptr); // Resolve lazily. @@ -386,7 +386,7 @@ namespace build2 // that's the only way to guarantee it will be up-to-date. // file& common:: - resolve_library (scope& s, + resolve_library (const scope& s, name n, lorder lo, const dir_paths& sysd, @@ -657,7 +657,7 @@ namespace build2 // if (cid == "msvc") { - scope& rs (*p.scope->root_scope ()); + const scope& rs (*p.scope->root_scope ()); const process_path& ld (cast<process_path> (rs["bin.ld.path"])); if (s == nullptr && !sn.empty ()) @@ -821,7 +821,7 @@ namespace build2 } dir_paths common:: - extract_library_dirs (scope& bs) const + extract_library_dirs (const scope& bs) const { dir_paths r; diff --git a/build2/cc/compile b/build2/cc/compile index 11b3919..b6fc7d6 100644 --- a/build2/cc/compile +++ b/build2/cc/compile @@ -40,10 +40,10 @@ namespace build2 private: void - append_lib_options (scope&, cstrings&, target&, lorder) const; + append_lib_options (const scope&, cstrings&, target&, lorder) const; void - hash_lib_options (scope&, sha256&, target&, lorder) const; + hash_lib_options (const scope&, sha256&, target&, lorder) const; // Mapping of include prefixes (e.g., foo in <foo/bar>) for auto- // generated headers to directories where they will be generated. @@ -61,15 +61,15 @@ namespace build2 append_prefixes (prefix_map&, target&, const variable&) const; void - append_lib_prefixes (scope&, prefix_map&, target&, lorder) const; + append_lib_prefixes (const scope&, prefix_map&, target&, lorder) const; prefix_map - build_prefix_map (scope&, target&, lorder) const; + build_prefix_map (const scope&, target&, lorder) const; // Reverse-lookup target type from extension. // const target_type* - map_extension (scope&, const string&, const string&) const; + map_extension (const scope&, const string&, const string&) const; // Header dependency injection. // diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx index bc35272..2176b82 100644 --- a/build2/cc/compile.cxx +++ b/build2/cc/compile.cxx @@ -76,7 +76,10 @@ namespace build2 // (first one is cc.export.*) recursively, prerequisite libraries first. // void compile:: - append_lib_options (scope& bs, cstrings& args, target& t, lorder lo) const + append_lib_options (const scope& bs, + cstrings& args, + target& t, + lorder lo) const { auto opt = [&args, this] (file& l, const string& t, bool com, bool exp) { @@ -117,7 +120,7 @@ namespace build2 } void compile:: - hash_lib_options (scope& bs, sha256& cs, target& t, lorder lo) const + hash_lib_options (const scope& bs, sha256& cs, target& t, lorder lo) const { auto opt = [&cs, this] (file& l, const string& t, bool com, bool exp) { @@ -156,7 +159,10 @@ namespace build2 // recursively, prerequisite libraries first. // void compile:: - append_lib_prefixes (scope& bs, prefix_map& m, target& t, lorder lo) const + append_lib_prefixes (const scope& bs, + prefix_map& m, + target& t, + lorder lo) const { auto opt = [&m, this] (file& l, const string& t, bool com, bool exp) { @@ -199,8 +205,8 @@ namespace build2 file& t (static_cast<file&> (xt)); const match_data& md (t.data<match_data> ()); - scope& bs (t.base_scope ()); - scope& rs (*bs.root_scope ()); + const scope& bs (t.base_scope ()); + const scope& rs (*bs.root_scope ()); otype ct (compile_type (t)); // Derive file name from target name. @@ -405,7 +411,7 @@ namespace build2 // Reverse-lookup target type from extension. // const target_type* compile:: - map_extension (scope& s, const string& n, const string& e) const + map_extension (const scope& s, const string& n, const string& e) const { // We will just have to try all of the possible ones, in the "most // likely to match" order. @@ -442,7 +448,7 @@ namespace build2 // "imported as installed" library), then it can't possibly // generate any headers for us. // - scope* rs (t.base_scope ().root_scope ()); + const scope* rs (t.base_scope ().root_scope ()); if (rs == nullptr) return; @@ -526,7 +532,9 @@ namespace build2 } auto compile:: - build_prefix_map (scope& bs, target& t, lorder lo) const -> prefix_map + build_prefix_map (const scope& bs, + target& t, + lorder lo) const -> prefix_map { prefix_map m; @@ -737,8 +745,8 @@ namespace build2 info << "while extracting header dependencies from " << src; })); - scope& bs (t.base_scope ()); - scope& rs (*bs.root_scope ()); + const scope& bs (t.base_scope ()); + const scope& rs (*bs.root_scope ()); // Initialize lazily, only if required. // @@ -937,8 +945,8 @@ namespace build2 // dir_path out; - scope& bs (scopes.find (d)); - if (scope* rs = bs.root_scope ()) + const scope& bs (scopes.find (d)); + if (const scope* rs = bs.root_scope ()) { tt = map_extension (bs, n, e); @@ -1403,8 +1411,8 @@ namespace build2 return p.second; } - scope& bs (t.base_scope ()); - scope& rs (*bs.root_scope ()); + const scope& bs (t.base_scope ()); + const scope& rs (*bs.root_scope ()); otype ct (compile_type (t)); lorder lo (link_order (bs, ct)); diff --git a/build2/cc/link b/build2/cc/link index 5f28204..d1b0e7a 100644 --- a/build2/cc/link +++ b/build2/cc/link @@ -71,13 +71,13 @@ namespace build2 // Library handling. // void - append_libraries (strings&, file&, bool, scope&, lorder) const; + append_libraries (strings&, file&, bool, const scope&, lorder) const; void - hash_libraries (sha256&, file&, bool, scope&, lorder) const; + hash_libraries (sha256&, file&, bool, const scope&, lorder) const; void - rpath_libraries (strings&, target&, scope&, lorder, bool) const; + rpath_libraries (strings&, target&, const scope&, lorder, bool) const; // Windows rpath emulation (windows-rpath.cxx). // @@ -93,13 +93,13 @@ namespace build2 using windows_dlls = std::set<windows_dll>; timestamp - windows_rpath_timestamp (file&, scope&, lorder) const; + windows_rpath_timestamp (file&, const scope&, lorder) const; windows_dlls - windows_rpath_dlls (file&, scope&, lorder) const; + windows_rpath_dlls (file&, const scope&, lorder) const; void - windows_rpath_assembly (file&, scope&, lorder, + windows_rpath_assembly (file&, const scope&, lorder, const string&, timestamp, bool) const; diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx index 6de294a..d85faed 100644 --- a/build2/cc/link.cxx +++ b/build2/cc/link.cxx @@ -322,8 +322,8 @@ namespace build2 file& t (static_cast<file&> (xt)); - scope& bs (t.base_scope ()); - scope& rs (*bs.root_scope ()); + const scope& bs (t.base_scope ()); + const scope& rs (*bs.root_scope ()); otype lt (link_type (t)); lorder lo (link_order (bs, lt)); @@ -657,7 +657,7 @@ namespace build2 void link:: append_libraries (strings& args, file& l, bool la, - scope& bs, lorder lo) const + const scope& bs, lorder lo) const { // Note: lack of the "small function object" optimization will really // kill us here since we are called in a loop. @@ -704,7 +704,11 @@ namespace build2 } void link:: - hash_libraries (sha256& cs, file& l, bool la, scope& bs, lorder lo) const + hash_libraries (sha256& cs, + file& l, + bool la, + const scope& bs, + lorder lo) const { bool win (tclass == "windows"); @@ -747,7 +751,9 @@ namespace build2 void link:: rpath_libraries (strings& args, - target& t, scope& bs, lorder lo, + target& t, + const scope& bs, + lorder lo, bool for_install) const { // Use -rpath-link on targets that support it (Linux, *BSD). Note @@ -887,8 +893,8 @@ namespace build2 file& t (static_cast<file&> (xt)); - scope& bs (t.base_scope ()); - scope& rs (*bs.root_scope ()); + const scope& bs (t.base_scope ()); + const scope& rs (*bs.root_scope ()); otype lt (link_type (t)); lorder lo (link_order (bs, lt)); diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx index 6c8159f..d32cd61 100644 --- a/build2/cc/pkgconfig.cxx +++ b/build2/cc/pkgconfig.cxx @@ -37,7 +37,7 @@ namespace build2 // search_library() POV. // bool common:: - pkgconfig_extract (scope& s, + pkgconfig_extract (const scope& s, lib& lt, liba* at, libs* st, diff --git a/build2/cc/utility b/build2/cc/utility index b481202..050b645 100644 --- a/build2/cc/utility +++ b/build2/cc/utility @@ -37,7 +37,7 @@ namespace build2 // same directory have to have the same link order. // lorder - link_order (scope& base, otype); + link_order (const scope& base, otype); // Given the link order return the library member (liba or libs) to link. // diff --git a/build2/cc/utility.cxx b/build2/cc/utility.cxx index f8a0afc..5c5d1fe 100644 --- a/build2/cc/utility.cxx +++ b/build2/cc/utility.cxx @@ -18,7 +18,7 @@ namespace build2 using namespace bin; lorder - link_order (scope& bs, otype ot) + link_order (const scope& bs, otype ot) { // Initialize to suppress 'may be used uninitialized' warning produced // by MinGW GCC 5.4.0. diff --git a/build2/cc/windows-manifest.cxx b/build2/cc/windows-manifest.cxx index 44d8f7b..b0b0feb 100644 --- a/build2/cc/windows-manifest.cxx +++ b/build2/cc/windows-manifest.cxx @@ -43,7 +43,7 @@ namespace build2 { tracer trace (x, "windows_manifest"); - scope& rs (t.root_scope ()); + const scope& rs (t.root_scope ()); const char* pa (windows_manifest_arch (cast<string> (rs[x_target_cpu]))); diff --git a/build2/cc/windows-rpath.cxx b/build2/cc/windows-rpath.cxx index 35d83cc..00911d4 100644 --- a/build2/cc/windows-rpath.cxx +++ b/build2/cc/windows-rpath.cxx @@ -46,7 +46,7 @@ namespace build2 // adding to the assembly or timestamp_nonexistent if there aren't any. // timestamp link:: - windows_rpath_timestamp (file& t, scope& bs, lorder lo) const + windows_rpath_timestamp (file& t, const scope& bs, lorder lo) const { timestamp r (timestamp_nonexistent); @@ -116,7 +116,9 @@ namespace build2 // duplicates). // auto link:: - windows_rpath_dlls (file& t, scope& bs, lorder lo) const -> windows_dlls + windows_rpath_dlls (file& t, + const scope& bs, + lorder lo) const -> windows_dlls { windows_dlls r; @@ -204,7 +206,7 @@ namespace build2 // void link:: windows_rpath_assembly (file& t, - scope& bs, + const scope& bs, lorder lo, const string& tcpu, timestamp ts, @@ -276,7 +278,7 @@ namespace build2 << " processorArchitecture='" << pa << "'\n" << " version='0.0.0.0'/>\n"; - scope& as (*t.root_scope ().weak_scope ()); // Amalgamation scope. + const scope& as (*t.root_scope ().weak_scope ()); // Amalgamation. auto link = [&as, &ad] (const path& f, const path& l) { diff --git a/build2/cli/rule.cxx b/build2/cli/rule.cxx index 8cef1f5..773d00c 100644 --- a/build2/cli/rule.cxx +++ b/build2/cli/rule.cxx @@ -250,7 +250,7 @@ namespace build2 path relo (relative (t.dir)); path rels (relative (s->path ())); - scope& rs (t.root_scope ()); + const scope& rs (t.root_scope ()); const process_path& cli (cast<process_path> (rs["cli.path"])); diff --git a/build2/config/init.cxx b/build2/config/init.cxx index a73c394..682d817 100644 --- a/build2/config/init.cxx +++ b/build2/config/init.cxx @@ -75,7 +75,7 @@ namespace build2 { // Assume missing version is 0. // - auto p (extract_variable (f, c_v)); + auto p (extract_variable (rs, f, c_v)); uint64_t v (p.second ? cast<uint64_t> (p.first) : 0); if (v != module::version) @@ -127,9 +127,10 @@ namespace build2 // { // We need this rule for out-of-any-project dependencies (e.g., - // libraries imported from /usr/lib). + // libraries imported from /usr/lib). Registring it on the global + // scope smells a bit but seems harmless. // - global_scope->rules.insert<file> ( + rs.global ().rules.insert<file> ( configure_id, 0, "config.file", file_rule::instance); auto& r (rs.rules); diff --git a/build2/config/operation.cxx b/build2/config/operation.cxx index 63e6d9b..75f5abc 100644 --- a/build2/config/operation.cxx +++ b/build2/config/operation.cxx @@ -61,8 +61,10 @@ namespace build2 } } + using project_set = set<const scope*>; // Use pointers to get comparison. + static void - save_config (scope& root, const set<scope*>& projects) + save_config (const scope& root, const project_set& projects) { const dir_path& out_root (root.out_path ()); path f (out_root / config_file); @@ -137,7 +139,7 @@ namespace build2 // root. // bool found (false); - scope* r (&root); + const scope* r (&root); while ((r = r->parent_scope ()->root_scope ()) != nullptr) { if (l.belongs (*r)) @@ -282,7 +284,7 @@ namespace build2 } static void - configure_project (action a, scope& root, set<scope*>& projects) + configure_project (action a, const scope& root, project_set& projects) { tracer trace ("configure_project"); @@ -331,7 +333,7 @@ namespace build2 { const dir_path& pd (p.second); dir_path out_nroot (out_root / pd); - scope& nroot (scopes.find (out_nroot)); + const scope& nroot (scopes.find (out_nroot)); // @@ Strictly speaking we need to check whether the config // module was loaded for this subproject. @@ -358,7 +360,7 @@ namespace build2 // callbacks here since the meta operation is configure and we // know what we are doing. // - set<scope*> projects; + project_set projects; // Note that we cannot do this in parallel. We cannot parallelize the // outer loop because we should match for a single action at a time. @@ -371,7 +373,7 @@ namespace build2 for (void* v: ts) { target& t (*static_cast<target*> (v)); - scope* rs (t.base_scope ().root_scope ()); + const scope* rs (t.base_scope ().root_scope ()); if (rs == nullptr) fail << "out of project target " << t; @@ -423,7 +425,45 @@ namespace build2 } static void - disfigure_load (scope&, + load_project (scope& root) + { + if (auto l = root.vars[var_subprojects]) + { + const dir_path& out_root (root.out_path ()); + const dir_path& src_root (root.src_path ()); + + for (auto p: cast<subprojects> (l)) + { + const dir_path& pd (p.second); + + // Create and bootstrap subproject's root scope. + // + dir_path out_nroot (out_root / pd); + + // The same logic for src_root as in create_bootstrap_inner(). + // + scope& nroot (create_root (root, out_nroot, dir_path ())); + + if (!bootstrapped (nroot)) + { + bootstrap_out (nroot); + + value& val (nroot.assign (var_src_root)); + + if (!val) + val = is_src_root (out_nroot) ? out_nroot : (src_root / pd); + + setup_root (nroot); + bootstrap_src (nroot); + } + + load_project (nroot); + } + } + } + + static void + disfigure_load (scope& root, const path& bf, const dir_path&, const dir_path&, @@ -431,17 +471,23 @@ namespace build2 { tracer trace ("disfigure_load"); l6 ([&]{trace << "skipping " << bf;}); + + // Since we don't load buildfiles during disfigure but still want to + // disfigure all the subprojects (see disfigure_project() below), we + // bootstrap all known subprojects. + // + load_project (root); } static void - disfigure_search (scope& root, + disfigure_search (const scope& root, const target_key&, const location&, action_targets& ts) { tracer trace ("disfigure_search"); l6 ([&]{trace << "collecting " << root.out_path ();}); - ts.push_back (&root); + ts.push_back (const_cast<scope*> (&root)); //@@ MT TMP action_targets } static void @@ -450,7 +496,7 @@ namespace build2 } static bool - disfigure_project (action a, scope& root, set<scope*>& projects) + disfigure_project (action a, const scope& root, project_set& projects) { tracer trace ("disfigure_project"); @@ -473,27 +519,9 @@ namespace build2 for (auto p: cast<subprojects> (l)) { const dir_path& pd (p.second); - - // Create and bootstrap subproject's root scope. - // dir_path out_nroot (out_root / pd); - - // The same logic for src_root as in create_bootstrap_inner(). - // - scope& nroot (create_root (out_nroot, dir_path ())); - - if (!bootstrapped (nroot)) - { - bootstrap_out (nroot); - - value& val (nroot.assign (var_src_root)); - - if (!val) - val = is_src_root (out_nroot) ? out_nroot : (src_root / pd); - - setup_root (nroot); - bootstrap_src (nroot); - } + const scope& nroot (scopes.find (out_nroot)); + assert (nroot.out_path () == out_nroot); // See disfigure_load(). m = disfigure_project (a, nroot, projects) || m; @@ -565,13 +593,14 @@ namespace build2 { tracer trace ("disfigure_execute"); - set<scope*> projects; + project_set projects; - // Note: doing everything in the load phase. + // Note: doing everything in the load phase (disfigure_project () does + // modify the model). // for (void* v: ts) { - scope& root (*static_cast<scope*> (v)); + const scope& root (*static_cast<const scope*> (v)); if (!disfigure_project (a, root, projects)) { diff --git a/build2/context b/build2/context index c443a7a..d6f79af 100644 --- a/build2/context +++ b/build2/context @@ -268,14 +268,14 @@ namespace build2 // passed directory should be a sub-directory of out/src_root. // dir_path - src_out (const dir_path& out, scope& root); + src_out (const dir_path& out, const scope& root); dir_path src_out (const dir_path& out, const dir_path& out_root, const dir_path& src_root); dir_path - out_src (const dir_path& src, scope& root); + out_src (const dir_path& src, const scope& root); dir_path out_src (const dir_path& src, diff --git a/build2/context.cxx b/build2/context.cxx index 466db0d..e15294a 100644 --- a/build2/context.cxx +++ b/build2/context.cxx @@ -71,13 +71,14 @@ namespace build2 l6 ([&]{trace << "resetting build state";}); auto& vp (variable_pool::instance); + auto& sm (scope_map::instance); variable_overrides vos; var_override_cache.clear (); targets.clear (); - scopes.clear (); + sm.clear (); vp.clear (); // Reset meta/operation tables. Note that the order should match the id @@ -101,13 +102,16 @@ namespace build2 // Create global scope. Note that the empty path is a prefix for any other // path. See the comment in <butl/prefix-map> for details. // + auto make_global_scope = [&sm] () -> scope& { - auto i (scopes.insert (dir_path (), false)); - global_scope = &i->second; - global_scope->out_path_ = &i->first; - } + auto i (sm.insert (dir_path (), false)); + scope& r (i->second); + r.out_path_ = &i->first; + global_scope = scope::global_ = &r; + return r; + }; - scope& gs (*global_scope); + scope& gs (make_global_scope ()); // Parse and enter the command line variables. We do it before entering // any other variables so that all the variables that are overriden are @@ -215,7 +219,7 @@ namespace build2 // if (c == '!' || !dir.empty ()) { - scope& s (c == '!' ? gs : scopes.insert (dir, false)->second); + scope& s (c == '!' ? gs : sm.insert (dir, false)->second); auto p (s.vars.insert (*o)); if (!p.second) @@ -377,14 +381,14 @@ namespace build2 } dir_path - src_out (const dir_path& out, scope& r) + src_out (const dir_path& out, const scope& r) { assert (r.root ()); return src_out (out, r.out_path (), r.src_path ()); } dir_path - out_src (const dir_path& src, scope& r) + out_src (const dir_path& src, const scope& r) { assert (r.root ()); return out_src (src, r.out_path (), r.src_path ()); diff --git a/build2/dist/operation.cxx b/build2/dist/operation.cxx index c7fe83b..1f9fbbd 100644 --- a/build2/dist/operation.cxx +++ b/build2/dist/operation.cxx @@ -62,7 +62,7 @@ namespace build2 // For now we assume all the targets are from the same project. // target& t (*static_cast<target*> (ts[0])); - scope* rs (t.base_scope ().root_scope ()); + const scope* rs (t.base_scope ().root_scope ()); if (rs == nullptr) fail << "out of project target " << t; @@ -162,7 +162,7 @@ namespace build2 // ignored on the next step if the user explicitly marked them // nodist. // - auto add_adhoc = [&trace] (scope& rs, const path& f) + auto add_adhoc = [&trace] (const scope& rs, const path& f) { path p (rs.src_path () / f); if (exists (p)) @@ -194,7 +194,7 @@ namespace build2 { const dir_path& pd (p.second); dir_path out_nroot (out_root / pd); - scope& nrs (scopes.find (out_nroot)); + const scope& nrs (scopes.find (out_nroot)); if (nrs.out_path () != out_nroot) // This subproject not loaded. continue; diff --git a/build2/file b/build2/file index adfd884..696c5d7 100644 --- a/build2/file +++ b/build2/file @@ -70,10 +70,11 @@ namespace build2 source_once (scope& root, scope& base, const path&, scope& once); // Create project's root scope. Only set the src_root variable if the - // passed src_root value is not empty. + // passed src_root value is not empty. The scope argument is only used + // as proof of lock. // scope& - create_root (const dir_path& out_root, const dir_path& src_root); + create_root (scope&, const dir_path& out_root, const dir_path& src_root); // Setup root scope. Note that it assume the src_root variable // has already been set. @@ -140,10 +141,11 @@ namespace build2 // Extract the specified variable value from a buildfile. It is expected to // be the first non-comment line and not to rely on any variable expansion // other than those from the global scope or any variable overrides. Return - // an indication of whether the variable was found. + // an indication of whether the variable was found. The scope is only used + // as proof of lock (though we don't modify anything). // pair<value, bool> - extract_variable (const path&, const variable&); + extract_variable (scope&, const path&, const variable&); // Import has two phases: the first is triggered by the import // directive in the buildfile. It will try to find and load the diff --git a/build2/file.cxx b/build2/file.cxx index 755ff0f..3da1d35 100644 --- a/build2/file.cxx +++ b/build2/file.cxx @@ -133,12 +133,12 @@ namespace build2 } scope& - create_root (const dir_path& out_root, const dir_path& src_root) + create_root (scope& l, const dir_path& out_root, const dir_path& src_root) { - auto i (scopes.insert (out_root, true)); + auto i (scopes.rw (l).insert (out_root, true)); scope& rs (i->second); - // Set out_path. src_path is set in setup_root() below. + // Set out_path. Note that src_path is set in setup_root() below. // if (rs.out_path_ != &i->first) { @@ -260,7 +260,7 @@ namespace build2 // First, enter the scope into the map and see if it is in any project. If // it is not, then there is nothing else to do. // - auto i (scopes.insert (p, false)); + auto i (scopes.rw (root).insert (p, false)); scope& base (i->second); scope* rs (base.root_scope ()); @@ -317,7 +317,7 @@ namespace build2 // other than those from the global scope or any variable overrides. // pair<value, bool> - extract_variable (const path& bf, const variable& var) + extract_variable (scope& s, const path& bf, const variable& var) { try { @@ -336,7 +336,7 @@ namespace build2 } parser p; - temp_scope tmp (*global_scope); + temp_scope tmp (s.global ()); p.parse_variable (lex, tmp, var, tt); value* v (tmp.vars.find (var)); @@ -357,7 +357,8 @@ namespace build2 // Extract the project name from bootstrap.build. // static string - find_project_name (const dir_path& out_root, + find_project_name (scope& s, + const dir_path& out_root, const dir_path& fallback_src_root, bool* src_hint = nullptr) { @@ -380,7 +381,7 @@ namespace build2 src_root = &fallback_src_root; else { - auto p (extract_variable (f, *var_src_root)); + auto p (extract_variable (s, f, *var_src_root)); if (!p.second) fail << "variable 'src_root' expected as first line in " << f; @@ -395,7 +396,7 @@ namespace build2 string name; { path f (*src_root / bootstrap_file); - auto p (extract_variable (f, *var_project)); + auto p (extract_variable (s, f, *var_project)); if (!p.second) fail << "variable '" << var_project->name << "' expected " @@ -414,7 +415,8 @@ namespace build2 // Otherwise, scan the subdirectory recursively. // static void - find_subprojects (subprojects& sps, + find_subprojects (scope& s, + subprojects& sps, const dir_path& d, const dir_path& root, bool out) @@ -460,7 +462,7 @@ namespace build2 // Load its name. Note that here we don't use fallback src_root // since this function is used to scan both out_root and src_root. // - string name (find_project_name (sd, dir_path (), &src)); + string name (find_project_name (s, sd, dir_path (), &src)); // If the name is empty, then is is an unnamed project. While the // 'project' variable stays empty, here we come up with a surrogate @@ -619,13 +621,13 @@ namespace build2 if (exists (out_root)) { l5 ([&]{trace << "looking for subprojects in " << out_root;}); - find_subprojects (sps, out_root, out_root, true); + find_subprojects (root, sps, out_root, out_root, true); } if (out_root != src_root) { l5 ([&]{trace << "looking for subprojects in " << src_root;}); - find_subprojects (sps, src_root, src_root, false); + find_subprojects (root, sps, src_root, src_root, false); } if (!sps.empty ()) // Keep it NULL if no subprojects. @@ -695,7 +697,7 @@ namespace build2 // was specified by the user so it is most likely in our // src. // - n = find_project_name (out_root / d, src_root / d); + n = find_project_name (root, out_root / d, src_root / d); // See find_subprojects() for details on unnamed projects. // @@ -750,7 +752,7 @@ namespace build2 // explicitly configured by the user. After that, #2 followed // by #1 seems reasonable. // - scope& rs (create_root (out_root, dir_path ())); + scope& rs (create_root (root, out_root, dir_path ())); if (!bootstrapped (rs)) { @@ -796,7 +798,7 @@ namespace build2 // The same logic to src_root as in create_bootstrap_outer(). // - scope& rs (create_root (out_root, dir_path ())); + scope& rs (create_root (root, out_root, dir_path ())); if (!bootstrapped (rs)) { @@ -1037,7 +1039,7 @@ namespace build2 for (;;) { src_root = is_src_root (out_root) ? out_root : dir_path (); - root = &create_root (out_root, src_root); + root = &create_root (iroot, out_root, src_root); if (!bootstrapped (*root)) { diff --git a/build2/install/rule.cxx b/build2/install/rule.cxx index 13c93a7..8c21dc1 100644 --- a/build2/install/rule.cxx +++ b/build2/install/rule.cxx @@ -278,7 +278,10 @@ namespace build2 // empty add it to install_dirs. Return the new last element. // static install_dir& - resolve_subdir (install_dirs& rs, target& t, scope& s, const lookup& l) + resolve_subdir (install_dirs& rs, + target& t, + const scope& s, + const lookup& l) { // Find the scope from which this value came and use as a base // to calculate the subdirectory. @@ -338,7 +341,7 @@ namespace build2 } install_dir* r (&rs.back ()); - scope& s (t.base_scope ()); + const scope& s (t.base_scope ()); // Override components in install_dir if we have our own. // diff --git a/build2/operation b/build2/operation index 22bb8a7..4af306d 100644 --- a/build2/operation +++ b/build2/operation @@ -173,7 +173,7 @@ namespace build2 // Normally a list of resolved and matched targets to execute. But // can be something else, depending on the meta-operation. // - typedef vector<void*> action_targets; + typedef vector<void*> action_targets; //@@ MT TMP: make const void* struct meta_operation_info { @@ -204,7 +204,7 @@ namespace build2 const dir_path& src_base, const location&); - void (*search) (scope& root, + void (*search) (const scope& root, const target_key&, const location&, action_targets&); @@ -239,7 +239,7 @@ namespace build2 // that does just that and adds a pointer to the target to the list. // void - search (scope&, const target_key&, const location&, action_targets&); + search (const scope&, const target_key&, const location&, action_targets&); void match (action, action_targets&); diff --git a/build2/operation.cxx b/build2/operation.cxx index 6e8511d..4e65783 100644 --- a/build2/operation.cxx +++ b/build2/operation.cxx @@ -58,7 +58,7 @@ namespace build2 // Create the base scope. Note that its existence doesn't mean it was // already setup as a base scope; it can be the same as root. // - auto i (scopes.insert (out_base, false)); + auto i (scopes.rw (root).insert (out_base, false)); scope& base (setup_base (i, out_base, src_base)); // Load the buildfile unless it has already been loaded. @@ -67,7 +67,7 @@ namespace build2 } void - search (scope&, + search (const scope&, const target_key& tk, const location& l, action_targets& ts) diff --git a/build2/parser.cxx b/build2/parser.cxx index 7f6b940..c48159a 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -3280,7 +3280,7 @@ namespace build2 lexer l (is, *path_, "\'\"\\$(", &paren_processor); lexer_ = &l; target_ = nullptr; - scope_ = root_ = global_scope; + scope_ = root_ = scope::global_; // Turn on the value mode/pairs recognition with '@' as the pair separator // (e.g., src_root/@out_root/exe{foo bar}). diff --git a/build2/prerequisite b/build2/prerequisite index abfb2c1..a6d3632 100644 --- a/build2/prerequisite +++ b/build2/prerequisite @@ -33,7 +33,7 @@ namespace build2 const optional<string>& proj; target_key tk; // The .dir and .out members can be relative. - scope_type* scope; // Can be NULL if tk.dir is absolute. + const scope_type* scope; // Can be NULL if tk.dir is absolute. static const optional<string> nullproj; @@ -69,7 +69,7 @@ namespace build2 const dir_path out; // Empty, normalized absolute, or relative. const string name; const optional<string> ext; // Absent if unspecified. - scope_type& scope; + const scope_type& scope; target_type* target; // NULL if not yet resolved. Note that this // should always be the "primary target", not @@ -82,7 +82,7 @@ namespace build2 dir_path o, string n, optional<string> e, - scope_type& s) + const scope_type& s) : proj (move (p)), type (t), dir (move (d)), diff --git a/build2/rule-map b/build2/rule-map index b7397a0..d7748b6 100644 --- a/build2/rule-map +++ b/build2/rule-map @@ -26,6 +26,9 @@ namespace build2 // This is an "indexed map" with operation_id being the index. Entry // with id 0 is a wildcard. // + // Note that while we may resize some vectors during non-serial load, this + // is MT-safe since we never cache any references to their elements. + // class operation_rule_map { public: @@ -63,6 +66,8 @@ namespace build2 // allocation for the common cases since most rules will be registered // for perform, at least on non-root scopes. // + // @@ Redo using small_vector? + // class rule_map { public: diff --git a/build2/scope b/build2/scope index 8c5ec00..64aaf24 100644 --- a/build2/scope +++ b/build2/scope @@ -39,16 +39,16 @@ namespace build2 bool root () const {return root_ == this;} - scope* - parent_scope () const {return parent_;} + scope* parent_scope () {return parent_;} + const scope* parent_scope () const {return parent_;} // Root scope of this scope or NULL if this scope is not (yet) // in any (known) project. Note that if the scope itself is // root, then this function return this. To get to the outer // root, query the root scope of the parent. // - scope* - root_scope () const {return root_;} + scope* root_scope () {return root_;} + const scope* root_scope () const {return root_;} // Root scope of a strong amalgamation of this scope or NULL if // this scope is not (yet) in any (known) project. If there is @@ -56,27 +56,16 @@ namespace build2 // scope of the project (in other words, in this case a project // is treated as its own strong amalgamation). // - scope* - strong_scope () const - { - return root_ != nullptr - ? root_->strong_ != nullptr ? root_->strong_ : root_ - : nullptr; - } + scope* strong_scope (); + const scope* strong_scope () const; // Root scope of the outermost amalgamation or NULL if this scope is not // (yet) in any (known) project. If there is no amalgamation, then this // function returns the root scope of the project (in other words, in this // case a project is treated as its own amalgamation). // - scope* - weak_scope () const - { - scope* r (root_); - if (r != nullptr) - for (; r->parent_->root_ != nullptr; r = r->parent_->root_) ; - return r; - } + scope* weak_scope (); + const scope* weak_scope () const; // Variables. // @@ -244,7 +233,27 @@ namespace build2 public: loaded_module_map modules; // Only on root scope. + public: + // Proof of lock for RW access. + // + scope& + rw (const ulock&) const {return const_cast<scope&> (*this);} + + // RW access to global scope (RO via global global_scope below). + // + scope& + global () {return *global_;} + + private: + static scope* global_; + + // Entities that can access bypassing the lock proof. + // + friend int main (int, char*[]); + friend variable_overrides reset (const strings&); + private: + friend class parser; friend class scope_map; friend class temp_scope; @@ -302,11 +311,14 @@ namespace build2 // Find the most qualified scope that encompasses this path. // - scope& - find (const dir_path&); + const scope& + find (const dir_path& d) const + { + return const_cast<scope_map*> (this)->find (d); + } - scope& - find (const path& p) + const scope& + find (const path& p) const { // Natural thing to do here would be to call find (p.directory ()). // However, there could be a situation where the passed path is a @@ -315,10 +327,34 @@ namespace build2 // return find (path_cast<dir_path> (p)); } + + // Proof of lock for RW access. + // + public: + scope_map& + rw (ulock&) const {return const_cast<scope_map&> (*this);} + + scope_map& + rw (scope&) const {return const_cast<scope_map&> (*this);} + + private: + static scope_map instance; + + // Entities that can access bypassing the lock proof. + // + friend variable_overrides reset (const strings&); + + scope& + find (const dir_path&); + + public: + static const scope_map& cinstance; // For var_pool initialization. }; - extern scope_map scopes; - extern scope* global_scope; + extern const scope_map& scopes; + extern const scope* global_scope; } +#include <build2/scope.ixx> + #endif // BUILD2_SCOPE diff --git a/build2/scope.cxx b/build2/scope.cxx index 9514817..0c80052 100644 --- a/build2/scope.cxx +++ b/build2/scope.cxx @@ -691,10 +691,15 @@ namespace build2 pr.first->second.get (), pr.second); } + scope* scope::global_; + // scope_map // - scope_map scopes; - scope* global_scope; + scope_map scope_map::instance; + const scope_map& scope_map::cinstance = scope_map::instance; + const scope_map& scopes = scope_map::cinstance; + + const scope* global_scope; auto scope_map:: insert (const dir_path& k, bool root) -> iterator diff --git a/build2/scope.ixx b/build2/scope.ixx new file mode 100644 index 0000000..46eea3d --- /dev/null +++ b/build2/scope.ixx @@ -0,0 +1,42 @@ +// file : build2/scope.ixx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +namespace build2 +{ + // scope + // + inline scope* scope:: + strong_scope () + { + return root_ != nullptr + ? root_->strong_ != nullptr ? root_->strong_ : root_ + : nullptr; + } + + inline const scope* scope:: + strong_scope () const + { + return root_ != nullptr + ? root_->strong_ != nullptr ? root_->strong_ : root_ + : nullptr; + } + + inline scope* scope:: + weak_scope () + { + scope* r (root_); + if (r != nullptr) + for (; r->parent_->root_ != nullptr; r = r->parent_->root_) ; + return r; + } + + inline const scope* scope:: + weak_scope () const + { + const scope* r (root_); + if (r != nullptr) + for (; r->parent_->root_ != nullptr; r = r->parent_->root_) ; + return r; + } +} diff --git a/build2/target b/build2/target index 30dffab..05e4281 100644 --- a/build2/target +++ b/build2/target @@ -256,7 +256,7 @@ namespace build2 public: // Most qualified scope that contains this target. // - scope& + const scope& base_scope () const; // Root scope of a project that contains this target. Note that @@ -264,19 +264,19 @@ namespace build2 // this function asserts. If you need to detect this situation, // then use base_scope().root_scope() expression instead. // - scope& + const scope& root_scope () const; // Root scope of a strong amalgamation that contains this target. // The same notes as to root_scope() apply. // - scope& + const scope& strong_scope () const {return *root_scope ().strong_scope ();} // Root scope of the outermost amalgamation that contains this target. // The same notes as to root_scope() apply. // - scope& + const scope& weak_scope () const {return *root_scope ().weak_scope ();} bool @@ -1356,24 +1356,24 @@ namespace build2 // template <const char* ext> optional<string> - target_extension_fix (const target_key&, scope&, bool); + target_extension_fix (const target_key&, const scope&, bool); // Get the extension from the variable or use the default if none set. If // the default is NULL, then return NULL. // template <const char* var, const char* def> optional<string> - target_extension_var (const target_key&, scope&, bool); + target_extension_var (const target_key&, const scope&, bool); // Always return NULL extension. // optional<string> - target_extension_null (const target_key&, scope&, bool); + target_extension_null (const target_key&, const scope&, bool); // Assert if called. // optional<string> - target_extension_assert (const target_key&, scope&, bool); + target_extension_assert (const target_key&, const scope&, bool); // Target print functions. // diff --git a/build2/target-type b/build2/target-type index cddb9e2..ab21aa0 100644 --- a/build2/target-type +++ b/build2/target-type @@ -40,11 +40,21 @@ namespace build2 { const char* name; const target_type* base; - target* (*factory) ( - const target_type&, dir_path, dir_path, string, optional<string>); - optional<string> (*extension) (const target_key&, scope&, bool search); + + target* (*factory) (const target_type&, + dir_path, + dir_path, + string, + optional<string>); + + optional<string> (*extension) (const target_key&, + const scope&, + bool search); + void (*print) (ostream&, const target_key&); + target* (*search) (const prerequisite_key&); + bool see_through; // A group with the default "see through" semantics. template <typename T> diff --git a/build2/target.cxx b/build2/target.cxx index f04e26f..30e580a 100644 --- a/build2/target.cxx +++ b/build2/target.cxx @@ -110,7 +110,7 @@ namespace build2 return group_view {nullptr, 0}; } - scope& target:: + const scope& target:: base_scope () const { // If this target is from the src tree, use its out directory to find @@ -119,12 +119,12 @@ namespace build2 return scopes.find (out_dir ()); } - scope& target:: + const scope& target:: root_scope () const { // This is tricky to cache so we do the lookup for now. // - scope* r (base_scope ().root_scope ()); + const scope* r (base_scope ().root_scope ()); assert (r != nullptr); return *r; } @@ -458,13 +458,13 @@ namespace build2 } optional<string> - target_extension_null (const target_key&, scope&, bool) + target_extension_null (const target_key&, const scope&, bool) { return nullopt; } optional<string> - target_extension_assert (const target_key&, scope&, bool) + target_extension_assert (const target_key&, const scope&, bool) { assert (false); // Attempt to obtain the default extension. throw failed (); @@ -605,7 +605,7 @@ namespace build2 { // Note: this code is a custom version of parser::parse_include(). - scope& s (*pk.scope); + const scope& s (*pk.scope); // Calculate the new out_base. // @@ -633,7 +633,8 @@ namespace build2 model_rlock rl; phase_guard pg (run_phase::load); - pair<scope&, scope*> sp (switch_scope (*s.root_scope (), out_base)); + pair<scope&, scope*> sp ( + switch_scope (*s.rw (rl).root_scope (), out_base)); if (sp.second != nullptr) // Ignore scopes out of any project. { @@ -689,7 +690,7 @@ namespace build2 }; static optional<string> - exe_extension (const target_key&, scope&, bool search) + exe_extension (const target_key&, const scope&, bool search) { // If we are searching for an executable that is not a target, then // use the build machine executable extension. Otherwise, if this is @@ -731,7 +732,7 @@ namespace build2 } static optional<string> - buildfile_target_extension (const target_key& tk, scope&, bool) + buildfile_target_extension (const target_key& tk, const scope&, bool) { // If the name is special 'buildfile', then there is no extension, // otherwise it is .build. diff --git a/build2/target.txx b/build2/target.txx index 5519126..ea7bca7 100644 --- a/build2/target.txx +++ b/build2/target.txx @@ -34,14 +34,14 @@ namespace build2 // template <const char* ext> optional<string> - target_extension_fix (const target_key&, scope&, bool) + target_extension_fix (const target_key&, const scope&, bool) { return string (ext); } template <const char* var, const char* def> optional<string> - target_extension_var (const target_key& tk, scope& s, bool) + target_extension_var (const target_key& tk, const scope& s, bool) { // Include target type/pattern-specific variables. // diff --git a/build2/test/rule.cxx b/build2/test/rule.cxx index 6b06dca..05d5eac 100644 --- a/build2/test/rule.cxx +++ b/build2/test/rule.cxx @@ -270,7 +270,7 @@ namespace build2 // Resolve them to targets, which normally would be existing files // but could also be targets that need updating. // - scope& bs (t.base_scope ()); + const scope& bs (t.base_scope ()); // @@ OUT: what if this is a @-qualified pair or names? // diff --git a/build2/test/target.cxx b/build2/test/target.cxx index 44f65aa..a5801e8 100644 --- a/build2/test/target.cxx +++ b/build2/test/target.cxx @@ -25,7 +25,7 @@ namespace build2 } static optional<string> - testscript_target_extension (const target_key& tk, scope&, bool) + testscript_target_extension (const target_key& tk, const scope&, bool) { // If the name is special 'testscript', then there is no extension, // otherwise it is .test. diff --git a/build2/variable b/build2/variable index 33d33a7..aa554fe 100644 --- a/build2/variable +++ b/build2/variable @@ -934,7 +934,7 @@ namespace build2 const variable_visibility* = nullptr, const bool* = nullptr) const; - // Entities that can access bypassing the lock. + // Entities that can access bypassing the lock proof. // friend class parser; friend class scope; diff --git a/unit-tests/function/driver.cxx b/unit-tests/function/driver.cxx index 2f605b0..70fd69e 100644 --- a/unit-tests/function/driver.cxx +++ b/unit-tests/function/driver.cxx @@ -92,7 +92,7 @@ namespace build2 try { - scope& s (*global_scope); + scope& s (*scope::global_); parser p; p.parse_buildfile (cin, path ("buildfile"), s, s); |