aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/file.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/file.hxx')
-rw-r--r--libbuild2/file.hxx166
1 files changed, 132 insertions, 34 deletions
diff --git a/libbuild2/file.hxx b/libbuild2/file.hxx
index e0291fe..36e4c00 100644
--- a/libbuild2/file.hxx
+++ b/libbuild2/file.hxx
@@ -17,7 +17,30 @@
namespace build2
{
class lexer;
-
+ class parser;
+
+ // The following filesystem entries in the build/ subdirectory are reserved
+ // by the build2 core:
+ //
+ // build/ -- build2 core-internal build state (e.g., recipes)
+ // bootstrap/ -- bootstrap state and hooks
+ // bootstrap.build -- bootstrap buildfile
+ // root/ -- root load hooks
+ // root.build -- root buildfile
+ // export.build -- export stub
+ // export/ -- exported buildfiles
+ //
+ // The build/, bootstrap/, root/, and config.build entries are in .gitignore
+ // as generated by bdep-new.
+ //
+ // The rest of the filesystem entries are shared between the project and the
+ // modules that it loads. In particular, if a project loads module named
+ // <mod>, then the <mod>.build, <mod>/, *.<mod> entries (spelled in any
+ // case) are reserved to this module and should not be used by the project
+ // unless explicitly allowed by the module. By convention, <mod>/build/ is
+ // for module-internal build state (e.g., C++ modules side-build) and is
+ // .gitignore'ed.
+ //
LIBBUILD2_SYMEXPORT extern const dir_path std_build_dir; // build/
// build/root.build
@@ -54,7 +77,7 @@ namespace build2
find_src_root (const dir_path&, optional<bool>& altn);
// The same as above but for project's out. Note that we also check whether
- // a directory happens to be src_root, in case this is an in-tree build with
+ // a directory happens to be src_root, in case this is an in source build with
// the result returned as the second half of the pair. Note also that if the
// input is normalized/actualized, then the output will be as well.
//
@@ -115,10 +138,11 @@ namespace build2
bool
source_once (scope& root, scope& base, const path&);
- // As above but checks against the specified scope rather than base.
+ // As above but checks against the specified root scope rather than this
+ // root scope.
//
LIBBUILD2_SYMEXPORT bool
- source_once (scope& root, scope& base, const path&, scope& once);
+ source_once (scope& root, scope& base, const path&, scope& once_root);
// Create project's root scope. Only set the src_root variable if the passed
// src_root value is not empty.
@@ -145,8 +169,12 @@ namespace build2
// false or the new scope is not in any project, then NULL is returned in
// second.
//
+ // Note that if switching the scope involved switching the project, then you
+ // may also need to switch to the new project's environment (see
+ // root_extra::environment).
+ //
LIBBUILD2_SYMEXPORT pair<scope&, scope*>
- switch_scope (scope& root, const dir_path&, bool project = true);
+ switch_scope (scope& root, const dir_path& out_base, bool project = true);
// Bootstrap and optionally load an ad hoc (sub)project (i.e., the kind that
// is not discovered and loaded automatically by bootstrap/load functions
@@ -178,8 +206,15 @@ namespace build2
// Bootstrap the project's root scope, the src part.
//
+ // If amalgamation is present, then use the specified directory as the
+ // amalgamation instead of discovering or extracting it from bootstrap.build
+ // (use empty directory to disable amalgamation). If subprojects is false,
+ // then do not discover or extract subprojects.
+ //
LIBBUILD2_SYMEXPORT void
- bootstrap_src (scope& root, optional<bool>& altn);
+ bootstrap_src (scope& root, optional<bool>& altn,
+ optional<dir_path> amalgamation = nullopt,
+ bool subprojects = true);
// Return true if this scope has already been bootstrapped, that is, the
// following calls have already been made:
@@ -201,10 +236,11 @@ namespace build2
bootstrap_post (scope& root);
// Create and bootstrap outer root scopes, if any. Loading is done by
- // load_root().
+ // load_root(). If subprojects is false, then do not discover or extract
+ // subprojects.
//
LIBBUILD2_SYMEXPORT void
- create_bootstrap_outer (scope& root);
+ create_bootstrap_outer (scope& root, bool subprojects = true);
// Create and bootstrap inner root scopes, if any, recursively.
//
@@ -220,8 +256,13 @@ namespace build2
// loaded. Also make sure all outer root scopes are loaded prior to loading
// this root scope.
//
+ // If pre/post functions are specified, they are called before/after
+ // pre/post hooks, respectively.
+ //
LIBBUILD2_SYMEXPORT void
- load_root (scope& root);
+ load_root (scope& root,
+ const function<void (parser&)>& pre = nullptr,
+ const function<void (parser&)>& post = nullptr);
// Extract the specified variable value from a buildfile. It is expected to
// be the first non-blank/comment line and not to rely on any variable
@@ -305,10 +346,14 @@ namespace build2
// original; see the config.import.<proj>.<name>[.<type>] logic for details)
// in which case it should still be passed to import phase 2.
//
- // If phase2 is true then the phase 2 is performed right away (we call it
- // immediate import). Note that if optional is true, phase2 must be true as
- // well (and thus there is no rule-specific logic for optional imports). In
- // case of optional, empty names value is retuned if nothing was found.
+ // If phase2 is present then the phase 2 is performed right away (we call it
+ // immediate import). Note that if optional is true, phase2 must be present
+ // as well (and thus there is no rule-specific logic for optional imports).
+ // In case of optional, empty names value is returned if nothing was found.
+ // The value in phase2 is the optional rule hint that, if not empty, will be
+ // used to lookup a rule that will be asked to resolve the qualified target
+ // (see rule::import()). If it is empty, then built-in resolution logic will
+ // be used for some target types (currently only exe{}).
//
// If metadata is true, then load the target metadata. In this case phase2
// must be true as well.
@@ -316,7 +361,9 @@ namespace build2
// Note also that we return names rather than a single name: while normally
// it will be a single target name, it can be an out-qualified pair (if
// someone wants to return a source target) but it can also be a non-target
- // since we don't restrict what users can import/export.
+ // since we don't restrict what users can import/export. If name has
+ // buildfile type, then the result is an absolute buildfile target to be
+ // included (once) at the point of importation.
//
// Finally, note that import is (and should be kept) idempotent or, more
// precisely, "accumulatively idempotent" in that additional steps may be
@@ -324,10 +371,21 @@ namespace build2
//
enum class import_kind {adhoc, normal, fallback};
- LIBBUILD2_SYMEXPORT pair<names, import_kind>
+ template <typename T>
+ struct import_result
+ {
+ const T* target; // Note: T can be imported target or imported scope.
+ names name;
+ import_kind kind;
+ };
+
+ // Note that import_result<scope>::target may be NULL even if name is not
+ // empty (e.g, out of project target imported via phase 2).
+ //
+ LIBBUILD2_SYMEXPORT import_result<scope>
import (scope& base,
name,
- bool phase2,
+ const optional<string>& phase2,
bool optional,
bool metadata,
const location&);
@@ -335,33 +393,45 @@ namespace build2
// Import phase 2.
//
const target&
- import (context&, const prerequisite_key&);
+ import2 (context&, const prerequisite_key&);
// As above but import the target "here and now" without waiting for phase 2
// (and thus omitting any rule-specific logic). This version of import is,
// for example, used by build system modules to perform an implicit import
// of the corresponding tool.
//
- // If phase2 is false, then the second phase's fallback/default logic is
+ // If phase2 is absent, then the second phase's fallback/default logic is
// only invoked if the import was ad hoc (i.e., a relative path was
// specified via config.import.<proj>.<name>[.<type>]) with NULL returned
// otherwise.
//
- // If phase2 is true and optional is true, then NULL is returned instead of
- // failing if phase 2 could not find anything.
+ // If phase2 is present and optional is true, then NULL is returned instead
+ // of failing if phase 2 could not find anything.
//
// If metadata is true, then load the target metadata. In this case phase2
- // must be true as well.
+ // must be present as well.
//
// The what argument specifies what triggered the import (for example,
// "module load") and is used in diagnostics.
//
- // This function also returns the kind of import that was performed.
+ // This function also returns the stable exported target name (see
+ // target::as_name() for details) as well as the kind of import that was
+ // performed.
+ //
+ // Note: cannot be used to import buildfile targets (use import_buildfile()
+ // instead).
+
+ // Print import_direct<exe>() result either as a target for a normal import
+ // or as a process path for ad hoc and fallback imports. Normally used in
+ // build system modules to print the configuration report.
//
- pair<const target*, import_kind>
+ LIBBUILD2_SYMEXPORT ostream&
+ operator<< (ostream&, const import_result<exe>&);
+
+ import_result<target>
import_direct (scope& base,
name,
- bool phase2,
+ const optional<string>& phase2,
bool optional,
bool metadata,
const location&,
@@ -372,37 +442,44 @@ namespace build2
// details. Note that a phase 2 fallback/default logic is not considered new
// (though this can be easily adjusted based on import kind).
//
- LIBBUILD2_SYMEXPORT pair<const target*, import_kind>
+ LIBBUILD2_SYMEXPORT import_result<target>
import_direct (bool& new_value,
scope& base,
name,
- bool phase2,
+ const optional<string>& phase2,
bool optional,
bool metadata,
const location&,
const char* what = "import");
+ // As above but also cast the target and pass phase2 as bool (primarily
+ // for use in build system modules).
+ //
template <typename T>
- pair<const T*, import_kind>
+ import_result<T>
import_direct (scope&,
name, bool, bool, bool,
const location&, const char* = "import");
template <typename T>
- pair<const T*, import_kind>
+ import_result<T>
import_direct (bool&,
scope&,
name,
bool, bool, bool,
const location&, const char* = "import");
- // Print import_direct<exe>() result either as a target for a normal import
- // or as a process path for ad hoc and fallback imports. Normally used in
- // build system modules to print the configuration report.
+ // The import_direct() equivalent for importing buildfile targets. Return
+ // empty name if optional and not found. Note that the returned file path is
+ // not necessarily checked for existence so sourcing it may still fail.
//
- LIBBUILD2_SYMEXPORT ostream&
- operator<< (ostream&, const pair<const exe*, import_kind>&);
+ // Note also that this function can be used for an ad hoc import by passing
+ // an absolute target name as would be returned by the normal import (can be
+ // useful for importing own buildfiles).
+ //
+ LIBBUILD2_SYMEXPORT path
+ import_buildfile (scope& base, name, bool optional, const location&);
// As import phase 2 but only imports as an already existing target. But
// unlike it, this function can be called during the load and execute
@@ -444,6 +521,27 @@ namespace build2
bool metadata,
const location&);
+ // Import (more precisely, alias as if using the `define =` syntax) the
+ // target type from imported project (iroot) into this project (root). If
+ // the target type with this name is already defined in this project, then
+ // make sure it is the same as in the imported project.
+ //
+ LIBBUILD2_SYMEXPORT const target_type&
+ import_target_type (scope& root,
+ const scope& iroot, const string&,
+ const location&);
+
+ // Suggest appropriate ways to import the specified target (as type and
+ // name) from the specified project.
+ //
+ void
+ import_suggest (const diag_record&,
+ const project_name&,
+ const target_type*,
+ const string& name,
+ bool rule_hint,
+ const char* qual = nullptr);
+
// Create a build system project in the specified directory.
//
LIBBUILD2_SYMEXPORT void
@@ -458,7 +556,7 @@ namespace build2
const optional<string>& config_file, // Ad hoc config.build contents.
bool buildfile, // Create root buildfile.
const char* who, // Who is creating it.
- uint16_t verbosity = 1); // Diagnostic verbosity.
+ uint16_t verbosity); // Diagnostic verbosity.
}
#include <libbuild2/file.ixx>