aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/target.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-04-27 09:49:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-04-27 10:03:50 +0200
commit9e5750ae2e3f837f80860aaab6b01e4d556213ed (patch)
treed3b2e551e444c47b6ce0289969e78360161b6685 /libbuild2/target.hxx
parent028e10ba787a7dbb46e3fcba6f88f496b76cebc5 (diff)
Rework tool importation along with cli module
Specifically, now config.<tool> (like config.cli) is handled by the import machinery (it is like a shorter alias for config.import.<tool>.<tool>.exe that we already had). And the cli module now uses that instead of custom logic. This also adds support for uniform tool metadata extraction that is handled by the import machinery. As a result, a tool that follows the "build2 way" can be imported with metadata by the buildfile and/or corresponding module without any tool-specific code or brittleness associated with parsing --version or similar outputs. See the cli tool/module for details. Finally, two new flavors of the import directive are now supported: import! triggers immediate importation skipping any rule-specific logic while import? is optional import (analogous to using?). Note that optional import is always immediate. There is also the import-specific metadata attribute which can be specified for these two import flavors in order to trigger metadata importation. For example: import? [metadata] cli = cli%exe{cli} if ($cli != [null]) info "cli version $($cli:cli.version)"
Diffstat (limited to 'libbuild2/target.hxx')
-rw-r--r--libbuild2/target.hxx63
1 files changed, 60 insertions, 3 deletions
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index ea72925..6edfe5c 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -138,7 +138,7 @@ namespace build2
class LIBBUILD2_SYMEXPORT target
{
public:
- // Context this scope belongs to.
+ // Context this target belongs to.
//
context& ctx;
@@ -305,6 +305,12 @@ namespace build2
target_key
key () const;
+ names
+ as_name () const
+ {
+ return key ().as_name ();
+ }
+
// Scoping.
//
public:
@@ -764,6 +770,15 @@ namespace build2
virtual const target_type& dynamic_type () const = 0;
static const target_type static_type;
+ // RW access.
+ //
+ target&
+ rw () const
+ {
+ assert (ctx.phase == run_phase::load);
+ return const_cast<target&> (*this);
+ }
+
public:
// Split the name leaf into target name (in place) and extension
// (returned).
@@ -1529,8 +1544,15 @@ namespace build2
//
// An empty path may signify special unknown/undetermined/unreal location
// (for example, a binless library or an installed import library -- we
- // know the DLL is there, just not exactly where). In this case you would
- // also normally set its mtime.
+ // know the DLL is there, just not exactly where). In this case you could
+ // also set its mtime to timestamp_unreal (but don't have to, if a real
+ // timestamp can be derived, for example, the from the import library in
+ // the DLL case above).
+ //
+ // Note, however, that a target with timestamp_unreal does not have to
+ // have an empty path. One consequence of this arrangement (assigned path
+ // with unreal timestamp) is that the timestamp of such a target when used
+ // as a prerequisite won't affect the dependent's target out-of-date-ness.
//
// We used to return a pointer to properly distinguish between not set and
// empty but that proved too tedious to work with. So now we return empty
@@ -1705,9 +1727,44 @@ namespace build2
public:
using file::file;
+ using process_path_type = build2::process_path;
+
+ // Return the process path of this executable target. Normally it will be
+ // the absolute path returned by path() but can also be something custom
+ // if, for example, the target was found via a PATH search (see import for
+ // details). The idea is to use this path if we need to execute the target
+ // in which case, for the above example, we will see a short (recall) path
+ // instead of the absolute one in diagnostics.
+ //
+ process_path_type
+ process_path () const
+ {
+ // It's unfortunate we have to return by value but hopefully the
+ // compiler will see through it. Note also that returning empty
+ // process path if path is empty.
+ //
+ return process_path_.empty ()
+ ? process_path_type (path ().string ().c_str (),
+ path_type (),
+ path_type ())
+ : process_path_type (process_path_, false /* init */);
+ }
+
+ // Note that setting the custom process path is not MT-safe and must be
+ // done while holding the insertion lock.
+ //
+ void
+ process_path (process_path_type p)
+ {
+ process_path_ = move (p);
+ }
+
public:
static const target_type static_type;
virtual const target_type& dynamic_type () const {return static_type;}
+
+ private:
+ process_path_type process_path_;
};
class LIBBUILD2_SYMEXPORT buildfile: public file