summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/common/path.h7
-rw-r--r--tools/common/target_detect.h11
-rw-r--r--tools/common/toml.cpp85
-rw-r--r--tools/common/toml.h21
-rw-r--r--tools/minicargo/build.cpp76
-rw-r--r--tools/minicargo/main.cpp4
-rw-r--r--tools/minicargo/manifest.cpp6
7 files changed, 154 insertions, 56 deletions
diff --git a/tools/common/path.h b/tools/common/path.h
index eae4951f..1ad6f506 100644
--- a/tools/common/path.h
+++ b/tools/common/path.h
@@ -38,6 +38,13 @@ public:
return m_str != "";
}
+ bool operator==(const path& p) const {
+ return m_str == p.m_str;
+ }
+ bool operator!=(const path& p) const {
+ return m_str != p.m_str;
+ }
+
path& operator/=(const path& p)
{
if(!p.is_valid())
diff --git a/tools/common/target_detect.h b/tools/common/target_detect.h
index a4c44ba4..1bfc7dd9 100644
--- a/tools/common/target_detect.h
+++ b/tools/common/target_detect.h
@@ -24,6 +24,8 @@
# define DEFAULT_TARGET_NAME "arm-linux-gnu"
# elif defined(__i386__)
# define DEFAULT_TARGET_NAME "i586-linux-gnu"
+# elif defined(__m68k__)
+# define DEFAULT_TARGET_NAME "m68k-linux-gnu"
# else
# warning "Unable to detect a suitable default target (linux-gnu)"
# endif
@@ -73,6 +75,15 @@
// - Apple devices
#elif defined(__APPLE__)
# define DEFAULT_TARGET_NAME "x86_64-apple-macosx"
+// - Haiku
+#elif defined(__HAIKU__)
+# if defined(__x86_64__)
+# define DEFAULT_TARGET_NAME "x86_64-unknown-haiku"
+# elif defined(__arm__)
+# define DEFAULT_TARGET_NAME "arm-unknown-haiku"
+# else
+# warning "Unable to detect a suitable default target (Haiku)"
+# endif
// - Unknown
#else
# warning "Unable to detect a suitable default target"
diff --git a/tools/common/toml.cpp b/tools/common/toml.cpp
index 7e24b610..4e8e6da6 100644
--- a/tools/common/toml.cpp
+++ b/tools/common/toml.cpp
@@ -80,11 +80,8 @@ struct Token
};
TomlFile::TomlFile(const ::std::string& filename):
- m_if(filename)
+ m_lexer(filename)
{
- if( !m_if.is_open() ) {
- throw ::std::runtime_error("Unable to open file '" + filename + "'");
- }
}
TomlFileIter TomlFile::begin()
{
@@ -99,12 +96,14 @@ TomlFileIter TomlFile::end()
TomlKeyValue TomlFile::get_next_value()
{
- auto t = Token::lex_from(m_if);
+ auto t = m_lexer.get_token();
if(m_current_composite.empty())
{
while( t.m_type == Token::Type::Newline )
- t = Token::lex_from(m_if);
+ {
+ t = m_lexer.get_token();
+ }
// Expect '[', a string, or an identifier
switch(t.m_type)
@@ -116,32 +115,32 @@ TomlKeyValue TomlFile::get_next_value()
m_current_block.clear();
do
{
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
bool is_array = false;
if(t.m_type == Token::Type::SquareOpen)
{
is_array = true;
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
}
assert(t.m_type == Token::Type::Ident || t.m_type == Token::Type::String);
m_current_block.push_back(t.as_string());
if(is_array)
{
m_current_block.push_back(::format(m_array_counts[t.as_string()]++));
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
assert(t.m_type == Token::Type::SquareClose);
}
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
} while(t.m_type == Token::Type::Dot);
if( t.m_type != Token::Type::SquareClose )
{
- throw ::std::runtime_error(::format("Unexpected token in block header - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in block header - ", t));
}
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
if (t.m_type != Token::Type::Newline)
{
- throw ::std::runtime_error(::format("Unexpected token after block block - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token after block block - ", t));
}
DEBUG("Start block " << m_current_block);
// Recurse!
@@ -156,7 +155,7 @@ TomlKeyValue TomlFile::get_next_value()
if( t.m_type == Token::Type::Eof )
{
// EOF isn't allowed here
- throw ::std::runtime_error(::format("Unexpected EOF in composite"));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected EOF in composite"));
}
}
switch (t.m_type)
@@ -165,14 +164,14 @@ TomlKeyValue TomlFile::get_next_value()
case Token::Type::Ident:
break;
default:
- throw ::std::runtime_error(::format("Unexpected token for key - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token for key - ", t));
}
::std::string key_name = t.as_string();
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
if(t.m_type != Token::Type::Assign)
- throw ::std::runtime_error(::format("Unexpected token after key - ", t));
- t = Token::lex_from(m_if);
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token after key - ", t));
+ t = m_lexer.get_token();
// --- Value ---
TomlKeyValue rv;
@@ -193,10 +192,12 @@ TomlKeyValue TomlFile::get_next_value()
rv.path.push_back(key_name);
rv.value.m_type = TomlValue::Type::List;
- while( (t = Token::lex_from(m_if)).m_type != Token::Type::SquareClose )
+ while( (t = m_lexer.get_token()).m_type != Token::Type::SquareClose )
{
while( t.m_type == Token::Type::Newline )
- t = Token::lex_from(m_if);
+ {
+ t = m_lexer.get_token();
+ }
if( t.m_type == Token::Type::SquareClose )
break;
@@ -208,15 +209,15 @@ TomlKeyValue TomlFile::get_next_value()
rv.value.m_sub_values.push_back(TomlValue { t.as_string() });
break;
default:
- throw ::std::runtime_error(::format("Unexpected token in array value position - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in array value position - ", t));
}
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
if(t.m_type != Token::Type::Comma)
break;
}
if(t.m_type != Token::Type::SquareClose)
- throw ::std::runtime_error(::format("Unexpected token after array - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token after array - ", t));
break;
case Token::Type::BraceOpen:
m_current_composite.push_back(key_name);
@@ -228,7 +229,7 @@ TomlKeyValue TomlFile::get_next_value()
rv.path.insert(rv.path.end(), m_current_composite.begin(), m_current_composite.end());
rv.path.push_back(key_name);
rv.value = TomlValue { t.m_intval };
- return rv;
+ break;
case Token::Type::Ident:
if( t.m_data == "true" )
{
@@ -247,33 +248,57 @@ TomlKeyValue TomlFile::get_next_value()
}
else
{
- throw ::std::runtime_error(::format("Unexpected identifier in value position - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected identifier in value position - ", t));
}
break;
default:
- throw ::std::runtime_error(::format("Unexpected token in value position - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in value position - ", t));
}
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
while (!m_current_composite.empty() && t.m_type == Token::Type::BraceClose)
{
DEBUG("Leave composite block " << m_current_block << ", " << m_current_composite);
m_current_composite.pop_back();
- t = Token::lex_from(m_if);
+ t = m_lexer.get_token();
}
if( m_current_composite.empty() )
{
if(t.m_type != Token::Type::Newline && t.m_type != Token::Type::Eof)
- throw ::std::runtime_error(::format("Unexpected token in TOML file after entry - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in TOML file after entry - ", t));
}
else
{
if( t.m_type != Token::Type::Comma )
- throw ::std::runtime_error(::format("Unexpected token in TOML file after composite entry - ", t));
+ throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in TOML file after composite entry - ", t));
}
return rv;
}
+TomlLexer::TomlLexer(const ::std::string& filename)
+ :m_if(filename)
+ ,m_filename(filename)
+ ,m_line(1)
+{
+ if( !m_if.is_open() ) {
+ throw ::std::runtime_error("Unable to open file '" + filename + "'");
+ }
+}
+Token TomlLexer::get_token()
+{
+ auto rv = Token::lex_from(m_if);
+ if( rv.m_type == Token::Type::Newline )
+ {
+ m_line ++;
+ }
+ return rv;
+}
+::std::ostream& operator<<(::std::ostream& os, const TomlLexer& x)
+{
+ os << x.m_filename << ":" << x.m_line;
+ return os;
+}
+
Token Token::lex_from(::std::ifstream& is)
{
auto rv = Token::lex_from_inner(is);
diff --git a/tools/common/toml.h b/tools/common/toml.h
index 4c97e7f2..17e05142 100644
--- a/tools/common/toml.h
+++ b/tools/common/toml.h
@@ -15,11 +15,28 @@
class TomlFileIter;
struct TomlKeyValue;
-class TomlFile
+struct Token;
+class TomlLexer
{
+ friend class TomlFile;
/// Input file stream
::std::ifstream m_if;
+ ::std::string m_filename;
+ unsigned m_line;
+protected:
+ TomlLexer(const ::std::string& filename);
+ Token get_token();
+
+public:
+ friend ::std::ostream& operator<<(::std::ostream& os, const TomlLexer& x);
+};
+
+class TomlFile
+{
+ /// Input file stream
+ TomlLexer m_lexer;
+
/// Name of the current `[]` block
::std::vector<::std::string> m_current_block;
@@ -40,6 +57,8 @@ public:
// Obtain the next value in the file
TomlKeyValue get_next_value();
+
+ const TomlLexer& lexer() const;
};
struct TomlValue
diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp
index 04a9a507..5eb07104 100644
--- a/tools/minicargo/build.cpp
+++ b/tools/minicargo/build.cpp
@@ -31,6 +31,7 @@ extern int _putenv_s(const char*, const char*);
# include <mutex>
# include <condition_variable>
#endif
+#include <fstream>
#include <climits>
#include <cassert>
#ifdef _WIN32
@@ -67,6 +68,9 @@ class Builder
::helpers::path m_compiler_path;
size_t m_total_targets;
mutable size_t m_targets_built;
+#ifndef _WIN32
+ mutable ::std::mutex chdir_mutex;
+#endif
public:
Builder(const BuildOptions& opts, size_t total_targets);
@@ -78,7 +82,7 @@ public:
private:
::helpers::path get_crate_path(const PackageManifest& manifest, const PackageTarget& target, bool is_for_host, const char** crate_type, ::std::string* out_crate_suffix) const;
bool spawn_process_mrustc(const StringList& args, StringListKV env, const ::helpers::path& logfile) const;
- bool spawn_process(const char* exe_name, const StringList& args, const StringListKV& env, const ::helpers::path& logfile) const;
+ bool spawn_process(const char* exe_name, const StringList& args, const StringListKV& env, const ::helpers::path& logfile, const ::helpers::path& working_directory={}) const;
::helpers::path build_and_run_script(const PackageManifest& manifest, bool is_for_host) const;
@@ -566,6 +570,11 @@ Builder::Builder(const BuildOptions& opts, size_t total_targets):
m_total_targets(total_targets),
m_targets_built(0)
{
+ if( const char* override_path = getenv("MRUSTC_PATH") ) {
+ m_compiler_path = override_path;
+ return ;
+ }
+ // TODO: Clean this stuff up
#ifdef _WIN32
char buf[1024];
size_t s = GetModuleFileName(NULL, buf, sizeof(buf)-1);
@@ -1000,6 +1009,10 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget&
args.push_back("--crate-type"); args.push_back("bin");
args.push_back("-o"); args.push_back(outfile);
args.push_back("-L"); args.push_back(this->get_output_dir(true).str()); // NOTE: Forces `is_for_host` to true here.
+ if( true )
+ {
+ args.push_back("-g");
+ }
for(const auto& d : m_opts.lib_search_dirs)
{
args.push_back("-L");
@@ -1102,23 +1115,31 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget&
}
//auto _ = ScopedChdir { manifest.directory() };
- #if _WIN32
- #else
- auto fd_cwd = open(".", O_DIRECTORY);
- chdir(manifest.directory().str().c_str());
- #endif
- if( !this->spawn_process(script_exe_abs.str().c_str(), {}, env, out_file) )
+ if( !this->spawn_process(script_exe_abs.str().c_str(), {}, env, out_file, /*working_directory=*/manifest.directory()) )
{
- rename(out_file.str().c_str(), (out_file+"_failed").str().c_str());
+ auto failed_filename = out_file+"_failed.txt";
+ remove(failed_filename.str().c_str());
+ rename(out_file.str().c_str(), failed_filename.str().c_str());
+
+ ::std::cerr << "Calling " << script_exe_abs << " failed" << ::std::endl;
+ {
+ ::std::ifstream ifs(failed_filename);
+ char linebuf[1024];
+ while( ifs.good() && !ifs.eof() )
+ {
+ ifs.getline(linebuf, sizeof(linebuf)-1);
+ if( strncmp(linebuf, "cargo:", 6) == 0 ) {
+ continue;
+ }
+ ::std::cerr << "> " << linebuf << ::std::endl;
+ }
+ }
+
// Build failed, return an invalid path
- return ::helpers::path();;
+ return ::helpers::path();
}
- #if _WIN32
- #else
- fchdir(fd_cwd);
- #endif
}
-
+
return out_file;
}
bool Builder::build_library(const PackageManifest& manifest, bool is_for_host, size_t index) const
@@ -1154,7 +1175,7 @@ bool Builder::spawn_process_mrustc(const StringList& args, StringListKV env, con
//env.push_back("MRUSTC_DEBUG", "");
return spawn_process(m_compiler_path.str().c_str(), args, env, logfile);
}
-bool Builder::spawn_process(const char* exe_name, const StringList& args, const StringListKV& env, const ::helpers::path& logfile) const
+bool Builder::spawn_process(const char* exe_name, const StringList& args, const StringListKV& env, const ::helpers::path& logfile, const ::helpers::path& working_directory/*={}*/) const
{
#ifdef _WIN32
::std::stringstream cmdline;
@@ -1206,14 +1227,14 @@ bool Builder::spawn_process(const char* exe_name, const StringList& args, const
WriteFile(si.hStdOutput, "\n", 1, &tmp, NULL);
}
PROCESS_INFORMATION pi = { 0 };
- CreateProcessA(exe_name, (LPSTR)cmdline_str.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
+ CreateProcessA(exe_name, (LPSTR)cmdline_str.c_str(), NULL, NULL, TRUE, 0, NULL, (working_directory != ::helpers::path() ? working_directory.str().c_str() : NULL), &si, &pi);
CloseHandle(si.hStdOutput);
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD status = 1;
GetExitCodeProcess(pi.hProcess, &status);
if (status != 0)
{
- DEBUG("Compiler exited with non-zero exit status " << status);
+ DEBUG("Process exited with non-zero exit status " << status);
return false;
}
#else
@@ -1270,12 +1291,23 @@ bool Builder::spawn_process(const char* exe_name, const StringList& args, const
// });
envp.push_back(nullptr);
- if( posix_spawn(&pid, exe_name, &fa, /*attr=*/nullptr, (char* const*)argv.data(), (char* const*)envp.get_vec().data()) != 0 )
+ // TODO: Acquire a lock
{
- ::std::cerr << "Unable to run process '" << exe_name << "' - " << strerror(errno) << ::std::endl;
- DEBUG("Unable to spawn executable");
- posix_spawn_file_actions_destroy(&fa);
- return false;
+ ::std::lock_guard<::std::mutex> lh { this->chdir_mutex };
+ auto fd_cwd = open(".", O_DIRECTORY);
+ if( working_directory != ::helpers::path() ) {
+ chdir(working_directory.str().c_str());
+ }
+ if( posix_spawn(&pid, exe_name, &fa, /*attr=*/nullptr, (char* const*)argv.data(), (char* const*)envp.get_vec().data()) != 0 )
+ {
+ ::std::cerr << "Unable to run process '" << exe_name << "' - " << strerror(errno) << ::std::endl;
+ DEBUG("Unable to spawn executable");
+ posix_spawn_file_actions_destroy(&fa);
+ return false;
+ }
+ if( working_directory != ::helpers::path() ) {
+ fchdir(fd_cwd);
+ }
}
posix_spawn_file_actions_destroy(&fa);
int status = -1;
diff --git a/tools/minicargo/main.cpp b/tools/minicargo/main.cpp
index 7065b7f5..4e929653 100644
--- a/tools/minicargo/main.cpp
+++ b/tools/minicargo/main.cpp
@@ -9,9 +9,9 @@
#include <iostream>
#include <cstring> // strcmp
#include <map>
-#include "debug.h"
+#include <debug.h>
#include "manifest.h"
-#include "helpers.h"
+#include <helpers.h>
#include "repository.h"
#include "build.h"
diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp
index 8c0a7f44..edebd71a 100644
--- a/tools/minicargo/manifest.cpp
+++ b/tools/minicargo/manifest.cpp
@@ -317,7 +317,7 @@ 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 there's no binary section, but src/main.rs exists, add as a binary
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
@@ -327,6 +327,10 @@ PackageManifest PackageManifest::load_from_toml(const ::std::string& path)
rv.m_targets.push_back(PackageTarget { PackageTarget::Type::Bin });
}
}
+ if( rv.m_targets.empty() )
+ {
+ throw ::std::runtime_error(format("Manifest file ", path, " didn't specify any targets (and src/{main,lib}.rs doesn't exist)"));
+ }
// Default target names
for(auto& tgt : rv.m_targets)