#include <dds/toolchain.hpp> | #include <dds/toolchain.hpp> | ||||
#include <dds/util/algo.hpp> | #include <dds/util/algo.hpp> | ||||
#include <dds/util/string.hpp> | #include <dds/util/string.hpp> | ||||
#include <dds/util/tl.hpp> | |||||
#include <libman/index.hpp> | #include <libman/index.hpp> | ||||
#include <libman/parse.hpp> | #include <libman/parse.hpp> | ||||
auto all_libs = iter_libraries(project); | auto all_libs = iter_libraries(project); | ||||
extend(pairs, | extend(pairs, | ||||
all_libs // | |||||
| transform(DDS_TL(export_project_library(params, _1, project, export_root))) // | |||||
| transform(DDS_TL(lm::pair("Library", _1.string()))) // | |||||
); | |||||
all_libs // | |||||
| transform([&](auto&& lib) { | |||||
return export_project_library(params, lib, project, export_root); | |||||
}) // | |||||
| transform([](auto&& path) { return lm::pair("Library", path.string()); })); // | |||||
lm::write_pairs(export_root / "package.lmp", pairs); | lm::write_pairs(export_root / "package.lmp", pairs); | ||||
} | } | ||||
return // | return // | ||||
sources // | sources // | ||||
| filter(should_compile_source) // | | filter(should_compile_source) // | ||||
| transform(DDS_TL(file_compilation{rules, | |||||
_1, | |||||
object_file_path(_1.path, params), | |||||
lib.name(), | |||||
params.enable_warnings})) // | |||||
| transform([&](auto&& src) { | |||||
return file_compilation{rules, | |||||
src, | |||||
object_file_path(src.path, params), | |||||
lib.name(), | |||||
params.enable_warnings}; | |||||
}) // | |||||
| to_vector; | | to_vector; | ||||
} | } | ||||
std::vector<dds::file_compilation> collect_compiles(const build_params& params, | std::vector<dds::file_compilation> collect_compiles(const build_params& params, | ||||
const project& project) { | const project& project) { | ||||
auto libs = iter_libraries(project); | auto libs = iter_libraries(project); | ||||
return // | |||||
libs // | |||||
| transform(DDS_TL(file_compilations_of_lib(params, _1))) // | |||||
| ranges::actions::join // | |||||
| to_vector // | |||||
return // | |||||
libs // | |||||
| transform([&](auto&& lib) { return file_compilations_of_lib(params, lib); }) // | |||||
| ranges::actions::join // | |||||
| to_vector // | |||||
; | ; | ||||
} | } | ||||
arc.out_path = lib_archive_path(params, lib); | arc.out_path = lib_archive_path(params, lib); | ||||
// Collect object files that make up that library | // Collect object files that make up that library | ||||
arc.input_files = // | |||||
lib.sources() // | |||||
| filter(DDS_TL(_1.kind == source_kind::source)) // | |||||
| transform(DDS_TL(obj_for_source(obj_idx, _1.path))) // | |||||
| to_vector // | |||||
arc.input_files = // | |||||
lib.sources() // | |||||
| filter([](auto&& s) { return s.kind == source_kind::source; }) // | |||||
| transform([&](auto&& s) { return obj_for_source(obj_idx, s.path); }) // | |||||
| to_vector // | |||||
; | ; | ||||
if (arc.input_files.empty()) { | if (arc.input_files.empty()) { | ||||
const build_params& params, | const build_params& params, | ||||
const library& lib, | const library& lib, | ||||
const object_file_index& obj_idx) { | const object_file_index& obj_idx) { | ||||
return // | |||||
lib.sources() // | |||||
| filter(DDS_TL(_1.kind == sk)) // | |||||
| transform(DDS_TL(link_one_exe(get_exe_path(_1), _1.path, params, lib, obj_idx))) // | |||||
| to_vector // | |||||
return // | |||||
lib.sources() // | |||||
| filter([&](auto&& s) { return s.kind == sk; }) // | |||||
| transform([&](auto&& s) { | |||||
return link_one_exe(get_exe_path(s), s.path, params, lib, obj_idx); | |||||
}) // | |||||
| to_vector // | |||||
; | ; | ||||
} | } | ||||
std::vector<link_results> link_project(const build_params& params, | std::vector<link_results> link_project(const build_params& params, | ||||
const project& pr, | const project& pr, | ||||
const std::vector<file_compilation>& compilations) { | const std::vector<file_compilation>& compilations) { | ||||
auto obj_index = // | |||||
compilations // | |||||
| transform(DDS_TL(std::pair(_1.source.path, _1.obj))) // | |||||
| to<object_file_index> // | |||||
auto obj_index = // | |||||
ranges::views::all(compilations) // | |||||
| transform([](auto&& comp) { return std::pair(comp.source.path, comp.obj); }) // | |||||
| ranges::to<object_file_index>() // | |||||
; | ; | ||||
auto libs = iter_libraries(pr); | auto libs = iter_libraries(pr); | ||||
return libs // | |||||
| transform(DDS_TL(link_project_lib(params, _1, obj_index))) // | |||||
return libs // | |||||
| transform([&](auto&& lib) { return link_project_lib(params, lib, obj_index); }) // | |||||
| to_vector; | | to_vector; | ||||
} | } | ||||
auto link_res = link_project(params, project, compiles); | auto link_res = link_project(params, project, compiles); | ||||
auto all_tests = link_res // | |||||
| transform(DDS_TL(_1.test_exes)) // | |||||
auto all_tests = link_res // | |||||
| transform([](auto&& link) { return link.test_exes; }) // | |||||
| ranges::actions::join; | | ranges::actions::join; | ||||
int n_test_fails = 0; | int n_test_fails = 0; |
std::string owner_name; | std::string owner_name; | ||||
bool enable_warnings = false; | bool enable_warnings = false; | ||||
file_compilation(compilation_rules rules, | |||||
source_file sf, | |||||
path_ref obj, | |||||
std::string owner, | |||||
bool); | |||||
void compile(const toolchain& tc) const; | void compile(const toolchain& tc) const; | ||||
}; | }; | ||||
#include <dds/project.hpp> | #include <dds/project.hpp> | ||||
#include <dds/source.hpp> | #include <dds/source.hpp> | ||||
#include <dds/util/tl.hpp> | |||||
#include <range/v3/range/conversion.hpp> | #include <range/v3/range/conversion.hpp> | ||||
#include <range/v3/view/filter.hpp> | #include <range/v3/view/filter.hpp> | ||||
return {}; | return {}; | ||||
} | } | ||||
using namespace ranges::views; | using namespace ranges::views; | ||||
return fs::directory_iterator(pf_libs_dir) // | |||||
| filter(has_library_dirs) // | |||||
| transform(DDS_TL(library::from_directory(_1))) // | |||||
return fs::directory_iterator(pf_libs_dir) // | |||||
| filter(has_library_dirs) // | |||||
| transform([](auto&& entry) { return library::from_directory(entry); }) // | |||||
| ranges::to_vector; | | ranges::to_vector; | ||||
} | } | ||||
#include <dds/project.hpp> | #include <dds/project.hpp> | ||||
#include <dds/temp.hpp> | #include <dds/temp.hpp> | ||||
#include <dds/util/fs.hpp> | #include <dds/util/fs.hpp> | ||||
#include <dds/util/tl.hpp> | |||||
#include <libman/parse.hpp> | #include <libman/parse.hpp> | ||||
}) // | }) // | ||||
| ranges::to_vector; | | ranges::to_vector; | ||||
ranges::sort(sources_to_keep, std::less<>(), DDS_TL(_1.path)); | |||||
ranges::sort(sources_to_keep, std::less<>(), [](auto&& s) { return s.path; }); | |||||
auto lib_dds_path = lib.base_dir() / "library.dds"; | auto lib_dds_path = lib.base_dir() / "library.dds"; | ||||
if (fs::is_regular_file(lib_dds_path)) { | if (fs::is_regular_file(lib_dds_path)) { |
#include "./source.hpp" | #include "./source.hpp" | ||||
#include <dds/util/tl.hpp> | |||||
#include <dds/util/string.hpp> | #include <dds/util/string.hpp> | ||||
#include <spdlog/spdlog.h> | #include <spdlog/spdlog.h> | ||||
source_list source_file::collect_for_dir(path_ref src) { | source_list source_file::collect_for_dir(path_ref src) { | ||||
using namespace ranges::views; | using namespace ranges::views; | ||||
// Strips nullopt elements and lifts the value from the results | // Strips nullopt elements and lifts the value from the results | ||||
auto drop_nulls = // | |||||
filter(DDS_TL(_1.has_value())) // | |||||
| transform(DDS_TL(*_1)); | |||||
auto drop_nulls = // | |||||
filter([](auto&& opt) { return opt.has_value(); }) // | |||||
| transform([](auto&& opt) { return *opt; }); // | |||||
// Collect all source files from the directory | // Collect all source files from the directory | ||||
return // | |||||
fs::recursive_directory_iterator(src) // | |||||
| filter(DDS_TL(_1.is_regular_file())) // | |||||
| transform(DDS_TL(source_file::from_path(_1))) // | |||||
return // | |||||
fs::recursive_directory_iterator(src) // | |||||
| filter([](auto&& entry) { return entry.is_regular_file(); }) // | |||||
| transform([](auto&& entry) { return source_file::from_path(entry); }) // | |||||
// source_file::from_path returns an optional. Drop nulls | // source_file::from_path returns an optional. Drop nulls | ||||
| drop_nulls // | | drop_nulls // | ||||
| ranges::to_vector; | | ranges::to_vector; |
#pragma once | |||||
#include <cstddef> | |||||
namespace dds { | |||||
namespace detail { | |||||
template <std::size_t I, | |||||
typename A = std::nullptr_t, | |||||
typename B = std::nullptr_t, | |||||
typename C = std::nullptr_t, | |||||
typename D = std::nullptr_t> | |||||
decltype(auto) nth_arg(A&& a[[maybe_unused]] = nullptr, | |||||
B&& b[[maybe_unused]] = nullptr, | |||||
C&& c[[maybe_unused]] = nullptr, | |||||
D&& d[[maybe_unused]] = nullptr) { | |||||
if constexpr (I == 0) { | |||||
return (A &&) a; | |||||
} else if constexpr (I == 1) { | |||||
return (B &&) b; | |||||
} else if constexpr (I == 2) { | |||||
return (C &&) c; | |||||
} else if constexpr (I == 3) { | |||||
return (D &&) d; | |||||
} | |||||
} | |||||
} // namespace detail | |||||
// Based on https://github.com/Quincunx271/TerseLambda | |||||
#define DDS_CTL(...) \ | |||||
(auto&&... tl_args)->auto { \ | |||||
[[maybe_unused]] auto&& _1 = ::dds::detail::nth_arg<0, decltype(tl_args)...>( \ | |||||
static_cast<decltype(tl_args)&&>(tl_args)...); \ | |||||
[[maybe_unused]] auto&& _2 = ::dds::detail::nth_arg<1, decltype(tl_args)...>( \ | |||||
static_cast<decltype(tl_args)&&>(tl_args)...); \ | |||||
[[maybe_unused]] auto&& _3 = ::dds::detail::nth_arg<2, decltype(tl_args)...>( \ | |||||
static_cast<decltype(tl_args)&&>(tl_args)...); \ | |||||
[[maybe_unused]] auto&& _4 = ::dds::detail::nth_arg<3, decltype(tl_args)...>( \ | |||||
static_cast<decltype(tl_args)&&>(tl_args)...); \ | |||||
static_assert(sizeof...(tl_args) <= 4); \ | |||||
return (__VA_ARGS__); \ | |||||
} | |||||
#define DDS_TL [&] DDS_CTL | |||||
} // namespace dds |