From 4d1c02b736f4c1e827b11085cdc83ce4b46c03d1 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 26 Jun 2016 16:06:54 +0200 Subject: Add notion of ad hoc group, use to handle DLL/import library --- build2/install/module.cxx | 6 ++--- build2/install/rule.cxx | 64 ++++++++++++++++++++++++++++++++++------------- build2/install/utility | 22 ++++++++++++---- 3 files changed, 66 insertions(+), 26 deletions(-) (limited to 'build2/install') diff --git a/build2/install/module.cxx b/build2/install/module.cxx index 1ebbb17..15c6ea8 100644 --- a/build2/install/module.cxx +++ b/build2/install/module.cxx @@ -182,9 +182,9 @@ namespace build2 // Configure "installability" for built-in target types. // - path (b, dir_path ("doc")); // Install into install.doc. - path (b, dir_path ("man")); // Install into install.man. - path (b, dir_path ("man1")); // Install into install.man1. + install_path (b, dir_path ("doc")); // Install into install.doc. + install_path (b, dir_path ("man")); // Install into install.man. + install_path (b, dir_path ("man1")); // Install into install.man1. return true; } diff --git a/build2/install/rule.cxx b/build2/install/rule.cxx index 24c1df0..cbfb105 100644 --- a/build2/install/rule.cxx +++ b/build2/install/rule.cxx @@ -18,9 +18,9 @@ namespace build2 { namespace install { - // Lookup the install or install.* variable. Return NULL if - // not found or if the value is the special 'false' name (which - // means do not install). T is either scope or target. + // Lookup the install or install.* variable. Return NULL if not found or + // if the value is the special 'false' name (which means do not install). + // T is either scope or target. // template static const dir_path* @@ -131,8 +131,11 @@ namespace build2 // run standard search_and_match()? Will need an indicator // that it was forced (e.g., [install]) for filter() below. // - for (prerequisite_member p: group_prerequisite_members (a, t)) + auto r (group_prerequisite_members (a, t)); + for (auto i (r.begin ()); i != r.end (); ++i) { + prerequisite_member p (*i); + // Ignore unresolved targets that are imported from other projects. // We are definitely not installing those. // @@ -145,7 +148,7 @@ namespace build2 if (pt == nullptr) continue; - // See if the user instructed us not to install it. + // See if were explicitly instructed not to install this target. // auto l ((*pt)["install"]); if (l && cast (l).string () == "false") @@ -163,6 +166,11 @@ namespace build2 t.prerequisite_targets.push_back (pt); else unmatch (a, *pt); // No intent to execute. + + // Skip members of ad hoc groups. We handle them explicitly below. + // + if (pt->adhoc_group ()) + i.leave_group (); } // This is where we diverge depending on the operation. In the @@ -275,8 +283,11 @@ namespace build2 // install // + // If verbose is false, then only print the command at verbosity level 2 + // or higher. + // static void - install (const install_dir& base, file& t) + install (const install_dir& base, file& t, bool verbose = true) { path reld (relative (base.dir)); path relf (relative (t.path ())); @@ -299,7 +310,7 @@ namespace build2 if (verb >= 2) print_process (args); - else if (verb) + else if (verb && verbose) text << "install " << t; try @@ -390,27 +401,44 @@ namespace build2 } target_state file_rule:: - perform_install (action a, target& t) + perform_install (action a, target& xt) { - file& ft (static_cast (t)); - assert (!ft.path ().empty ()); // Should have been assigned by update. + file& t (static_cast (xt)); + assert (!t.path ().empty ()); // Should have been assigned by update. + + scope& bs (t.base_scope ()); + + auto install_target = [&bs](file& t, const dir_path& d, bool verbose) + { + // Resolve and, if necessary, create target directory. + // + install_dir id (resolve (bs, d)); + + // Override mode if one was specified. + // + if (auto l = t["install.mode"]) + id.mode = cast (l); + + install (id, t, verbose); + }; // First handle installable prerequisites. // target_state r (execute_prerequisites (a, t)); - // Resolve and, if necessary, create target directory. + // Then installable ad hoc group members, if any. // - install_dir d ( - resolve (t.base_scope (), - cast (t["install"]))); // We know it's there. + for (target* m (t.member); m != nullptr; m = m->member) + { + if (const dir_path* d = lookup (*m, "install")) + install_target (static_cast (*m), *d, false); + } - // Override mode if one was specified. + // Finally install the target itself (since we got here we know the + // install variable is there). // - if (auto l = t["install.mode"]) - d.mode = cast (l); + install_target (t, cast (t["install"]), true); - install (d, ft); return (r |= target_state::changed); } } diff --git a/build2/install/utility b/build2/install/utility index 3d3b1a1..1abed27 100644 --- a/build2/install/utility +++ b/build2/install/utility @@ -16,23 +16,35 @@ namespace build2 { // Set install path, mode for a target type. // - template inline void - path (scope& s, dir_path d) + install_path (const target_type& tt, scope& s, dir_path d) { - auto r (s.target_vars[T::static_type]["*"].assign ("install")); + auto r (s.target_vars[tt]["*"].assign ("install")); if (r.second) // Already set by the user? r.first.get () = move (d); } template inline void - mode (scope& s, string m) + install_path (scope& s, dir_path d) + { + return install_path (T::static_type, s, d); + } + + inline void + install_mode (const target_type& tt, scope& s, string m) { - auto r (s.target_vars[T::static_type]["*"].assign ("install.mode")); + auto r (s.target_vars[tt]["*"].assign ("install.mode")); if (r.second) // Already set by the user? r.first.get () = move (m); } + + template + inline void + install_mode (scope& s, string m) + { + return install_mode (T::static_type, s, m); + } } } -- cgit v1.1