| #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 |