diff options
Diffstat (limited to 'libbuild2/file.hxx')
-rw-r--r-- | libbuild2/file.hxx | 154 |
1 files changed, 119 insertions, 35 deletions
diff --git a/libbuild2/file.hxx b/libbuild2/file.hxx index b47d8dc..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. @@ -182,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: @@ -205,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. // @@ -224,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 @@ -309,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. @@ -320,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 @@ -328,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&); @@ -339,23 +393,23 @@ 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. @@ -364,18 +418,20 @@ namespace build2 // target::as_name() for details) as well as the kind of import that was // performed. // - template <typename T> - struct import_result - { - const T* target; - names name; - import_kind kind; - }; + // 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. + // + 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&, @@ -390,13 +446,16 @@ namespace build2 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> import_result<T> import_direct (scope&, @@ -411,12 +470,16 @@ namespace build2 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 import_result<exe>&); + // 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 @@ -458,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 @@ -472,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> |