summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/minicargo/Makefile2
-rw-r--r--tools/minicargo/build.cpp115
-rw-r--r--tools/minicargo/helpers.h253
-rw-r--r--tools/minicargo/manifest.cpp62
-rw-r--r--tools/minicargo/manifest.h37
-rw-r--r--tools/minicargo/path.cpp157
-rw-r--r--tools/minicargo/path.h131
-rw-r--r--tools/minicargo/repository.cpp6
-rw-r--r--tools/overrides/nightly-2017-07-08/build_libc.txt3
9 files changed, 486 insertions, 280 deletions
diff --git a/tools/minicargo/Makefile b/tools/minicargo/Makefile
index ab3f8531..b528bac6 100644
--- a/tools/minicargo/Makefile
+++ b/tools/minicargo/Makefile
@@ -10,7 +10,7 @@ OBJDIR := .obj/
BIN := ../bin/minicargo
OBJS := main.o build.o manifest.o repository.o
-OBJS += toml.o
+OBJS += toml.o path.o
LINKFLAGS :=
CXXFLAGS := -Wall -std=c++14
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
+}
+
diff --git a/tools/minicargo/helpers.h b/tools/minicargo/helpers.h
index f2679ef4..d913e3c2 100644
--- a/tools/minicargo/helpers.h
+++ b/tools/minicargo/helpers.h
@@ -2,6 +2,7 @@
#include <string>
#include <cstring>
+#include <iostream>
namespace helpers {
@@ -23,256 +24,18 @@ public:
return false;
return s[m_len] == '\0';
}
+ operator ::std::string() const {
+ return ::std::string { m_start, m_start + m_len };
+ }
friend ::std::string& operator+=(::std::string& x, const string_view& sv) {
x.append(sv.m_start, sv.m_start+sv.m_len);
return x;
}
-};
-
-/// Path helper class (because I don't want to include boost)
-class path
-{
-#ifdef _WIN32
- static const char SEP = '\\';
-#else
- static const char SEP = '/';
-#endif
-
- ::std::string m_str;
-
- path()
- {
- }
-public:
- path(const ::std::string& s):
- path(s.c_str())
- {
- }
- path(const char* s):
- m_str(s)
- {
- // 1. Normalise path separators to the system specified separator
- for(size_t i = 0; i < m_str.size(); i ++)
- {
- if( m_str[i] == '/' || m_str[i] == '\\' )
- m_str[i] = SEP;
- }
-
- // 2. Remove any trailing separators
- if( !m_str.empty() )
- {
- while(!m_str.empty() && m_str.back() == SEP )
- m_str.pop_back();
- if(m_str.empty())
- {
- m_str.push_back(SEP);
- }
- }
- else
- {
- throw ::std::runtime_error("Empty path being constructed");
- }
- }
-
- path operator/(const path& p) const
- {
- if(p.m_str[0] == '/')
- 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
- {
- auto pos = m_str.find_last_of(SEP);
- if(pos == ::std::string::npos)
- {
- return *this;
- }
- else
- {
- path rv;
- rv.m_str = m_str.substr(0, pos);
- return rv;
- }
- }
-
- operator ::std::string() const
- {
- return m_str;
- }
-
- class ComponentsIter
- {
- const path& p;
- size_t pos;
- size_t end;
-
- friend class path;
- ComponentsIter(const path& p, size_t i): p(p), pos(i) {
- end = p.m_str.find(SEP, pos);
- if(end == ::std::string::npos)
- end = p.m_str.size();
- }
- public:
- string_view operator*() const {
- return string_view(p.m_str.c_str() + pos, end - pos);
- }
- void operator++() {
- if(end == p.m_str.size())
- pos = end;
- else
- {
- pos = end+1;
- end = p.m_str.find(SEP, pos);
- if(end == ::std::string::npos)
- end = p.m_str.size();
- }
- }
- bool operator!=(const ComponentsIter& x) const {
- return pos != x.pos;
- }
- };
- ComponentsIter begin() const {
- return ComponentsIter(*this, 0);
- }
- ComponentsIter end() const {
- return ComponentsIter(*this, m_str.size());
- }
-
- path normalise() const
- {
- path rv;
- rv.m_str.reserve( m_str.size()+1 );
-
- for(auto comp : *this)
- {
- if( comp == "." ) {
- // Ignore.
- }
- else if( comp == ".." )
- {
- // If the path is empty, OR the last element is a "..", push the element
- if( rv.m_str.empty()
- || (rv.m_str.size() == 3 && rv.m_str[0] == '.' && rv.m_str[1] == '.' && rv.m_str[2] == SEP)
- || (rv.m_str.size() > 4 && *(rv.m_str.end()-4) == SEP && *(rv.m_str.end()-3) == '.' && *(rv.m_str.end()-2) == '.' && *(rv.m_str.end()-1) == SEP )
- )
- {
- // Push
- rv.m_str += comp;
- rv.m_str += SEP;
- }
- else
- {
- rv.m_str.pop_back();
- auto pos = rv.m_str.find_last_of(SEP);
- if(pos == ::std::string::npos)
- {
- rv.m_str.resize(0);
- }
- else if( pos == 0 )
- {
- // Keep.
- }
- else
- {
- rv.m_str.resize(pos+1);
- }
- }
- }
- else {
- rv.m_str += comp;
- rv.m_str += SEP;
- }
- }
- rv.m_str.pop_back();
- return rv;
- }
-#if 0
- void normalise_in_place()
- {
- size_t insert_point = 0;
-
- for(size_t read_pos = 0; read_pos < m_str.size(); read_pos ++)
- {
- auto pos = m_str.find_first_of(SEP, read_pos);
- if(pos == ::std::string::npos)
- pos = m_str.size();
- auto comp = string_view(m_str.c_str() + read_pos, pos - read_pos);
-
- bool append;
- if(comp == ".")
- {
- // Advance read without touching insert
- append = false;
- }
- else if( comp == ".." )
- {
- // Consume parent (if not a relative component already)
- // Move insertion point back to the previous separator
- auto pos = m_str.find_last_of(SEP, insert_point);
- if(pos == ::std::string::npos)
- {
- // Only one component currently (or empty)
- append = true;
- }
- else if(string_view(m_str.c_str() + pos+1, insert_point - pos-1) == "..")
- {
- // Last component is ".." - keep adding
- append = true;
- }
- else
- {
- insert_point = pos;
- append = false;
- }
- }
- else
- {
- append = true;
- }
-
- if(append)
- {
- if( read_pos != insert_point )
- {
- //assert(read_pos > insert_point);
- while(read_pos < pos)
- {
- m_str[insert_point++] = m_str[read_pos++];
- }
- }
- }
- else
- {
- read_pos = pos;
- }
- }
- }
-#endif
-
- friend ::std::ostream& operator<<(::std::ostream& os, const path& p)
- {
- return os << p.m_str;
+ friend ::std::ostream& operator<<(::std::ostream& os, const string_view& sv) {
+ os.write(sv.m_start, sv.m_len);
+ return os;
}
};
+
} // namespace helpers
diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp
index 1bb815d8..60594303 100644
--- a/tools/minicargo/manifest.cpp
+++ b/tools/minicargo/manifest.cpp
@@ -3,7 +3,7 @@
#include "manifest.h"
#include "toml.h"
#include "debug.h"
-#include "helpers.h"
+#include "path.h"
#include <cassert>
#include <algorithm>
#include "repository.h"
@@ -305,6 +305,66 @@ void PackageManifest::load_dependencies(Repository& repo)
}
}
+void PackageManifest::load_build_script(const ::std::string& path)
+{
+ ::std::ifstream is( path );
+ if( !is.good() )
+ throw ::std::runtime_error("Unable to open build script file '" + path + "'");
+
+ BuildScriptOutput rv;
+
+ while( !is.eof() )
+ {
+ ::std::string line;
+ is >> line;
+ if( line.compare(0, 5+1, "cargo:") == 0 )
+ {
+ size_t start = 5+1;
+ size_t eq_pos = line.find_first_of('=');
+ ::helpers::string_view key { line.c_str() + start, eq_pos - start };
+ ::helpers::string_view value { line.c_str() + eq_pos + 1, line.size() - eq_pos - 1 };
+
+ if( key == "minicargo-pre-build" ) {
+ rv.pre_build_commands.push_back(value);
+ }
+ // cargo:rustc-link-search=foo/bar/baz
+ else if( key == "rustc-link-search" ) {
+ // TODO: Check for an = (otherwise default to dynamic)
+ throw ::std::runtime_error("TODO: rustc-link-search");
+ }
+ // cargo:rustc-link-lib=mysql
+ else if( key == "rustc-link-lib" ) {
+ // TODO: Check for an = (otherwise default to dynamic)
+ throw ::std::runtime_error("TODO: rustc-link-lib");
+ }
+ // cargo:rustc-cfg=foo
+ else if( key == "rustc-cfg" ) {
+ // TODO: Validate
+ rv.rustc_cfg.push_back( value );
+ }
+ // cargo:rustc-flags=-l foo
+ else if( key == "rustc-flags" ) {
+ // Split on space, then push each.
+ throw ::std::runtime_error("TODO: rustc-flags");
+ }
+ // cargo:rustc-env=FOO=BAR
+ else if( key == "rustc-env" ) {
+ rv.rustc_env.push_back( value );
+ }
+ // cargo:rerun-if-changed=foo.rs
+ else if( key == "rerun-if-changed" ) {
+ DEBUG("TODO: '" << key << "' = '" << value << "'");
+ }
+ // - Ignore
+ else {
+ DEBUG("TODO: '" << key << "' = '" << value << "'");
+ }
+ }
+ }
+
+ m_build_script_output = rv;
+}
+
void PackageRef::load_manifest(Repository& repo, const ::helpers::path& base_path)
{
// If the path isn't set, check for:
diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h
index 428a9721..7f93e2c4 100644
--- a/tools/minicargo/manifest.h
+++ b/tools/minicargo/manifest.h
@@ -3,7 +3,7 @@
#include <string>
#include <vector>
#include <memory>
-#include "helpers.h"
+#include "path.h"
class PackageManifest;
class Repository;
@@ -122,6 +122,25 @@ struct PackageTarget
}
};
+class BuildScriptOutput
+{
+public:
+ // `cargo:minicargo-pre-build=make -C bar/`
+ // MiniCargo hack
+ ::std::vector<::std::string> pre_build_commands;
+
+ // cargo:rustc-link-search=foo/bar/baz
+ ::std::vector<::std::pair<const char*,::std::string>> rustc_link_search;
+ // cargo:rustc-link-lib=mysql
+ ::std::vector<::std::pair<const char*,::std::string>> rustc_link_lib;
+ // cargo:rustc-cfg=foo
+ ::std::vector<::std::string> rustc_cfg;
+ // cargo:rustc-flags=-l foo
+ ::std::vector<::std::string> rustc_flags;
+ // cargo:rustc-env=FOO=BAR
+ ::std::vector<::std::string> rustc_env;
+};
+
class PackageManifest
{
::std::string m_manifest_path;
@@ -135,11 +154,10 @@ class PackageManifest
::std::vector<PackageTarget> m_targets;
- struct BuildScript
- {
- };
+ BuildScriptOutput m_build_script_output;
PackageManifest();
+
public:
static PackageManifest load_from_toml(const ::std::string& path);
@@ -152,10 +170,17 @@ public:
const ::std::string& name() const {
return m_name;
}
- const ::std::string& build_script() const { return m_build_script; }
+ const ::std::string& build_script() const {
+ return m_build_script;
+ }
+ const BuildScriptOutput& build_script_output() const {
+ return m_build_script_output;
+ }
const ::std::vector<PackageRef>& dependencies() const {
return m_dependencies;
}
-
+
void load_dependencies(Repository& repo);
+
+ void load_build_script(const ::std::string& path);
};
diff --git a/tools/minicargo/path.cpp b/tools/minicargo/path.cpp
new file mode 100644
index 00000000..d0316548
--- /dev/null
+++ b/tools/minicargo/path.cpp
@@ -0,0 +1,157 @@
+/*
+ */
+#include "path.h"
+
+helpers::path::path(const char* s):
+ m_str(s)
+{
+ // 1. Normalise path separators to the system specified separator
+ for(size_t i = 0; i < m_str.size(); i ++)
+ {
+ if( m_str[i] == '/' || m_str[i] == '\\' )
+ m_str[i] = SEP;
+ }
+
+ // 2. Remove any trailing separators
+ if( !m_str.empty() )
+ {
+ while(!m_str.empty() && m_str.back() == SEP )
+ m_str.pop_back();
+ if(m_str.empty())
+ {
+ m_str.push_back(SEP);
+ }
+ }
+ else
+ {
+ throw ::std::runtime_error("Empty path being constructed");
+ }
+}
+
+helpers::path helpers::path::normalise() const
+{
+ path rv;
+ rv.m_str.reserve( m_str.size()+1 );
+
+ for(auto comp : *this)
+ {
+ if( comp == "." ) {
+ // Ignore.
+ }
+ else if( comp == ".." )
+ {
+ // If the path is empty, OR the last element is a "..", push the element
+ if( rv.m_str.empty()
+ || (rv.m_str.size() == 3 && rv.m_str[0] == '.' && rv.m_str[1] == '.' && rv.m_str[2] == SEP)
+ || (rv.m_str.size() > 4 && *(rv.m_str.end()-4) == SEP && *(rv.m_str.end()-3) == '.' && *(rv.m_str.end()-2) == '.' && *(rv.m_str.end()-1) == SEP )
+ )
+ {
+ // Push
+ rv.m_str += comp;
+ rv.m_str += SEP;
+ }
+ else
+ {
+ rv.m_str.pop_back();
+ auto pos = rv.m_str.find_last_of(SEP);
+ if(pos == ::std::string::npos)
+ {
+ rv.m_str.resize(0);
+ }
+ else if( pos == 0 )
+ {
+ // Keep.
+ }
+ else
+ {
+ rv.m_str.resize(pos+1);
+ }
+ }
+ }
+ else
+ {
+ rv.m_str += comp;
+ rv.m_str += SEP;
+ }
+ }
+ rv.m_str.pop_back();
+ return rv;
+}
+
+#if 0
+void helpers::path::normalise_in_place()
+{
+ size_t insert_point = 0;
+
+ for(size_t read_pos = 0; read_pos < m_str.size(); read_pos ++)
+ {
+ auto pos = m_str.find_first_of(SEP, read_pos);
+ if(pos == ::std::string::npos)
+ pos = m_str.size();
+ auto comp = string_view(m_str.c_str() + read_pos, pos - read_pos);
+
+ bool append;
+ if(comp == ".")
+ {
+ // Advance read without touching insert
+ append = false;
+ }
+ else if( comp == ".." )
+ {
+ // Consume parent (if not a relative component already)
+ // Move insertion point back to the previous separator
+ auto pos = m_str.find_last_of(SEP, insert_point);
+ if(pos == ::std::string::npos)
+ {
+ // Only one component currently (or empty)
+ append = true;
+ }
+ else if(string_view(m_str.c_str() + pos+1, insert_point - pos-1) == "..")
+ {
+ // Last component is ".." - keep adding
+ append = true;
+ }
+ else
+ {
+ insert_point = pos;
+ append = false;
+ }
+ }
+ else
+ {
+ append = true;
+ }
+
+ if(append)
+ {
+ if( read_pos != insert_point )
+ {
+ //assert(read_pos > insert_point);
+ while(read_pos < pos)
+ {
+ m_str[insert_point++] = m_str[read_pos++];
+ }
+ }
+ }
+ else
+ {
+ read_pos = pos;
+ }
+ }
+}
+#endif
+
+void helpers::path::ComponentsIter::operator++()
+{
+ if(end == p.m_str.size())
+ {
+ pos = end;
+ }
+ else
+ {
+ pos = end+1;
+ end = p.m_str.find(SEP, pos);
+ if(end == ::std::string::npos)
+ end = p.m_str.size();
+ }
+} \ No newline at end of file
diff --git a/tools/minicargo/path.h b/tools/minicargo/path.h
new file mode 100644
index 00000000..54cb8f40
--- /dev/null
+++ b/tools/minicargo/path.h
@@ -0,0 +1,131 @@
+#pragma once
+
+#include <string>
+#include <stdexcept>
+#include "helpers.h"
+
+namespace helpers {
+
+/// Path helper class (because I don't want to include boost)
+class path
+{
+#ifdef _WIN32
+ static const char SEP = '\\';
+#else
+ static const char SEP = '/';
+#endif
+
+ ::std::string m_str;
+
+public:
+ path()
+ {
+ }
+ path(const ::std::string& s):
+ path(s.c_str())
+ {
+ }
+ path(const char* s);
+
+ bool is_valid() const {
+ return m_str != "";
+ }
+
+ path operator/(const path& p) const
+ {
+ if(!this->is_valid())
+ throw ::std::runtime_error("Appending to an invalid path");
+ if(!p.is_valid())
+ throw ::std::runtime_error("Appending from an invalid path");
+ if(p.m_str[0] == '/')
+ 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(!this->is_valid())
+ throw ::std::runtime_error("Appending to an invalid path");
+ 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(!this->is_valid())
+ throw ::std::runtime_error("Appending a string to an invalid path");
+ 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
+ {
+ if(!this->is_valid())
+ throw ::std::runtime_error("Calling parent() on an invalid path");
+ auto pos = m_str.find_last_of(SEP);
+ if(pos == ::std::string::npos)
+ {
+ return *this;
+ }
+ else
+ {
+ path rv;
+ rv.m_str = m_str.substr(0, pos);
+ return rv;
+ }
+ }
+
+ const ::std::string& str() const
+ {
+ return m_str;
+ }
+ operator ::std::string() const
+ {
+ return m_str;
+ }
+
+ class ComponentsIter
+ {
+ const path& p;
+ size_t pos;
+ size_t end;
+
+ friend class path;
+ ComponentsIter(const path& p, size_t i): p(p), pos(i) {
+ end = p.m_str.find(SEP, pos);
+ if(end == ::std::string::npos)
+ end = p.m_str.size();
+ }
+ public:
+ string_view operator*() const {
+ return string_view(p.m_str.c_str() + pos, end - pos);
+ }
+ void operator++();
+ bool operator!=(const ComponentsIter& x) const {
+ return pos != x.pos;
+ }
+ };
+ ComponentsIter begin() const {
+ return ComponentsIter(*this, 0);
+ }
+ ComponentsIter end() const {
+ return ComponentsIter(*this, m_str.size());
+ }
+
+ path normalise() const;
+ //void normalise_in_place();
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const path& p)
+ {
+ return os << p.m_str;
+ }
+};
+
+}
diff --git a/tools/minicargo/repository.cpp b/tools/minicargo/repository.cpp
index 0a097f66..c6fe284f 100644
--- a/tools/minicargo/repository.cpp
+++ b/tools/minicargo/repository.cpp
@@ -13,11 +13,11 @@ void Repository::load_vendored(const ::helpers::path& path)
// Extract package name and version from each manifest
}
-::std::shared_ptr<PackageManifest> Repository::from_path(::helpers::path path)
+::std::shared_ptr<PackageManifest> Repository::from_path(::helpers::path in_path)
{
- DEBUG("Repository::from_path(" << path << ")");
+ DEBUG("Repository::from_path(" << in_path << ")");
// 1. Normalise path
- path = path.normalise();
+ auto path = in_path.normalise();
DEBUG("path = " << path);
auto it = m_path_cache.find(path);
diff --git a/tools/overrides/nightly-2017-07-08/build_libc.txt b/tools/overrides/nightly-2017-07-08/build_libc.txt
new file mode 100644
index 00000000..32bbd68e
--- /dev/null
+++ b/tools/overrides/nightly-2017-07-08/build_libc.txt
@@ -0,0 +1,3 @@
+cargo:rustc-cfg=stdbuild
+cargo:rerun-if-changed=build.rs
+