summaryrefslogtreecommitdiff
path: root/tools/minicargo/build.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/minicargo/build.cpp')
-rw-r--r--tools/minicargo/build.cpp115
1 files changed, 91 insertions, 24 deletions
diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp
index 8127fbf0..b4e736d2 100644
--- a/tools/minicargo/build.cpp
+++ b/tools/minicargo/build.cpp
@@ -5,7 +5,7 @@
#include <vector>
#include <algorithm>
#include <sstream> // stringstream
-#include "helpers.h" // path
+#include "path.h"
#ifdef _WIN32
# include <Windows.h>
#else
@@ -33,7 +33,7 @@ struct BuildList
size_t i;
const PackageManifest& operator*() const {
- return *this->l.m_list[this->l.m_list.size() - this->i - 1].package;
+ return *this->l.m_list[this->i].package;
}
void operator++() {
this->i++;
@@ -81,12 +81,22 @@ class Builder
}
};
+ ::helpers::path m_build_script_overrides;
+
public:
+ Builder(::helpers::path override_dir):
+ m_build_script_overrides(override_dir)
+ {
+ }
+
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;
+
+
+ time_t get_timestamp(const ::helpers::path& path) const;
};
void MiniCargo_Build(const PackageManifest& manifest)
@@ -103,7 +113,8 @@ void MiniCargo_Build(const PackageManifest& manifest)
}
// Build dependencies
- Builder builder;
+ // TODO: Take this path as input. (XXX HACK)
+ Builder builder { "overrides/nightly-2017-07-08" };
for(const auto& p : list.iter())
{
if( ! builder.build_library(p) )
@@ -129,13 +140,15 @@ void BuildList::add_dependencies(const PackageManifest& p, unsigned level)
}
void BuildList::add_package(const PackageManifest& p, unsigned level)
{
+ // If the package is already loaded
for(auto& ent : m_list)
{
- if(ent.package == &p)
+ if(ent.package == &p && ent.level >= level)
{
- ent.level = level;
+ // NOTE: Only skip if this package will be built before we needed (i.e. the level is greater)
return ;
}
+ // Keep searching (might already have a higher entry)
}
m_list.push_back({ &p, level });
for (const auto& dep : p.dependencies())
@@ -145,17 +158,20 @@ void BuildList::add_package(const PackageManifest& p, unsigned level)
}
void BuildList::sort_list()
{
- ::std::sort(m_list.begin(), m_list.end(), [](const auto& a, const auto& b){ return a.level < b.level; });
+ ::std::sort(m_list.begin(), m_list.end(), [](const auto& a, const auto& b){ return a.level > b.level; });
+ // Needed to deduplicate after sorting (`add_package` doesn't fully dedup)
for(auto it = m_list.begin(); it != m_list.end(); )
{
auto it2 = ::std::find_if(m_list.begin(), it, [&](const auto& x){ return x.package == it->package; });
if( it2 != it )
{
+ DEBUG((it - m_list.begin()) << ": Duplicate " << it->package->name() << " - Already at pos " << (it2 - m_list.begin()));
it = m_list.erase(it);
}
else
{
+ DEBUG((it - m_list.begin()) << ": Keep " << it->package->name() << ", level = " << it->level);
++it;
}
}
@@ -172,6 +188,28 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget&
// > mrustc/minicargo is newer than `outfile`
// > build script has changed
// > any input file has changed (requires depfile from mrustc)
+ bool force_rebuild = false;
+ auto ts_result = this->get_timestamp(outfile);
+ if( force_rebuild ) {
+ }
+ else if( ts_result == 0/*Timestamp::infinite_past()*/ ) {
+ // Rebuild (missing)
+ }
+ //else if( ts_result < this->get_timestamp("../bin/mrustc") || ts_result < this->get_timestamp("bin/minicargo") ) {
+ // // Rebuild (older than mrustc/minicargo)
+ //}
+ else {
+ // TODO: Check dependencies. (from depfile)
+ // Don't rebuild (no need to)
+ DEBUG("Not building " << outfile << " - not out of date");
+ return true;
+ }
+
+
+ for(const auto& cmd : manifest.build_script_output().pre_build_commands)
+ {
+ // TODO: Run commands specified by build script (override)
+ }
StringList args;
args.push_back(::helpers::path(manifest.manifest_path()).parent() / ::helpers::path(target.m_path));
@@ -179,18 +217,18 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget&
args.push_back("--crate-type"); args.push_back("rlib");
args.push_back("-o"); args.push_back(outfile);
args.push_back("-L"); args.push_back(outdir);
- //for(const auto& dir : manifest.build_script.rustc_link_search) {
- // args.push_back("-L"); args.push_back(dir.second.c_str());
- //}
- //for(const auto& lib : manifest.build_script.rustc_link_lib) {
- // args.push_back("-l"); args.push_back(lib.second.c_str());
- //}
- //for(const auto& cfg : manifest.build_script.rustc_cfg) {
- // args.push_back("--cfg"); args.push_back(cfg.c_str());
- //}
- //for(const auto& flag : manifest.build_script.rustc_flags) {
- // args.push_back(flag.c_str());
- //}
+ for(const auto& dir : manifest.build_script_output().rustc_link_search) {
+ args.push_back("-L"); args.push_back(dir.second.c_str());
+ }
+ for(const auto& lib : manifest.build_script_output().rustc_link_lib) {
+ args.push_back("-l"); args.push_back(lib.second.c_str());
+ }
+ for(const auto& cfg : manifest.build_script_output().rustc_cfg) {
+ args.push_back("--cfg"); args.push_back(cfg.c_str());
+ }
+ for(const auto& flag : manifest.build_script_output().rustc_flags) {
+ args.push_back(flag.c_str());
+ }
// TODO: Environment variables (rustc_env)
return this->spawn_process(args, outfile + "_dbg.txt");
@@ -200,12 +238,24 @@ bool Builder::build_library(const PackageManifest& manifest) const
if( manifest.build_script() != "" )
{
// Locate a build script override file
- // > Note, override file can specify a list of commands to run.
- //manifest.script_output = BuildScript::load( override_file );
- // Otherwise, compile and run build script
- //manifest.script_output = BuildScript::load( ::helpers::path("output") / "build_" + manifest.name + ".txt" );
- // Parse build script output.
- throw ::std::runtime_error("TODO: Build script");
+ if(this->m_build_script_overrides.is_valid())
+ {
+ auto override_file = this->m_build_script_overrides / "build_" + manifest.name().c_str() + ".txt";
+ // TODO: Should this test if it exists? or just assume and let it error?
+
+ // > Note, override file can specify a list of commands to run.
+ const_cast<PackageManifest&>(manifest).load_build_script( override_file.str() );
+ }
+ else
+ {
+ // Otherwise, compile and run build script
+ // - Load dependencies for the build script
+ // - Build the script itself
+ //this->build_build_script( manifest );
+ // - Run the script and put output in the right dir
+ //manifest.load_build_script( ::helpers::path("output") / "build_" + manifest.name().c_str() + ".txt" );
+ throw ::std::runtime_error("TODO: Build script for " + manifest.name());
+ }
}
return this->build_target(manifest, manifest.get_library());
@@ -297,3 +347,20 @@ bool Builder::spawn_process(const StringList& args, const ::helpers::path& logfi
#endif
return true;
}
+
+time_t Builder::get_timestamp(const ::helpers::path& path) const
+{
+#if _WIN32
+#else
+ struct stat s;
+ if( stat(path.str().c_str(), &s) == 0 )
+ {
+ return s.st_mtime;
+ }
+ else
+ {
+ return 0;
+ }
+#endif
+}
+