diff options
Diffstat (limited to 'build2/search.cxx')
-rw-r--r-- | build2/search.cxx | 244 |
1 files changed, 0 insertions, 244 deletions
diff --git a/build2/search.cxx b/build2/search.cxx deleted file mode 100644 index 68fd5a5..0000000 --- a/build2/search.cxx +++ /dev/null @@ -1,244 +0,0 @@ -// file : build2/search.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include <build2/search.hxx> - -#include <build2/scope.hxx> -#include <build2/target.hxx> -#include <build2/context.hxx> -#include <build2/filesystem.hxx> // mtime() -#include <build2/prerequisite.hxx> -#include <build2/diagnostics.hxx> - -using namespace std; -using namespace butl; - -namespace build2 -{ - const target* - search_existing_target (const prerequisite_key& pk) - { - tracer trace ("search_existing_target"); - - const target_key& tk (pk.tk); - - // Look for an existing target in the prerequisite's scope. - // - dir_path d; - if (tk.dir->absolute ()) - d = *tk.dir; // Already normalized. - else - { - d = tk.out->empty () ? pk.scope->out_path () : pk.scope->src_path (); - - if (!tk.dir->empty ()) - { - d /= *tk.dir; - d.normalize (); - } - } - - // Prerequisite's out directory can be one of the following: - // - // empty This means out is undetermined and we simply search for a - // target that is in the out tree which happens to be indicated - // by an empty value, so we can just pass this as is. - // - // absolute This is the "final" value that doesn't require any processing - // and we simply use it as is. - // - // relative The out directory was specified using @-syntax as relative (to - // the prerequisite's scope) and we need to complete it similar - // to how we complete the relative dir above. - // - dir_path o; - if (!tk.out->empty ()) - { - if (tk.out->absolute ()) - o = *tk.out; // Already normalized. - else - { - o = pk.scope->out_path (); - o /= *tk.out; - o.normalize (); - } - - // Drop out if it is the same as src (in-src build). - // - if (o == d) - o.clear (); - } - - const target* t (targets.find (*tk.type, d, o, *tk.name, tk.ext, trace)); - - if (t != nullptr) - l5 ([&]{trace << "existing target " << *t - << " for prerequisite " << pk;}); - - return t; - } - - const target* - search_existing_file (const prerequisite_key& cpk) - { - tracer trace ("search_existing_file"); - - const target_key& ctk (cpk.tk); - const scope* s (cpk.scope); - - path f; - - if (ctk.dir->absolute ()) - f = *ctk.dir; // Already normalized. - else - { - f = s->src_path (); - - if (!ctk.dir->empty ()) - { - f /= *ctk.dir; - f.normalize (); - } - } - - // Bail out if not inside project's src_root. - // - if (s == nullptr || !f.sub (s->root_scope ()->src_path ())) - return nullptr; - - // Figure out the extension. Pretty similar logic to file::derive_path(). - // - optional<string> ext (ctk.ext); - - if (!ext) - { - if (auto f = ctk.type->fixed_extension) - ext = f (ctk, s->root_scope ()); - else if (auto f = ctk.type->default_extension) - ext = f (ctk, *s, nullptr, true); - - if (!ext) - { - // What should we do here, fail or say we didn't find anything? - // Current think is that if the target type couldn't find the default - // extension, then we simply shouldn't search for any existing files - // (of course, if the user specified the extension explicitly, we will - // still do so). - // - l4 ([&]{trace << "no default extension for prerequisite " << cpk;}); - return nullptr; - } - } - - // Make a copy with the updated extension. - // - const prerequisite_key pk { - cpk.proj, {ctk.type, ctk.dir, ctk.out, ctk.name, ext}, cpk.scope}; - const target_key& tk (pk.tk); - - // Check if there is a file. - // - f /= *tk.name; - - if (!ext->empty ()) - { - f += '.'; - f += *ext; - } - - timestamp mt (mtime (f)); - - if (mt == timestamp_nonexistent) - { - l4 ([&]{trace << "no existing file for prerequisite " << cpk;}); - return nullptr; - } - - l5 ([&]{trace << "found existing file " << f << " for prerequisite " - << cpk;}); - - dir_path d (f.directory ()); - - // Calculate the corresponding out. We have the same three options for the - // prerequisite's out directory as in search_existing_target(). If it is - // empty (undetermined), then we need to calculate it since this target - // will be from the src tree. - // - // In the other two cases we use the prerequisite's out (in case it is - // relative, we need to complete it, which is @@ OUT TODO). Note that we - // blindly trust the user's value which can be used for some interesting - // tricks, for example: - // - // ../cxx{foo}@./ - // - dir_path out; - - if (tk.out->empty ()) - { - if (s->out_path () != s->src_path ()) - out = out_src (d, *s->root_scope ()); - } - else - out = *tk.out; - - // Find or insert. Note that we are using our updated extension. - // - auto r ( - targets.insert ( - *tk.type, move (d), move (out), *tk.name, ext, true, trace)); - - // Has to be a file_target. - // - const file& t (dynamic_cast<const file&> (r.first)); - - l5 ([&]{trace << (r.second ? "new" : "existing") << " target " << t - << " for prerequisite " << cpk;}); - - t.mtime (mt); - t.path (move (f)); - - return &t; - } - - const target& - create_new_target (const prerequisite_key& pk) - { - tracer trace ("create_new_target"); - - const target_key& tk (pk.tk); - - // We default to the target in this directory scope. - // - dir_path d; - if (tk.dir->absolute ()) - d = *tk.dir; // Already normalized. - else - { - d = pk.scope->out_path (); - - if (!tk.dir->empty ()) - { - d /= *tk.dir; - d.normalize (); - } - } - - // Find or insert. - // - // @@ OUT: same story as in search_existing_target() re out. - // - auto r (targets.insert (*tk.type, - move (d), - *tk.out, - *tk.name, - tk.ext, - true /* implied */, - trace)); - - const target& t (r.first); - l5 ([&]{trace << (r.second ? "new" : "existing") << " target " << t - << " for prerequisite " << pk;}); - return t; - } -} |