diff options
-rw-r--r-- | tools/minicargo/build.cpp | 24 | ||||
-rw-r--r-- | tools/minicargo/manifest.cpp | 153 | ||||
-rw-r--r-- | tools/minicargo/manifest.h | 10 |
3 files changed, 170 insertions, 17 deletions
diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp index 1ffbf8db..17b738cc 100644 --- a/tools/minicargo/build.cpp +++ b/tools/minicargo/build.cpp @@ -398,8 +398,11 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget& for(const auto& feat : manifest.active_features()) { args.push_back("--cfg"); args.push_back(::format("feature=", feat)); } + // TODO: Environment variables (rustc_env) StringListKV env; + env.push_back("CARGO_MANIFEST_DIR", manifest.directory().to_absolute()); + env.push_back("CARGO_PKG_VERSION", ::format(manifest.version())); return this->spawn_process_mrustc(args, ::std::move(env), outfile + "_dbg.txt"); } @@ -414,7 +417,11 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget& args.push_back("-o"); args.push_back(outfile); args.push_back("-L"); args.push_back(m_output_dir.str().c_str()); - if( this->spawn_process_mrustc(args, {}, outfile + "_dbg.txt") ) + StringListKV env; + env.push_back("CARGO_MANIFEST_DIR", manifest.directory().to_absolute()); + env.push_back("CARGO_PKG_VERSION", ::format(manifest.version())); + + if( this->spawn_process_mrustc(args, ::std::move(env), outfile + "_dbg.txt") ) return outfile; else return ""; @@ -464,6 +471,8 @@ bool Builder::build_library(const PackageManifest& manifest) const // - Run the script and put output in the right dir auto out_file = output_dir_abs / "build_" + manifest.name().c_str() + ".txt"; + auto out_dir = output_dir_abs / "build_" + manifest.name().c_str(); + mkdir(out_dir.str().c_str(), 0755); // TODO: Environment variables (key-value list) StringListKV env; env.push_back("CARGO_MANIFEST_DIR", manifest.directory().to_absolute()); @@ -476,7 +485,7 @@ bool Builder::build_library(const PackageManifest& manifest) const // env.push_back(fn, manifest.m_links); //} //env.push_back("CARGO_CFG_RELEASE", ""); - env.push_back("OUT_DIR", output_dir_abs / "build_" + manifest.name().c_str()); + env.push_back("OUT_DIR", out_dir); env.push_back("TARGET", TARGET); env.push_back("HOST", TARGET); env.push_back("NUM_JOBS", "1"); @@ -505,7 +514,7 @@ bool Builder::build_library(const PackageManifest& manifest) const } bool Builder::spawn_process_mrustc(const StringList& args, StringListKV env, const ::helpers::path& logfile) const { - env.push_back("MRUSTC_DEBUG", ""); + //env.push_back("MRUSTC_DEBUG", ""); return spawn_process(m_compiler_path.str().c_str(), args, env, logfile); } bool Builder::spawn_process(const char* exe_name, const StringList& args, const StringListKV& env, const ::helpers::path& logfile) const @@ -518,6 +527,7 @@ bool Builder::spawn_process(const char* exe_name, const StringList& args, const auto cmdline_str = cmdline.str(); DEBUG("Calling " << cmdline_str); +#if 0 ::std::stringstream environ_str; environ_str << "TEMP=" << getenv("TEMP") << '\0'; environ_str << "TMP=" << getenv("TMP") << '\0'; @@ -526,6 +536,12 @@ bool Builder::spawn_process(const char* exe_name, const StringList& args, const environ_str << kv.first << "=" << kv.second << '\0'; } environ_str << '\0'; +#else + for(auto kv : env) + { + setenv(kv.first, kv.second); + } +#endif CreateDirectory(static_cast<::std::string>(logfile.parent()).c_str(), NULL); @@ -607,7 +623,7 @@ bool Builder::spawn_process(const char* exe_name, const StringList& args, const if( WIFEXITED(status) ) DEBUG("Compiler exited with non-zero exit status " << WEXITSTATUS(status)); else if( WIFSIGNALED(status) ) - DEBUG("Compiler was terminated with signal " << WSTOPSIG(status)); + DEBUG("Compiler was terminated with signal " << WTERMSIG(status)); else DEBUG("Compiler terminated for unknown reason, status=" << status); return false; diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp index 32735732..7b48d1d7 100644 --- a/tools/minicargo/manifest.cpp +++ b/tools/minicargo/manifest.cpp @@ -8,6 +8,16 @@ #include <algorithm> #include "repository.h" + +#ifdef _WIN32 +# define CFG_UNIX false +# define CFG_WINDOWS true +#else +# define TARGET_NAME "x86_64-unknown-linux-gnu" +# define CFG_UNIX true +# define CFG_WINDOWS false +#endif + static ::std::vector<::std::shared_ptr<PackageManifest>> g_loaded_manifests; PackageManifest::PackageManifest() @@ -88,9 +98,19 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) { // Informational only, ignore } + else if( key == "exclude" + || key == "include" + ) + { + // Packaging + } + else if( key == "metadata" ) + { + // Unknown. + } else if( key == "links" ) { - // TODO: Add "-l <thisname>" to command line + // Metadata only } else { @@ -182,9 +202,75 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) //const auto& repo = key_val.path[1]; TODO("Support repository patches"); } + else if( section == "profile" ) + { + // TODO: Various profiles (debug, release, ...) + } else if( section == "target" ) { // TODO: Target opts? + if( key_val.path.size() < 3 ) { + } + const auto& cfg = key_val.path[1]; + const auto& real_section = key_val.path[2]; + // Check if `cfg` currently applies. + // - It can be a target spec, or a cfg(foo) same as rustc + bool success; + if( cfg.substr(0, 4) == "cfg(" ) { + // TODO: Parser? + if( cfg == "cfg(unix)" ) { + success = CFG_UNIX; + } + else if( cfg == "cfg(all(unix, not(target_os = \"macos\")))" ) { + success = CFG_UNIX; + } + else if( cfg == "cfg(all(unix, not(target_os = \"emscripten\"), not(target_os = \"macos\"), not(target_os = \"ios\")))" ) { + success = CFG_UNIX; + } + else if( cfg == "cfg(windows)" ) { + success = CFG_WINDOWS; + } + else if( cfg == "cfg(target_env = \"msvc\")" ) { + success = CFG_WINDOWS; + } + else if( cfg == "cfg(not(windows))" ) { + success = !CFG_WINDOWS; + } + else if( cfg == "cfg(not(stage0))" ) { + success = true; + } + else { + TODO("Target deps - " << cfg); + } + } + else { + // It's a target name + success = (cfg == TARGET_NAME); + } + // If so, parse as if the path was `real_section....` + if( success ) + { + if( real_section == "dependencies" ) + { + assert(key_val.path.size() > 3); + + const auto& depname = key_val.path[3]; + + // Find/create dependency descriptor + auto it = ::std::find_if(rv.m_dependencies.begin(), rv.m_dependencies.end(), [&](const auto& x) { return x.m_name == depname; }); + bool was_added = (it == rv.m_dependencies.end()); + if( was_added ) + { + it = rv.m_dependencies.insert(it, PackageRef{ depname }); + } + + it->fill_from_kv(was_added, key_val, 4); + } + else + { + TODO("Unknown manifest section for target - " << real_section); + } + } } else if( section == "features" ) { @@ -461,8 +547,17 @@ void PackageManifest::set_features(const ::std::vector<::std::string>& features, DEBUG("Activating feature " << featname << " = [" << it->second << "]"); for(const auto& sub_feat : it->second) { - if( sub_feat.find('/') != ::std::string::npos ) { - TODO("Activate dependency feature from '" << sub_feat << "'"); + auto slash_pos = sub_feat.find('/'); + if( slash_pos != ::std::string::npos ) { + ::std::string depname = sub_feat.substr(0, slash_pos); + ::std::string depfeat = sub_feat.substr(slash_pos+1); + DEBUG("Activate feature '" << depfeat << "' from dependency '" << depname << "'"); + auto it2 = ::std::find_if(m_dependencies.begin(), m_dependencies.end(), [&](const auto& x){ return x.m_name == depname; }); + if(it2 != m_dependencies.end()) + { + it2->m_features.push_back(depfeat); + // TODO: Does this need to be set again? + } } else { add_feature(sub_feat); @@ -665,7 +760,7 @@ PackageVersionSpec PackageVersionSpec::from_string(const ::std::string& s) char* out_ptr = nullptr; long rv = ::std::strtol(istr.c_str() + pos, &out_ptr, 10); if( out_ptr == istr.c_str() + pos ) - throw ::std::invalid_argument(istr.c_str() + pos); + throw ::std::invalid_argument(::format("Failed to parse integer from '", istr.c_str() + pos, "'")); pos = out_ptr - istr.c_str(); return rv; } @@ -690,12 +785,30 @@ PackageVersionSpec PackageVersionSpec::from_string(const ::std::string& s) pos ++; break; case '>': - ty = PackageVersionSpec::Bound::Type::Greater; pos ++; + switch(s[pos]) + { + case '=': + pos ++; + ty = PackageVersionSpec::Bound::Type::GreaterEqual; + break; + default: + ty = PackageVersionSpec::Bound::Type::Greater; + break; + } break; case '<': - ty = PackageVersionSpec::Bound::Type::Greater; pos ++; + switch(s[pos]) + { + case '=': + pos ++; + ty = PackageVersionSpec::Bound::Type::LessEqual; + break; + default: + ty = PackageVersionSpec::Bound::Type::Less; + break; + } break; default: break; @@ -703,21 +816,27 @@ PackageVersionSpec PackageVersionSpec::from_string(const ::std::string& s) while( pos < s.size() && isblank(s[pos]) ) pos ++; if( pos == s.size() ) - throw ::std::runtime_error("Bad version string"); + throw ::std::runtime_error("Bad version string - Expected version number"); PackageVersion v; v.major = H::parse_i(s, pos); - if( s[pos] != '.' ) - throw ::std::runtime_error("Bad version string"); - pos ++; - v.minor = H::parse_i(s, pos); - if(s[pos] == '.') + if( s[pos] == '.' ) { pos ++; - v.patch = H::parse_i(s, pos); + v.minor = H::parse_i(s, pos); + if(s[pos] == '.') + { + pos ++; + v.patch = H::parse_i(s, pos); + } + else + { + v.patch = 0; + } } else { + v.minor = 0; v.patch = 0; } @@ -746,6 +865,10 @@ bool PackageVersionSpec::accepts(const PackageVersion& v) const if( !(v < b.ver.next_breaking()) ) return false; break; + case Bound::Type::GreaterEqual: + if( !(v >= b.ver) ) + return false; + break; case Bound::Type::Greater: if( !(v > b.ver) ) return false; @@ -754,6 +877,10 @@ bool PackageVersionSpec::accepts(const PackageVersion& v) const if( v != b.ver ) return false; break; + case Bound::Type::LessEqual: + if( !(v <= b.ver) ) + return false; + break; case Bound::Type::Less: if( !(v < b.ver) ) return false; diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h index 99df7843..be125e2a 100644 --- a/tools/minicargo/manifest.h +++ b/tools/minicargo/manifest.h @@ -52,6 +52,11 @@ struct PackageVersion if( minor != x.minor ) return minor < x.minor; return patch < x.patch; } + bool operator<=(const PackageVersion& x) const { + if( major != x.major ) return major < x.major; + if( minor != x.minor ) return minor < x.minor; + return patch <= x.patch; + } bool operator>(const PackageVersion& x) const { if( major != x.major ) return major > x.major; if( minor != x.minor ) return minor > x.minor; @@ -76,7 +81,9 @@ struct PackageVersionSpec { Compatible, Greater, + GreaterEqual, Equal, + LessEqual, Less, }; @@ -102,7 +109,9 @@ struct PackageVersionSpec { case Bound::Type::Compatible: os << "^"; break; case Bound::Type::Greater: os << ">"; break; + case Bound::Type::GreaterEqual: os << ">="; break; case Bound::Type::Equal: os << "="; break; + case Bound::Type::LessEqual: os << "<="; break; case Bound::Type::Less: os << "<"; break; } os << b.ver; @@ -238,6 +247,7 @@ class PackageManifest public: static PackageManifest load_from_toml(const ::std::string& path); + const PackageVersion& version() const { return m_version; } bool has_library() const; const PackageTarget& get_library() const; |