From abb7bf1045fde14f6ef87c8941ee22af233af397 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 3 Aug 2015 15:47:35 +0200 Subject: match_only rework, part 2 --- build/cxx/compile.cxx | 43 ++++++++-------------------------- build/cxx/link.cxx | 64 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 56 insertions(+), 51 deletions(-) (limited to 'build/cxx') diff --git a/build/cxx/compile.cxx b/build/cxx/compile.cxx index 48d2240..8dcad1e 100644 --- a/build/cxx/compile.cxx +++ b/build/cxx/compile.cxx @@ -98,46 +98,23 @@ namespace build // A dependency on a library is there so that we can get its // cxx.export.poptions. In particular, making sure it is // executed before us will only restrict parallelism. But we - // do need to match it in order to get its prerequisite_targets - // populated; see append_lib_options() above. + // do need to pre-match it in order to get its + // prerequisite_targets populated. This is the "library + // meta-information protocol". See also append_lib_options() + // above. // if (p.is_a () || p.is_a () || p.is_a ()) { if (a.operation () == update_id) { - // Handle imported libraries. + // Handle imported libraries. We know that for such libraries + // we don't need to do match() in order to get options (if + // any, they would be set by search_library()). // - if (p.proj () != nullptr) + if (p.proj () == nullptr || + link::search_library (lib_paths, p.prerequisite) == nullptr) { - // We know that for such libraries we don't need to do - // match() in order to get options (if any, they would - // be set by search_library()). - // - // @@ What if this is an installed import with an export - // stub? How will such a stub capture prerequsite libs? - // Probably as imported prerequisites, e.g., %lib{z}, not - // as -lz in .libs variable. - // - // In fact, even if we tried match() on lib{}, nothing - // would have matched since that lib{} is out of any - // project and is not a file (which is the case for - // liba/libso). So probably the importing code would - // have to take care of importing all the prerequisite - // libraries. It does make sense since we don't really - // want to match a rule to an installed library. - // - if (link::search_library (lib_paths, p.prerequisite) != nullptr) - continue; - } - - target& pt (p.search ()); - - if (p.is_a ()) //@@ TMP - build::match_only (a, pt); - else - { - build::match (a, pt); - pt.dependents--; + match_only (a, p.search ()); } } diff --git a/build/cxx/link.cxx b/build/cxx/link.cxx index 5c3a515..97c9696 100644 --- a/build/cxx/link.cxx +++ b/build/cxx/link.cxx @@ -365,7 +365,7 @@ namespace build // (i.e., a utility library). // - bool so (t.is_a ()); + type lt (link_type (t)); // Scan prerequisites and see if we can work with what we've got. // @@ -384,7 +384,7 @@ namespace build } else if (p.is_a ()) { - if (so) + if (lt == type::so) fail << "shared library " << t << " prerequisite " << p << " is static object"; @@ -423,6 +423,45 @@ namespace build return nullptr; } + // If we have any prerequisite libraries (which also means that + // we match), search/import and pre-match them to implement the + // "library meta-information protocol". + // + if (seen_lib && lt != type::e) + { + if (t.group != nullptr) + t.group->prerequisite_targets.clear (); // lib{}'s + + search_paths_cache lib_paths; // Extract lazily. + + for (prerequisite_member p: group_prerequisite_members (a, t)) + { + if (p.is_a () || p.is_a () || p.is_a ()) + { + target* pt (nullptr); + + // Handle imported libraries. + // + if (p.proj () != nullptr) + pt = search_library (lib_paths, p.prerequisite); + + if (pt == nullptr) + { + pt = &p.search (); + match_only (a, *pt); + } + + // If the prerequisite came from the lib{} group, then also + // add it to lib's prerequisite_targets. + // + if (!p.prerequisite.belongs (t)) + t.group->prerequisite_targets.push_back (pt); + + t.prerequisite_targets.push_back (pt); + } + } + } + return seen_cxx || seen_c || seen_obj || seen_lib ? &t : nullptr; } @@ -449,6 +488,8 @@ namespace build } } + t.prerequisite_targets.clear (); // See lib pre-match in match() above. + // Inject dependency on the output directory. // inject_parent_fsdir (a, t); @@ -480,27 +521,14 @@ namespace build if (!p.is_a () && !p.is_a ()) { - // Handle imported libraries. Essentially, we want to replicate - // the -lfoo functionality but as part of our import support. + // Handle imported libraries. // - if (p.proj () != nullptr && - (p.is_a () || p.is_a () || p.is_a ())) - { + if (p.proj () != nullptr) pt = search_library (lib_paths, p.prerequisite); - // We only need this target if we are updating (remember, like - // -lfoo). The question is why search in the first place? The - // reason is the "not found" situation, in which someone else - // (i.e., the import phase 2) could resolve it to something - // that, who knows, might need cleaning, for example. - // - if (pt != nullptr && a.operation () != update_id) - continue; // Skip. - } - // The rest is the same basic logic as in search_and_match(). // - if (pt == nullptr) // Could've been resolved by search_library(). + if (pt == nullptr) pt = &p.search (); if (a.operation () == clean_id && !pt->dir.sub (*amlg)) -- cgit v1.1