diff options
Diffstat (limited to 'tools/minicargo')
-rw-r--r-- | tools/minicargo/build.cpp | 48 | ||||
-rw-r--r-- | tools/minicargo/build.h | 10 | ||||
-rw-r--r-- | tools/minicargo/main.cpp | 13 | ||||
-rw-r--r-- | tools/minicargo/manifest.cpp | 79 | ||||
-rw-r--r-- | tools/minicargo/manifest.h | 13 | ||||
-rw-r--r-- | tools/minicargo/repository.cpp | 3 |
6 files changed, 125 insertions, 41 deletions
diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp index 145a1c1e..64558103 100644 --- a/tools/minicargo/build.cpp +++ b/tools/minicargo/build.cpp @@ -63,13 +63,13 @@ extern int _putenv_s(const char*, const char*); /// Class abstracting access to the compiler class Builder { - BuildOptions m_opts; + const BuildOptions& m_opts; ::helpers::path m_compiler_path; size_t m_total_targets; mutable size_t m_targets_built; public: - Builder(BuildOptions opts, size_t total_targets); + Builder(const BuildOptions& opts, size_t total_targets); bool build_target(const PackageManifest& manifest, const PackageTarget& target, bool is_for_host, size_t index) const; bool build_library(const PackageManifest& manifest, bool is_for_host, size_t index) const; @@ -218,6 +218,18 @@ BuildList::BuildList(const PackageManifest& manifest, const BuildOptions& opts): { b.m_list.push_back({ &manifest, !cross_compiling, 0 }); } + if( opts.mode != BuildOptions::Mode::Normal) + { + for(const auto& dep : manifest.dev_dependencies()) + { + if( dep.is_disabled() ) + { + continue ; + } + DEBUG(manifest.name() << ": Dependency " << dep.name()); + b.add_package(dep.get_package(), 1, !opts.build_script_overrides.is_valid(), !cross_compiling); + } + } // TODO: Add the binaries too? // - They need slightly different treatment. @@ -261,7 +273,7 @@ BuildList::BuildList(const PackageManifest& manifest, const BuildOptions& opts): bool BuildList::build(BuildOptions opts, unsigned num_jobs) { bool include_build = !opts.build_script_overrides.is_valid(); - Builder builder { ::std::move(opts), m_list.size() }; + Builder builder { opts, m_list.size() }; // Pre-count how many dependencies are remaining for each package struct BuildState @@ -533,14 +545,24 @@ bool BuildList::build(BuildOptions opts, unsigned num_jobs) } // Now that all libraries are done, build the binaries (if present) - return this->m_root_manifest.foreach_binaries([&](const auto& bin_target) { - return builder.build_target(this->m_root_manifest, bin_target, /*is_for_host=*/false, ~0u); - }); + switch(opts.mode) + { + case BuildOptions::Mode::Normal: + return this->m_root_manifest.foreach_binaries([&](const auto& bin_target) { + return builder.build_target(this->m_root_manifest, bin_target, /*is_for_host=*/false, ~0u); + }); + case BuildOptions::Mode::Test: + // TODO: What about unit tests? + return this->m_root_manifest.foreach_ty(PackageTarget::Type::Test, [&](const auto& test_target) { + return builder.build_target(this->m_root_manifest, test_target, /*is_for_host=*/true, ~0u); + }); + } + throw "unreachable"; } -Builder::Builder(BuildOptions opts, size_t total_targets): - m_opts(::std::move(opts)), +Builder::Builder(const BuildOptions& opts, size_t total_targets): + m_opts(opts), m_total_targets(total_targets), m_targets_built(0) { @@ -641,6 +663,11 @@ Builder::Builder(BuildOptions opts, size_t total_targets): *crate_type = "bin"; outfile /= ::format(target.m_name, EXESUF); break; + case PackageTarget::Type::Test: + if(crate_type) + *crate_type = "bin"; + outfile /= ::format(target.m_name, "-test", EXESUF); + break; default: throw ::std::runtime_error("Unknown target type being built"); } @@ -810,6 +837,7 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget& for(const auto& cmd : manifest.build_script_output().pre_build_commands) { // TODO: Run commands specified by build script (override) + TODO("Run command `" << cmd << "` from build script override"); } { @@ -882,6 +910,10 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget& args.push_back("--extern"); args.push_back(::format(m.get_library().m_name, "=", path)); } + if( target.m_type == PackageTarget::Type::Test /*|| building_unit_tests */) + { + args.push_back("--test"); + } for(const auto& dep : manifest.dependencies()) { if( ! dep.is_disabled() ) diff --git a/tools/minicargo/build.h b/tools/minicargo/build.h index bba22964..83af88d6 100644 --- a/tools/minicargo/build.h +++ b/tools/minicargo/build.h @@ -20,7 +20,15 @@ struct BuildOptions ::helpers::path build_script_overrides; ::std::vector<::helpers::path> lib_search_dirs; bool emit_mmir = false; - const char* target_name = nullptr; // if null, host is used + const char* target_name = nullptr; // if null, host is used + enum class Mode { + /// Build the binary/library + Normal, + /// Build tests + Test, + /// Build examples + Examples, + } mode = Mode::Normal; }; class BuildList diff --git a/tools/minicargo/main.cpp b/tools/minicargo/main.cpp index d7312d48..9ddff1f3 100644 --- a/tools/minicargo/main.cpp +++ b/tools/minicargo/main.cpp @@ -44,6 +44,9 @@ struct ProgramOptions // Pause for user input before quitting (useful for MSVC debugging) bool pause_before_quit = false; + /// Build and run tests? + bool test = false; + int parse(int argc, const char* argv[]); void usage() const; void help() const; @@ -100,7 +103,7 @@ int main(int argc, const char* argv[]) // 2. Load all dependencies Debug_SetPhase("Load Dependencies"); - m.load_dependencies(repo, !bs_override_dir.is_valid()); + m.load_dependencies(repo, !bs_override_dir.is_valid(), /*include_dev=*/opts.test); // 3. Build dependency tree and build program. BuildOptions build_opts; @@ -111,6 +114,11 @@ int main(int argc, const char* argv[]) build_opts.target_name = opts.target; for(const auto* d : opts.lib_search_dirs) build_opts.lib_search_dirs.push_back( ::helpers::path(d) ); + // Indicate desire to build tests (or examples) instead of the primary target + build_opts.mode = + opts.test ? BuildOptions::Mode::Test : + BuildOptions::Mode::Normal + ; Debug_SetPhase("Enumerate Build"); auto build_list = BuildList(m, build_opts); Debug_SetPhase("Run Build"); @@ -254,6 +262,9 @@ int ProgramOptions::parse(int argc, const char* argv[]) else if( ::std::strcmp(arg, "--pause") == 0 ) { this->pause_before_quit = true; } + else if( ::std::strcmp(arg, "--test") == 0 ) { + this->test = true; + } else { ::std::cerr << "Unknown flag " << arg << ::std::endl; return 1; diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp index be2e1c77..2a1493c8 100644 --- a/tools/minicargo/manifest.cpp +++ b/tools/minicargo/manifest.cpp @@ -179,42 +179,28 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) target_edit_from_kv(*it, key_val, 2); } - else if( section == "dependencies" ) + else if( section == "dependencies" || section == "build-dependencies" || section == "dev-dependencies" ) { + ::std::vector<PackageRef>& dep_list = + section == "dependencies" ? rv.m_dependencies : + section == "build-dependencies" ? rv.m_build_dependencies : + /*section == "dev-dependencies" ? */ rv.m_dev_dependencies /*: + throw ""*/ + ; assert(key_val.path.size() > 1); const auto& depname = key_val.path[1]; // 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()); + auto it = ::std::find_if(dep_list.begin(), dep_list.end(), [&](const auto& x) { return x.m_name == depname; }); + bool was_added = (it == dep_list.end()); if( was_added ) { - it = rv.m_dependencies.insert(it, PackageRef{ depname }); + it = dep_list.insert(it, PackageRef{ depname }); } it->fill_from_kv(was_added, key_val, 2); } - else if( section == "build-dependencies" ) - { - assert(key_val.path.size() > 1); - - const auto& depname = key_val.path[1]; - - // Find/create dependency descriptor - auto it = ::std::find_if(rv.m_build_dependencies.begin(), rv.m_build_dependencies.end(), [&](const auto& x) { return x.m_name == depname; }); - bool was_added = (it == rv.m_build_dependencies.end()); - if(was_added) - { - it = rv.m_build_dependencies.insert(it, PackageRef{ depname }); - } - - it->fill_from_kv(was_added, key_val, 2); - } - else if( section == "dev-dependencies" ) - { - // TODO: Developemnt (test/bench) deps - } else if( section == "patch" ) { //const auto& repo = key_val.path[1]; @@ -321,6 +307,16 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) rv.m_targets.push_back(PackageTarget { PackageTarget::Type::Lib }); } } + // - If there's no binary section, but src/main.rs exists, add one + if( ! ::std::any_of(rv.m_targets.begin(), rv.m_targets.end(), [](const auto& x){ return x.m_type == PackageTarget::Type::Bin; }) ) + { + // No library, add one pointing to lib.rs + if( ::std::ifstream(package_dir / "src" / "main.rs").good() ) + { + DEBUG("- Implicit library"); + rv.m_targets.push_back(PackageTarget { PackageTarget::Type::Bin }); + } + } // Default target names for(auto& tgt : rv.m_targets) @@ -341,6 +337,12 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) tgt.m_path = ::helpers::path("src") / "bin" / tgt.m_name.c_str() + ".rs"; } break; + case PackageTarget::Type::Test: + case PackageTarget::Type::Bench: + // no defaults + break; + case PackageTarget::Type::Example: + TODO("Default/implicit path for examples"); } } if(tgt.m_name == "") @@ -351,6 +353,8 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path) } } + // TODO: if there's a lib target, add a test target using the same path + for(const auto& dep : rv.m_dependencies) { if( dep.m_optional ) @@ -640,12 +644,19 @@ void PackageManifest::set_features(const ::std::vector<::std::string>& features, it2->m_optional_enabled = true; } } + { + auto it2 = ::std::find_if(m_dev_dependencies.begin(), m_dev_dependencies.end(), [&](const auto& x){ return x.m_name == featname; }); + if(it2 != m_dev_dependencies.end()) + { + it2->m_optional_enabled = true; + } + } } // Return true if any features were activated //return start < m_active_features.size(); } -void PackageManifest::load_dependencies(Repository& repo, bool include_build) +void PackageManifest::load_dependencies(Repository& repo, bool include_build, bool include_dev) { TRACE_FUNCTION_F(m_name); DEBUG("Loading depencencies for " << m_name); @@ -661,16 +672,30 @@ void PackageManifest::load_dependencies(Repository& repo, bool include_build) dep.load_manifest(repo, base_path, include_build); } - // TODO: Only enable if build script overrides aren't enabled. + // Load build deps if there's a build script AND build scripts are enabled if( m_build_script != "" && include_build ) { + DEBUG("- Build dependencies"); for(auto& dep : m_build_dependencies) { if( dep.m_optional && !dep.m_optional_enabled ) { continue ; } - dep.load_manifest(repo, base_path, true); + dep.load_manifest(repo, base_path, include_build); + } + } + // Load dev dependencies if the caller has indicated they should be + if( include_dev ) + { + DEBUG("- Dev dependencies"); + for(auto& dep : m_dev_dependencies) + { + if( dep.m_optional && !dep.m_optional_enabled ) + { + continue ; + } + dep.load_manifest(repo, base_path, include_build); } } } diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h index 54374dc2..d0c537e5 100644 --- a/tools/minicargo/manifest.h +++ b/tools/minicargo/manifest.h @@ -264,6 +264,7 @@ class PackageManifest ::std::vector<PackageRef> m_dependencies; ::std::vector<PackageRef> m_build_dependencies; + ::std::vector<PackageRef> m_dev_dependencies; ::std::vector<PackageTarget> m_targets; @@ -282,15 +283,18 @@ public: bool has_library() const; const PackageTarget& get_library() const; - bool foreach_binaries(::std::function<bool(const PackageTarget&)> cb) const { + bool foreach_ty(PackageTarget::Type ty, ::std::function<bool(const PackageTarget&)> cb) const { for(const auto& t : m_targets ) { - if( t.m_type == PackageTarget::Type::Bin ) { + if( t.m_type == ty ) { if( !cb(t) ) return false; } } return true; } + bool foreach_binaries(::std::function<bool(const PackageTarget&)> cb) const { + return foreach_ty(PackageTarget::Type::Bin, cb); + } const ::helpers::path directory() const { return ::helpers::path(m_manifest_path).parent(); @@ -313,12 +317,15 @@ public: const ::std::vector<PackageRef>& build_dependencies() const { return m_build_dependencies; } + const ::std::vector<PackageRef>& dev_dependencies() const { + return m_dev_dependencies; + } const ::std::vector<::std::string>& active_features() const { return m_active_features; } void set_features(const ::std::vector<::std::string>& features, bool enable_default); - void load_dependencies(Repository& repo, bool include_build); + void load_dependencies(Repository& repo, bool include_build, bool include_dev=false); void load_build_script(const ::std::string& path); }; diff --git a/tools/minicargo/repository.cpp b/tools/minicargo/repository.cpp index f5ff5ea8..060c5207 100644 --- a/tools/minicargo/repository.cpp +++ b/tools/minicargo/repository.cpp @@ -75,7 +75,7 @@ void Repository::load_vendored(const ::helpers::path& path) } } - //DEBUG("Package '" << name << "' v" << ver); + DEBUG("Vendored package '" << name << "' v" << ver); if(name == "") continue ; @@ -91,6 +91,7 @@ void Repository::load_vendored(const ::helpers::path& path) } while( FindNextFile(find_handle, &find_data) ); FindClose(find_handle); #endif + DEBUG("Loaded " << m_cache.size() << " vendored packages"); } ::std::shared_ptr<PackageManifest> Repository::from_path(::helpers::path in_path) |