summaryrefslogtreecommitdiff
path: root/tools/minicargo
diff options
context:
space:
mode:
Diffstat (limited to 'tools/minicargo')
-rw-r--r--tools/minicargo/build.cpp48
-rw-r--r--tools/minicargo/build.h10
-rw-r--r--tools/minicargo/main.cpp13
-rw-r--r--tools/minicargo/manifest.cpp79
-rw-r--r--tools/minicargo/manifest.h13
-rw-r--r--tools/minicargo/repository.cpp3
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)