diff --git a/src/main.cpp b/src/main.cpp index d0a9165..d43e4d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -173,6 +173,9 @@ void add_tasks() add_task(); add_task(); add_task(); + + add_task("cmake_common"); + add_task("modorganizer-uibase"); } int run(int argc, char** argv) diff --git a/src/tasks/boost.cpp b/src/tasks/boost.cpp index b0d0f97..cf5af2a 100644 --- a/src/tasks/boost.cpp +++ b/src/tasks/boost.cpp @@ -14,6 +14,19 @@ fs::path boost::source_path() return paths::build() / ("boost_" + boost_version_no_tags_underscores()); } +fs::path boost::lib_path(arch a) +{ + return root_lib_path(a) / "lib"; +} + +fs::path boost::root_lib_path(arch a) +{ + const std::string lib = + "lib" + address_model_for_arch(a) + "-msvc-" + versions::boost_vs(); + + return source_path() / lib; +} + void boost::do_fetch() { //if (prebuilt::boost()) @@ -33,8 +46,8 @@ void boost::do_build_and_install() void boost::do_clean_for_rebuild() { op::delete_directory(cx(), source_path() / "bin.v2", op::optional); - op::delete_directory(cx(), lib_path(arch::x86), op::optional); - op::delete_directory(cx(), lib_path(arch::x64), op::optional); + op::delete_directory(cx(), root_lib_path(arch::x86), op::optional); + op::delete_directory(cx(), root_lib_path(arch::x64), op::optional); op::delete_file(cx(), config_jam_file(), op::optional); op::delete_file(cx(), b2_exe(), op::optional); op::delete_file(cx(), source_path() / "project-config.jam", op::optional); @@ -52,7 +65,7 @@ void boost::fetch_prebuilt() void boost::build_and_install_prebuilt() { op::copy_file_to_dir_if_better(cx(), - lib_path(arch::x64) / "lib" / python_dll(), + lib_path(arch::x64) / python_dll(), paths::install_bin()); } @@ -98,11 +111,11 @@ void boost::build_and_install_from_source() "static", "static", arch::x86); do_b2( - {"python"}, + {"thread", "python"}, "shared", "shared", arch::x64); op::copy_file_to_dir_if_better(cx(), - lib_path(arch::x64) / "lib" / python_dll(), + lib_path(arch::x64) / python_dll(), paths::install_bin()); } @@ -117,8 +130,8 @@ void boost::do_b2( .arg("runtime-link=", runtime_link) .arg("toolset=", "msvc-" + versions::vs_toolset()) .arg("--user-config=", config_jam_file()) - .arg("--stagedir=", lib_path(a)) - .arg("--libdir=", lib_path(a)) + .arg("--stagedir=", root_lib_path(a)) + .arg("--libdir=", root_lib_path(a)) .args(map(components, [](auto&& c) { return "--with-" + c; })) .env(env::vs(a)) .cwd(source_path()))); @@ -191,14 +204,6 @@ url boost::source_url() boost_version_all_underscores() + ".zip"; } -fs::path boost::lib_path(arch a) -{ - const std::string lib = - "lib" + address_model_for_arch(a) + "-msvc-" + versions::boost_vs(); - - return source_path() / lib; -} - fs::path boost::b2_exe() { return source_path() / "b2.exe"; diff --git a/src/tasks/fmt.cpp b/src/tasks/fmt.cpp index 7d318ed..1753878 100644 --- a/src/tasks/fmt.cpp +++ b/src/tasks/fmt.cpp @@ -33,8 +33,8 @@ void fmt::do_build_and_install() const auto build_path = run_tool(cmake() .generator(cmake::jom) .root(source_path()) - .def("FMT_TEST=OFF") - .def("FMT_DOC=OFF")); + .def("FMT_TEST", "OFF") + .def("FMT_DOC", "OFF")); run_tool(jom().path(build_path)); } diff --git a/src/tasks/gtest.cpp b/src/tasks/gtest.cpp index 89a2878..7d0aa0d 100644 --- a/src/tasks/gtest.cpp +++ b/src/tasks/gtest.cpp @@ -5,7 +5,7 @@ namespace mob { gtest::gtest() - : basic_task({"gtest", "googletest"}) + : basic_task("gtest", "googletest") { } diff --git a/src/tasks/lz4.cpp b/src/tasks/lz4.cpp index 0ffc3a7..fe1b7a1 100644 --- a/src/tasks/lz4.cpp +++ b/src/tasks/lz4.cpp @@ -35,6 +35,11 @@ void lz4::do_build_and_install() .solution(solution_file()) .projects({"liblz4-dll"})); + op::copy_glob_to_dir_if_better(cx(), + out_dir() / "*", + source_path() / "bin", + op::copy_files); + op::copy_file_to_dir_if_better(cx(), out_dir() / "liblz4.dll", paths::install_dlls()); diff --git a/src/tasks/modorganizer.cpp b/src/tasks/modorganizer.cpp new file mode 100644 index 0000000..36bb22f --- /dev/null +++ b/src/tasks/modorganizer.cpp @@ -0,0 +1,149 @@ +#include "pch.h" +#include "tasks.h" + +namespace mob +{ + +static std::mutex g_super_mutex; +static std::atomic g_super_initialized = false; + +modorganizer::modorganizer(std::string long_name) + : basic_task(long_name) +{ + auto s = short_name(); + if (s != name()) + add_name(s); +} + +fs::path modorganizer::source_path() +{ + return {}; +} + +fs::path modorganizer::this_source_path() const +{ + return super_path() / short_name(); +} + +fs::path modorganizer::super_path() +{ + return paths::build() / "modorganizer_super"; +} + +void modorganizer::do_fetch() +{ + initialize_super(super_path()); + + if (fs::exists(this_source_path() / ".git")) + { + run_tool(git_clone() + .url(make_github_url(conf::mo_org(), name())) + .branch(conf::mo_branch()) + .output(this_source_path())); + } + else + { + run_tool(process_runner(process() + .binary(tools::git()) + .arg("-c", "core.autocrlf=false") + .arg("submodule") + .arg("--quiet") + .arg("add") + .arg("-b", conf::mo_branch()) + .arg("--force") + .arg("--name", short_name()) + .arg(make_github_url(conf::mo_org(), name())) + .arg(short_name()) + .cwd(super_path()))); + } +} + +void modorganizer::do_build_and_install() +{ + if (!fs::exists(this_source_path() / "CMakeLists.txt")) + { + cx().trace(context::generic, + name() + " has no CMakeLists.txt, not running cmake"); + + return; + } + + const auto build_path = run_tool(cmake() + .generator(cmake::vs) + .def("CMAKE_INSTALL_PREFIX:PATH", paths::install()) + .def("DEPENDENCIES_DIR", paths::build()) + .def("BOOST_ROOT", boost::source_path()) + .def("Boost_LIBRARY_DIRS", boost::lib_path(arch::x64)) + .def("BOOST_LIBRARYDIR", boost::lib_path(arch::x64)) + .def("FMT_ROOT", fmt::source_path()) + .def("SPDLOG_ROOT", spdlog::source_path()) + .def("LOOT_PATH", libloot::source_path()) + .def("LZ4_ROOT", lz4::source_path()) + .def("QT_ROOT", paths::qt_install()) + .def("ZLIB_ROOT", zlib::source_path()) + .def("PYTHON_ROOT", python::source_path()) + .def("SEVENZ_ROOT", sevenz::source_path()) + .def("LIBBSARCH_ROOT", libbsarch::source_path()) + .root(this_source_path())); + + // run the project file instead of the .sln and giving INSTALL as a + // target, because the target name depends on the folders in the solution + // + // since cmake can put INSTALL inside CMakePredefinedTarget, the target has + // to be "CMakePredefinedTarget\\INSTALL" instead of just "INSTALL" + // + // because the creation of the CMakePredefinedTarget actually depends on + // the USE_FOLDERS variable in the cmake file, just use the project + // instead + run_tool(msbuild() + .solution(build_path / ("INSTALL.vcxproj")) + .config("RelWithDebInfo") + .architecture(arch::x64)); +} + +void modorganizer::initialize_super(const fs::path& super_root) +{ + std::scoped_lock lock(g_super_mutex); + if (g_super_initialized) + return; + + g_super_initialized = true; + + cx().trace(context::generic, "checking super"); + + auto p = process() + .binary(tools::git()) + .arg("rev-parse") + .arg("--is-inside-work-tree") + .stderr_filter([](process::filter& f) + { + if (f.line.find("not a git repo") != std::string::npos) + f.lv = context::level::trace; + }) + .flags(process::allow_failure) + .cwd(super_root); + + if (run_tool(process_runner(p)) == 0) + { + cx().debug(context::generic, "super already initialized"); + return; + } + + cx().trace(context::generic, "initializing super"); + + run_tool(process_runner(process() + .binary(tools::git()) + .arg("init") + .cwd(super_root))); +} + +std::string modorganizer::short_name() const +{ + const auto dash = name().find("-"); + if (dash == std::string::npos) + return name(); + + return name().substr(dash + 1); +} + +} // namespace diff --git a/src/tasks/sevenz.cpp b/src/tasks/sevenz.cpp index 6591d2c..d0dc54e 100644 --- a/src/tasks/sevenz.cpp +++ b/src/tasks/sevenz.cpp @@ -5,7 +5,7 @@ namespace mob { sevenz::sevenz() - : basic_task({"7z", "sevenz"}) + : basic_task("7z", "sevenz") { } diff --git a/src/tasks/stylesheets.cpp b/src/tasks/stylesheets.cpp index 60a4925..4c27dc5 100644 --- a/src/tasks/stylesheets.cpp +++ b/src/tasks/stylesheets.cpp @@ -5,7 +5,7 @@ namespace mob { stylesheets::stylesheets() - : basic_task({"ss", "stylesheets"}) + : basic_task("ss", "stylesheets") { } diff --git a/src/tasks/task.cpp b/src/tasks/task.cpp index 15a65ad..a0bd2c3 100644 --- a/src/tasks/task.cpp +++ b/src/tasks/task.cpp @@ -84,11 +84,6 @@ void run_all_tasks() } -task::task(const char* name) - : task(std::vector{name}) -{ -} - task::task(std::vector names) : names_(std::move(names)), interrupted_(false) { @@ -125,6 +120,11 @@ const context& task::cx() const return bad; } +void task::add_name(std::string s) +{ + names_.push_back(s); +} + void task::interrupt_all() { std::scoped_lock lock(interrupt_mutex_); diff --git a/src/tasks/task.h b/src/tasks/task.h index 5d1f370..8ea3821 100644 --- a/src/tasks/task.h +++ b/src/tasks/task.h @@ -10,10 +10,10 @@ class task; void add_task(std::unique_ptr t); -template -void add_task() +template +void add_task(Args&&... args) { - add_task(std::make_unique()); + add_task(std::make_unique(std::forward(args)...)); } void run_task(const std::string& name); @@ -45,10 +45,16 @@ public: void build_and_install(); protected: - task(const char* name); + template + task(std::string name, Names&&... names) + : task(std::vector{name, std::forward(names)...}) + { + } + task(std::vector names); const context& cx() const; + void add_name(std::string s); void check_interrupted(); diff --git a/src/tasks/tasks.h b/src/tasks/tasks.h index d6351fd..a64093f 100644 --- a/src/tasks/tasks.h +++ b/src/tasks/tasks.h @@ -14,7 +14,10 @@ class boost : public basic_task { public: boost(); + static fs::path source_path(); + static fs::path lib_path(arch a); + static fs::path root_lib_path(arch a); protected: void do_fetch() override; @@ -40,7 +43,6 @@ private: static fs::path config_jam_file(); static url prebuilt_url(); static url source_url(); - static fs::path lib_path(arch a); static fs::path b2_exe(); static std::string python_dll(); static std::string python_version_for_dll(); @@ -171,6 +173,26 @@ private: }; +class modorganizer : public basic_task +{ +public: + modorganizer(std::string name); + static fs::path source_path(); + +protected: + void do_fetch() override; + void do_build_and_install() override; + +private: + void initialize_super(const fs::path& super_root); + + std::string short_name() const; + fs::path this_source_path() const; + + static fs::path super_path(); +}; + + class ncc : public basic_task { public: diff --git a/src/tools/cmake.cpp b/src/tools/cmake.cpp index c69ece5..4adc7c2 100644 --- a/src/tools/cmake.cpp +++ b/src/tools/cmake.cpp @@ -29,9 +29,21 @@ cmake& cmake::prefix(const fs::path& s) return *this; } -cmake& cmake::def(const std::string& s) +cmake& cmake::def(const std::string& name, const std::string& value) { - process_.arg("-D" + s); + process_.arg("-D" + name + "=" + value + ""); + return *this; +} + +cmake& cmake::def(const std::string& name, const fs::path& p) +{ + def(name, p.string()); + return *this; +} + +cmake& cmake::def(const std::string& name, const char* s) +{ + def(name, std::string(s)); return *this; } @@ -62,6 +74,9 @@ void cmake::clean(const context& cx, const fs::path& root) void cmake::do_run() { + if (root_.empty()) + cx_->bail_out(context::generic, "cmake output path is empty"); + const auto& g = get_generator(gen_); output_ = root_ / (g.output_dir(arch_)); @@ -128,7 +143,7 @@ std::string cmake::gen_info::get_arch(arch a) const if (x64.empty()) return {}; else - return "-A" + x64; + return "-A " + x64; } case arch::dont_care: diff --git a/src/tools/process_runner.cpp b/src/tools/process_runner.cpp index 91026e8..f981cf5 100644 --- a/src/tools/process_runner.cpp +++ b/src/tools/process_runner.cpp @@ -39,14 +39,14 @@ int basic_process_runner::exit_code() const } -process_runner::process_runner(process p) +process_runner::process_runner(process&& p) + : tool(p.name()), own_(std::move(p)), p_(nullptr) { - process_ = std::move(p); } -int process_runner::result() const +process_runner::process_runner(process& p) + : tool(p.name()), p_(&p) { - return exit_code(); } void process_runner::do_run() @@ -54,4 +54,55 @@ void process_runner::do_run() execute_and_join(); } +int process_runner::result() const +{ + return exit_code(); +} + +std::string process_runner::do_name() const +{ + return real_process().name(); +} + +void process_runner::do_interrupt() +{ + real_process().interrupt(); +} + +int process_runner::execute_and_join() +{ + real_process().set_context(cx_); + real_process().run(); + + join(); + + return real_process().exit_code(); +} + +void process_runner::join() +{ + real_process().join(); +} + +int process_runner::exit_code() const +{ + return real_process().exit_code(); +} + +process& process_runner::real_process() +{ + if (p_) + return *p_; + else + return own_; +} + +const process& process_runner::real_process() const +{ + if (p_) + return *p_; + else + return own_; +} + } // namespace diff --git a/src/tools/tools.h b/src/tools/tools.h index fe90f81..489a0a2 100644 --- a/src/tools/tools.h +++ b/src/tools/tools.h @@ -84,15 +84,30 @@ protected: }; -class process_runner : public basic_process_runner +class process_runner : public tool { public: - process_runner(process p); + process_runner(process&& p); + process_runner(process& p); + + std::string do_name() const override; + void join(); + int exit_code() const; int result() const; protected: void do_run() override; + +private: + process own_; + process* p_; + + void do_interrupt() override; + int execute_and_join(); + + process& real_process(); + const process& real_process() const; }; @@ -176,7 +191,9 @@ public: cmake& generator(generators g); cmake& root(const fs::path& p); cmake& prefix(const fs::path& s); - cmake& def(const std::string& s); + cmake& def(const std::string& name, const std::string& value); + cmake& def(const std::string& name, const fs::path& p); + cmake& def(const std::string& name, const char* s); cmake& architecture(arch a); fs::path result() const; diff --git a/vs/mob.vcxproj b/vs/mob.vcxproj index c90ed1b..6f4d2f6 100644 --- a/vs/mob.vcxproj +++ b/vs/mob.vcxproj @@ -97,6 +97,7 @@ + diff --git a/vs/mob.vcxproj.filters b/vs/mob.vcxproj.filters index d6a9f4d..b4b7418 100644 --- a/vs/mob.vcxproj.filters +++ b/vs/mob.vcxproj.filters @@ -129,6 +129,9 @@ src\tasks + + src\tasks +