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.cpp114
1 files changed, 102 insertions, 12 deletions
diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp
index b4e736d2..fd141395 100644
--- a/tools/minicargo/build.cpp
+++ b/tools/minicargo/build.cpp
@@ -56,6 +56,8 @@ struct BuildList
class Builder
{
+ static const char* const MRUSTC_PATH;
+
class StringList
{
::std::vector<::std::string> m_cached;
@@ -64,6 +66,7 @@ class Builder
StringList()
{
}
+ StringList(const StringList&) = delete;
const ::std::vector<const char*>& get_vec() const
{
@@ -72,6 +75,33 @@ class Builder
void push_back(::std::string s)
{
+#if _WIN32
+ // NOTE: MSVC's STL changes the pointer on move it seems
+ if(m_cached.capacity() == m_cached.size())
+ {
+ ::std::vector<bool> b;
+ b.reserve(m_strings.size());
+ size_t j = 0;
+ for(const auto* s : m_strings)
+ {
+ if(j == m_cached.size())
+ break;
+ if(s == m_cached[j].c_str())
+ b.push_back(true);
+ else
+ b.push_back(false);
+ }
+
+ m_cached.push_back(::std::move(s));
+ j = 0;
+ for(size_t i = 0; i < b.size(); i ++)
+ {
+ if(b[i])
+ m_strings[i] = m_cached[j++].c_str();
+ }
+ }
+ else
+#endif
m_cached.push_back(::std::move(s));
m_strings.push_back(m_cached.back().c_str());
}
@@ -81,6 +111,43 @@ class Builder
}
};
+ struct Timestamp
+ {
+#if _WIN32
+ uint64_t m_val;
+
+ Timestamp(FILETIME ft):
+ m_val( (static_cast<uint64_t>(ft.dwHighDateTime) << 32) | static_cast<uint64_t>(ft.dwLowDateTime) )
+ {
+ }
+#else
+ time_t m_val;
+#endif
+ static Timestamp infinite_past() {
+#if _WIN32
+ return Timestamp { FILETIME { 0, 0 } };
+#else
+ return Timestamp { 0 }
+#endif
+ }
+
+ bool operator==(const Timestamp& x) const {
+ return m_val == x.m_val;
+ }
+ bool operator<(const Timestamp& x) const {
+ return m_val < x.m_val;
+ }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const Timestamp& x) {
+#if _WIN32
+ os << ::std::hex << x.m_val << ::std::dec;
+#else
+ os << x.m_val;
+#endif
+ return os;
+ }
+ };
+
::helpers::path m_build_script_overrides;
public:
@@ -96,10 +163,16 @@ private:
bool spawn_process(const StringList& args, const ::helpers::path& logfile) const;
- time_t get_timestamp(const ::helpers::path& path) const;
+ Timestamp get_timestamp(const ::helpers::path& path) const;
};
-void MiniCargo_Build(const PackageManifest& manifest)
+#if _WIN32
+const char* const Builder::MRUSTC_PATH = "x64\\Release\\mrustc.exe";
+#else
+const char* const Builder::MRUSTC_PATH = "../bin/mrustc";
+#endif
+
+void MiniCargo_Build(const PackageManifest& manifest, ::helpers::path override_path)
{
BuildList list;
@@ -113,8 +186,7 @@ void MiniCargo_Build(const PackageManifest& manifest)
}
// Build dependencies
- // TODO: Take this path as input. (XXX HACK)
- Builder builder { "overrides/nightly-2017-07-08" };
+ Builder builder { override_path };
for(const auto& p : list.iter())
{
if( ! builder.build_library(p) )
@@ -181,6 +253,7 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget&
{
auto outdir = ::helpers::path("output");
auto outfile = outdir / ::format("lib", target.m_name, ".hir");
+ //DEBUG("Building " << manifest.name() << ":" << target.m_name << " as " << outfile);
// TODO: Determine if it needs re-running
// Rerun if:
@@ -191,13 +264,16 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget&
bool force_rebuild = false;
auto ts_result = this->get_timestamp(outfile);
if( force_rebuild ) {
+ DEBUG("Building " << outfile << " - Force");
}
- else if( ts_result == 0/*Timestamp::infinite_past()*/ ) {
+ else if( ts_result == Timestamp::infinite_past() ) {
// Rebuild (missing)
+ DEBUG("Building " << outfile << " - Missing");
+ }
+ else if( ts_result < this->get_timestamp(MRUSTC_PATH) /*|| ts_result < this->get_timestamp("bin/minicargo")*/ ) {
+ // Rebuild (older than mrustc/minicargo)
+ DEBUG("Building " << outfile << " - Older than mrustc ( " << ts_result << " < " << this->get_timestamp(MRUSTC_PATH) << ")");
}
- //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)
@@ -290,7 +366,7 @@ bool Builder::spawn_process(const StringList& args, const ::helpers::path& logfi
char env[] =
"MRUSTC_DEBUG=""\0"
;
- CreateProcessA("x64\\Release\\mrustc.exe", (LPSTR)cmdline_str.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
+ CreateProcessA(MRUSTC_PATH, (LPSTR)cmdline_str.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
CloseHandle(si.hStdOutput);
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD status = 1;
@@ -348,18 +424,32 @@ bool Builder::spawn_process(const StringList& args, const ::helpers::path& logfi
return true;
}
-time_t Builder::get_timestamp(const ::helpers::path& path) const
+Builder::Timestamp Builder::get_timestamp(const ::helpers::path& path) const
{
#if _WIN32
+ FILETIME out;
+ auto handle = CreateFile(path.str().c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if(handle == INVALID_HANDLE_VALUE) {
+ //DEBUG("Can't find " << path);
+ return Timestamp::infinite_past();
+ }
+ if( GetFileTime(handle, NULL, NULL, &out) == FALSE ) {
+ //DEBUG("Can't GetFileTime on " << path);
+ CloseHandle(handle);
+ return Timestamp::infinite_past();
+ }
+ CloseHandle(handle);
+ //DEBUG(Timestamp{out} << " " << path);
+ return Timestamp { out };
#else
struct stat s;
if( stat(path.str().c_str(), &s) == 0 )
{
- return s.st_mtime;
+ return Timestamp { s.st_mtime };
}
else
{
- return 0;
+ return Timestamp::infinite_past();
}
#endif
}