// file : build2/context -*- C++ -*- // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef BUILD2_CONTEXT #define BUILD2_CONTEXT #include #include #include #include #include #include namespace build2 { class scope; class file; extern dir_path work; extern dir_path home; extern options ops; extern string_pool extension_pool; extern string_pool project_name_pool; // Current action (meta/operation). // extern const meta_operation_info* current_mif; extern const operation_info* current_inner_oif; extern const operation_info* current_outer_oif; extern execution_mode current_mode; // Total number of dependency relationships in the current action. // Together with the target::dependents count it is incremented // during the rule search & match phase and is decremented during // execution with the expectation of it reaching 0. Used as a sanity // check. // extern uint64_t dependency_count; // Project-wide (as opposed to global) variable overrides. Returned by // reset(). // struct variable_override { const variable& var; // Original variable. const variable& ovr; // Override variable. value val; }; using variable_overrides = vector; // Reset the build state. In particular, this removes all the targets, // scopes, and variables. // variable_overrides reset (const strings& cmd_vars); // The dual interface wrapper for the {mk,rm}{file,dir}() functions // below that allows you to use it as a true/false return or a more // detailed enum from // template struct fs_status { T v; fs_status (T v): v (v) {}; operator T () const {return v;} explicit operator bool () const {return v == T::success;} }; // Create the directory and print the standard diagnostics. Note that // this implementation is not suitable if it is expected that the // directory will exist in the majority of case and performance is // important. See the fsdir{} rule for details. // fs_status mkdir (const dir_path&); fs_status mkdir_p (const dir_path&); // Remove the file and print the standard diagnostics. The second argument // is only used in diagnostics, to print the target name. Passing the path // for target will result in the relative path being printed. // // If verbose is false, then only print the command at verbosity level 3 // or higher. // template fs_status rmfile (const path&, const T& target, bool verbose = true); inline fs_status rmfile (const path& f, bool verbose = true) {return rmfile (f, f, verbose);} // Similar to rmfile() but for directories. // template fs_status rmdir (const dir_path&, const T& target); inline fs_status rmdir (const dir_path& d) {return rmdir (d, d);} // Note that this function returns not_empty if we try to remove // a working directory. // fs_status rmdir_r (const dir_path&); // Return the src/out directory corresponding to the given out/src. The // passed directory should be a sub-directory of out/src_base. // dir_path src_out (const dir_path& out, scope&); dir_path src_out (const dir_path& out, const dir_path& out_base, const dir_path& src_base); dir_path out_src (const dir_path& src, scope&); dir_path out_src (const dir_path& src, const dir_path& out_base, const dir_path& src_base); // If possible and beneficial, translate an absolute, normalized path // into relative to the relative_base directory, which is normally // work. Note that if the passed path is the same as relative_base, // then this function returns empty path. // template basic_path relative (const basic_path&); // By default this points to work. Setting this to something else // should only be done in tightly controlled, non-parallel // situations (see dump). If base is empty, then relative() // returns the original path. // extern const dir_path* relative_base; // In addition to calling relative(), this function also uses shorter // notations such as '~/'. // string diag_relative (const path&); // As above but also adds trailing '/'. If the path is the same as // base, returns "./" if current is true and empty string otherwise. // string diag_relative (const dir_path&, bool current = true); // Action phrases, e.g., "configure update exe{foo}", "updating exe{foo}", // and "updating exe{foo} is configured". Use like this: // // info << "while " << diag_doing (a, t); // class target; struct diag_phrase { const action& a; const target& t; void (*f) (ostream&, const action&, const target&); }; inline ostream& operator<< (ostream& os, const diag_phrase& p) { p.f (os, p.a, p.t); return os; } void diag_do (ostream&, const action&, const target&); inline diag_phrase diag_do (const action& a, const target& t) { return diag_phrase {a, t, &diag_do}; } void diag_doing (ostream&, const action&, const target&); inline diag_phrase diag_doing (const action& a, const target& t) { return diag_phrase {a, t, &diag_doing}; } void diag_done (ostream&, const action&, const target&); inline diag_phrase diag_done (const action& a, const target& t) { return diag_phrase {a, t, &diag_done}; } } #include #endif // BUILD2_CONTEXT