namespace { | namespace { | ||||
/// XXX: Duplicated in compile_exec.cpp !! | |||||
template <typename Range, typename Fn> | template <typename Range, typename Fn> | ||||
bool parallel_run(Range&& rng, int n_jobs, Fn&& fn) { | bool parallel_run(Range&& rng, int n_jobs, Fn&& fn) { | ||||
// We don't bother with a nice thread pool, as the overhead of most build | // We don't bother with a nice thread pool, as the overhead of most build | ||||
} | } | ||||
void build_plan::link_all(const build_env& env, int njobs) const { | void build_plan::link_all(const build_env& env, int njobs) const { | ||||
// Generate a pairing between executables and the libraries that own them | |||||
std::vector<std::pair<std::reference_wrapper<const library_plan>, | std::vector<std::pair<std::reference_wrapper<const library_plan>, | ||||
std::reference_wrapper<const link_executable_plan>>> | std::reference_wrapper<const link_executable_plan>>> | ||||
executables; | executables; | ||||
for (auto&& lib : iter_libraries(*this)) { | for (auto&& lib : iter_libraries(*this)) { | ||||
for (auto&& exe : lib.executables()) { | for (auto&& exe : lib.executables()) { | ||||
executables.emplace_back(lib, exe); | executables.emplace_back(lib, exe); | ||||
std::vector<test_failure> build_plan::run_all_tests(build_env_ref env, int njobs) const { | std::vector<test_failure> build_plan::run_all_tests(build_env_ref env, int njobs) const { | ||||
using namespace ranges::views; | using namespace ranges::views; | ||||
// Collect executables that are tests | |||||
auto test_executables = // | auto test_executables = // | ||||
iter_libraries(*this) // | iter_libraries(*this) // | ||||
| transform(&library_plan::executables) // | | transform(&library_plan::executables) // |
namespace dds { | namespace dds { | ||||
/** | |||||
* Encompases an entire build plan. | |||||
* | |||||
* A build plan consists of some number of packages, defined as `package_plan` | |||||
* objects. | |||||
*/ | |||||
class build_plan { | class build_plan { | ||||
/// The packages that are part of this plan. | |||||
std::vector<package_plan> _packages; | std::vector<package_plan> _packages; | ||||
public: | public: | ||||
/** | |||||
* Append a new package plan. Returns a reference to the package plan so that it can be further | |||||
* tweaked. Note that the reference is not stable. | |||||
*/ | |||||
package_plan& add_package(package_plan p) noexcept { | package_plan& add_package(package_plan p) noexcept { | ||||
return _packages.emplace_back(std::move(p)); | return _packages.emplace_back(std::move(p)); | ||||
} | } | ||||
/** | |||||
* All of the packages in this plan | |||||
*/ | |||||
auto& packages() const noexcept { return _packages; } | auto& packages() const noexcept { return _packages; } | ||||
void compile_all(const build_env& env, int njobs) const; | |||||
void archive_all(const build_env& env, int njobs) const; | |||||
void link_all(const build_env& env, int njobs) const; | |||||
/** | |||||
* Compile all files in the plan. | |||||
*/ | |||||
void compile_all(const build_env& env, int njobs) const; | |||||
/** | |||||
* Generate all static library archive in the plan | |||||
*/ | |||||
void archive_all(const build_env& env, int njobs) const; | |||||
/** | |||||
* Link all runtime binaries (executables) in the plan | |||||
*/ | |||||
void link_all(const build_env& env, int njobs) const; | |||||
/** | |||||
* Execute all tests defined in the plan. Returns information for every failed test. | |||||
*/ | |||||
std::vector<test_failure> run_all_tests(build_env_ref env, int njobs) const; | std::vector<test_failure> run_all_tests(build_env_ref env, int njobs) const; | ||||
}; | }; | ||||
namespace dds { | namespace dds { | ||||
/** | |||||
* A package is a top-level component with a name, namespace, and some number of associated | |||||
* libraries. A package plan will roughly correspond to either a source distribution or a project | |||||
* directory | |||||
*/ | |||||
class package_plan { | class package_plan { | ||||
std::string _name; | |||||
std::string _namespace; | |||||
/// Package name | |||||
std::string _name; | |||||
/// The package namespace. Used to specify interdependencies | |||||
std::string _namespace; | |||||
/// The libraries in this package | |||||
std::vector<library_plan> _libraries; | std::vector<library_plan> _libraries; | ||||
public: | public: | ||||
/** | |||||
* Create a new package plan. | |||||
* @param name The name of the package | |||||
* @param namespace_ The namespace of the package. Used when specifying linker dependencies. | |||||
*/ | |||||
package_plan(std::string_view name, std::string_view namespace_) | package_plan(std::string_view name, std::string_view namespace_) | ||||
: _name(name) | : _name(name) | ||||
, _namespace(namespace_) {} | , _namespace(namespace_) {} | ||||
/** | |||||
* Add a library plan to this package plan | |||||
* @param lp The `library_plan` to add to the package. Once added, the | |||||
* library plan cannot be changed directly. | |||||
*/ | |||||
void add_library(library_plan lp) { _libraries.emplace_back(std::move(lp)); } | void add_library(library_plan lp) { _libraries.emplace_back(std::move(lp)); } | ||||
/** | |||||
* Get the package name | |||||
*/ | |||||
auto& name() const noexcept { return _name; } | auto& name() const noexcept { return _name; } | ||||
/** | |||||
* The package namespace | |||||
*/ | |||||
auto& namespace_() const noexcept { return _namespace; } | auto& namespace_() const noexcept { return _namespace; } | ||||
/** | |||||
* The libraries in the package | |||||
*/ | |||||
auto& libraries() const noexcept { return _libraries; } | auto& libraries() const noexcept { return _libraries; } | ||||
}; | }; | ||||