diff options
-rw-r--r-- | tools/minicargo/build.cpp | 111 | ||||
-rw-r--r-- | tools/minicargo/helpers.h | 12 | ||||
-rw-r--r-- | tools/minicargo/manifest.cpp | 71 | ||||
-rw-r--r-- | tools/minicargo/manifest.h | 12 |
4 files changed, 148 insertions, 58 deletions
diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp index 1d9b30ba..ace0dd13 100644 --- a/tools/minicargo/build.cpp +++ b/tools/minicargo/build.cpp @@ -1,8 +1,14 @@ /* */ #include "manifest.h" +#include "debug.h" #include <vector> #include <algorithm> +#include <sstream> // stringstream +#include "helpers.h" // path +#ifdef _WIN32 +#include <Windows.h> +#endif struct BuildList { @@ -41,6 +47,41 @@ struct BuildList } }; +class Builder +{ + class StringList + { + ::std::vector<::std::string> m_cached; + ::std::vector<const char*> m_strings; + public: + StringList() + { + } + + const ::std::vector<const char*>& get_vec() const + { + return m_strings; + } + + void push_back(::std::string s) + { + m_cached.push_back(::std::move(s)); + m_strings.push_back(m_cached.back().c_str()); + } + void push_back(const char* s) + { + m_strings.push_back(s); + } + }; + +public: + bool build_target(const PackageManifest& manifest, const PackageTarget& target) const; + bool build_library(const PackageManifest& manifest) const; + +private: + bool spawn_process(const StringList& args, const ::helpers::path& logfile) const; +}; + void MiniCargo_Build(const PackageManifest& manifest) { BuildList list; @@ -52,15 +93,17 @@ void MiniCargo_Build(const PackageManifest& manifest) // Build dependencies + Builder builder; for(const auto& p : list.iter()) { - if( ! p.build_lib() ) - return ; + if( ! builder.build_library(p) ) + { + return; + } } - if( ! manifest.build_lib() ) - return ; // TODO: If the manifest doesn't have a library, build the binary + builder.build_library(manifest); } void BuildList::add_package(const PackageManifest& p, unsigned level) @@ -83,3 +126,63 @@ void BuildList::sort_list() { ::std::sort(m_list.begin(), m_list.end(), [](const auto& a, const auto& b){ return a.level < b.level; }); } + +bool Builder::build_target(const PackageManifest& manifest, const PackageTarget& target) const +{ + auto outfile = ::helpers::path("output") / ::format("lib", target.m_name, ".hir"); + + StringList args; + args.push_back(::helpers::path(manifest.manifest_path()).parent() / ::helpers::path(target.m_path)); + args.push_back("--crate-name"); args.push_back(target.m_name.c_str()); + args.push_back("--crate-type"); args.push_back("rlib"); + args.push_back("-o"); args.push_back(outfile); + + return this->spawn_process(args, outfile + "_dbg.txt"); +} +bool Builder::build_library(const PackageManifest& manifest) const +{ + return this->build_target(manifest, manifest.get_library()); +} +bool Builder::spawn_process(const StringList& args, const ::helpers::path& logfile) const +{ +#ifdef _WIN32 + ::std::stringstream cmdline; + cmdline << "mrustc.exe"; + for (const auto& arg : args.get_vec()) + cmdline << " " << arg; + auto cmdline_str = cmdline.str(); + DEBUG("Calling " << cmdline_str); + + CreateDirectory(static_cast<::std::string>(logfile.parent()).c_str(), NULL); + + STARTUPINFO si = { 0 }; + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = NULL; + si.hStdError = GetStdHandle(STD_ERROR_HANDLE); + { + SECURITY_ATTRIBUTES sa = { 0 }; + sa.nLength = sizeof(sa); + sa.bInheritHandle = TRUE; + si.hStdOutput = CreateFile( static_cast<::std::string>(logfile).c_str(), GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + DWORD tmp; + WriteFile(si.hStdOutput, cmdline_str.data(), cmdline_str.size(), &tmp, NULL); + WriteFile(si.hStdOutput, "\n", 1, &tmp, NULL); + } + PROCESS_INFORMATION pi = { 0 }; + CreateProcessA("x64\\Release\\mrustc.exe", (LPSTR)cmdline_str.c_str(), NULL, NULL, TRUE, 0, "MRUSTC_DEBUG=\0", NULL, &si, &pi); + CloseHandle(si.hStdOutput); + WaitForSingleObject(pi.hProcess, INFINITE); + DWORD status = 1; + GetExitCodeProcess(pi.hProcess, &status); + if (status != 0) + { + DEBUG("Compiler exited with non-zero exit status " << status); + return false; + } +#else + // TODO: posix_spawn + return false; +#endif + return true; +} diff --git a/tools/minicargo/helpers.h b/tools/minicargo/helpers.h index d811f21a..d9fe7e3c 100644 --- a/tools/minicargo/helpers.h +++ b/tools/minicargo/helpers.h @@ -56,13 +56,25 @@ public: throw ::std::runtime_error("Appending an absolute path to another path"); return *this / p.m_str.c_str(); } + /// Append a relative path path operator/(const char* o) const { + if (o[0] == '/') + throw ::std::runtime_error("Appending an absolute path to another path"); auto rv = *this; rv.m_str.push_back(SEP); rv.m_str.append(o); return rv; } + /// Add an arbitary string to the final component + path operator+(const char* o) const + { + if( ::std::strchr(o, SEP) != nullptr ) + throw ::std::runtime_error("Appending a string containing the path separator (with operator+)"); + auto rv = *this; + rv.m_str.append(o); + return rv; + } path parent() const { diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp index 22b63005..90bb68a5 100644 --- a/tools/minicargo/manifest.cpp +++ b/tools/minicargo/manifest.cpp @@ -25,7 +25,7 @@ namespace PackageManifest PackageManifest::load_from_toml(const ::std::string& path) { PackageManifest rv; - rv.m_manmifest_path = path; + rv.m_manifest_path = path; TomlFile toml_file(path); @@ -40,6 +40,7 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) if(key == "authors") { // TODO: Use the `authors` key + // - Ignore ofr now. } else if( key == "name" ) { @@ -67,12 +68,12 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) } else if( section == "lib" ) { - // TODO: Parse information related to use as a library // 1. Find (and add if needed) the `lib` descriptor auto it = ::std::find_if(rv.m_targets.begin(), rv.m_targets.end(), [](const auto& x){ return x.m_type == PackageTarget::Type::Lib; }); if(it == rv.m_targets.end()) it = rv.m_targets.insert(it, PackageTarget { PackageTarget::Type::Lib }); + // 2. Parse from the key-value pair target_edit_from_kv(*it, key_val, 1); } else if( section == "bin" ) @@ -97,6 +98,17 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) target_edit_from_kv(*it, key_val, 2); } + else if (section == "bench") + { + assert(key_val.path.size() > 1); + unsigned idx = ::std::stoi(key_val.path[1]); + + auto it = ::std::find_if(rv.m_targets.begin(), rv.m_targets.end(), [&idx](const auto& x) { return x.m_type == PackageTarget::Type::Bench && idx-- == 0; }); + if (it == rv.m_targets.end()) + it = rv.m_targets.insert(it, PackageTarget{ PackageTarget::Type::Bench }); + + target_edit_from_kv(*it, key_val, 2); + } else if( section == "dependencies" ) { assert(key_val.path.size() > 1); @@ -159,10 +171,12 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) else if( section == "patch" ) { //const auto& repo = key_val.path[1]; + TODO("Support repository patches"); } else { // Unknown manifest section + TODO("Unknown manifest section " << section); } } @@ -226,66 +240,19 @@ namespace } } - -bool PackageManifest::build_lib() const +const PackageTarget& PackageManifest::get_library() const { auto it = ::std::find_if(m_targets.begin(), m_targets.end(), [](const auto& x) { return x.m_type == PackageTarget::Type::Lib; }); if (it == m_targets.end()) { throw ::std::runtime_error(::format("Package ", m_name, " doesn't have a library")); } - - auto outfile = ::helpers::path("output") / ::format("lib", it->m_name, ".hir"); - - ::std::vector<::std::string> args; - args.push_back( ::helpers::path(m_manmifest_path).parent() / ::helpers::path(it->m_path) ); - args.push_back("--crate-name"); args.push_back(it->m_name); - args.push_back("--crate-type"); args.push_back("rlib"); - args.push_back("-o"); args.push_back( ::helpers::path("output") / ::format("lib", it->m_name, ".hir") ); -#ifdef _WIN32 - ::std::stringstream cmdline; - cmdline << "mrustc.exe"; - for(const auto& arg : args) - cmdline << " " << arg; - auto cmdline_str = cmdline.str(); - DEBUG("Calling " << cmdline_str); - - CreateDirectory(static_cast<::std::string>(outfile.parent()).c_str(), NULL); - - STARTUPINFO si = {0}; - si.cb = sizeof(si); - si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = NULL; - si.hStdError = GetStdHandle(STD_ERROR_HANDLE); - { - SECURITY_ATTRIBUTES sa = {0}; - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - si.hStdOutput = CreateFile( (static_cast<::std::string>(outfile) + "_dbg.txt").c_str(), GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - DWORD tmp; - WriteFile(si.hStdOutput, cmdline_str.data(), cmdline_str.size(), &tmp, NULL); - WriteFile(si.hStdOutput, "\n", 1, &tmp, NULL); - } - PROCESS_INFORMATION pi = {0}; - CreateProcessA("x64\\Release\\mrustc.exe", (LPSTR)cmdline_str.c_str(), NULL, NULL, TRUE, CREATE_NO_WINDOW, "MRUSTC_DEBUG=Parse\0", NULL, &si, &pi); - CloseHandle(si.hStdOutput); - WaitForSingleObject(pi.hProcess, INFINITE); - DWORD status = 1; - GetExitCodeProcess(pi.hProcess, &status); - if(status != 0) - { - DEBUG("Compiler exited with non-zero exit status " << status); - return false; - } -#elif defined(__posix__) - //spawn(); -#else -#endif - return true; + return *it; } const PackageManifest& PackageRef::get_package() const { + DEBUG("TODO: PackageRef::get_package()"); throw ""; } diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h index 108a8d2b..054347fb 100644 --- a/tools/minicargo/manifest.h +++ b/tools/minicargo/manifest.h @@ -93,7 +93,7 @@ struct PackageTarget class PackageManifest { - ::std::string m_manmifest_path; + ::std::string m_manifest_path; ::std::string m_name; PackageVersion m_version; @@ -109,8 +109,16 @@ class PackageManifest PackageManifest(); public: static PackageManifest load_from_toml(const ::std::string& path); - bool build_lib() const; + const PackageTarget& get_library() const; + + + const ::std::string& manifest_path() const { + return m_manifest_path; + } + const ::std::string& name() const { + return m_name; + } const ::std::vector<PackageRef>& dependencies() const { return m_dependencies; } |