diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/crate.cpp | 8 | ||||
-rw-r--r-- | src/expand/proc_macro.cpp | 5 | ||||
-rw-r--r-- | src/hir/deserialise.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 48 | ||||
-rw-r--r-- | src/trans/codegen.cpp | 12 | ||||
-rw-r--r-- | src/trans/codegen.hpp | 2 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 75 | ||||
-rw-r--r-- | src/trans/codegen_mmir.cpp | 4 | ||||
-rw-r--r-- | src/trans/main_bindings.hpp | 2 |
9 files changed, 98 insertions, 60 deletions
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index 6abe6d59..8743ae2b 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -146,7 +146,7 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st else { ::std::vector<::std::string> paths; - auto direct_filename = FMT("lib" << name.c_str() << ".hir"); + auto direct_filename = FMT("lib" << name.c_str() << ".rlib"); auto name_prefix = FMT("lib" << name.c_str() << "-"); // Search a list of load paths for the crate for(const auto& p : g_crate_load_dirs) @@ -158,7 +158,7 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st } path = ""; - // Search for `p+"/lib"+name+"-*.hir" (which would match e.g. libnum-0.11.hir) + // Search for `p+"/lib"+name+"-*.rlib" (which would match e.g. libnum-0.11.rlib) auto dp = opendir(p.c_str()); if( !dp ) { continue ; @@ -168,11 +168,11 @@ RcString Crate::load_extern_crate(Span sp, const RcString& name, const ::std::st { // AND the start is "lib"+name size_t len = strlen(ent->d_name); - if( len <= 4 || strcmp(ent->d_name + len - 4, ".hir") != 0 ) + if( len <= 5 || strcmp(ent->d_name + len - 5, ".rlib") != 0 ) continue ; DEBUG(ent->d_name << " vs " << name_prefix); - // Check if the entry ends with .hir + // Check if the entry ends with .rlib if( strncmp(name_prefix.c_str(), ent->d_name, name_prefix.size()) != 0 ) continue ; diff --git a/src/expand/proc_macro.cpp b/src/expand/proc_macro.cpp index 82944857..a88102f7 100644 --- a/src/expand/proc_macro.cpp +++ b/src/expand/proc_macro.cpp @@ -259,7 +259,8 @@ ProcMacroInv ProcMacro_Invoke_int(const Span& sp, const ::AST::Crate& crate, con } // 2. Get executable and macro name - ::std::string proc_macro_exe_name = (ext_crate.m_filename + "-plugin"); + // TODO: Windows will have .exe? + ::std::string proc_macro_exe_name = ext_crate.m_filename; // 3. Create ProcMacroInv return ProcMacroInv(sp, proc_macro_exe_name.c_str(), *pmp); @@ -820,7 +821,7 @@ ProcMacroInv::ProcMacroInv(const Span& sp, const char* executable, const ::HIR:: int rv = posix_spawn(&this->child_pid, executable, &file_actions, nullptr, argv, environ); if( rv != 0 ) { - BUG(sp, "Error in posix_spawn - " << rv); + BUG(sp, "Error in posix_spawn - " << rv << " - can't start `" << executable << "`"); } posix_spawn_file_actions_destroy(&file_actions); diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index 75e08f16..5ab24c0f 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -1367,7 +1367,7 @@ { try { - ::HIR::serialise::Reader in{ filename }; + ::HIR::serialise::Reader in{ filename + ".hir" }; // HACK! HirDeserialiser s { in }; ::HIR::Crate rv = s.deserialise_crate(); diff --git a/src/main.cpp b/src/main.cpp index 28d34da4..f910ff56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -705,50 +705,38 @@ int main(int argc, char *argv[]) case ::AST::Crate::Type::Unknown: throw ""; case ::AST::Crate::Type::RustLib: - // Generate a loadable .o - CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".o", trans_opt, *hir_crate, items, /*is_executable=*/false); }); // Save a loadable HIR dump - CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile, *hir_crate); }); - // TODO: Link metatdata and object into a .rlib - //Trans_Link(params.outfile, params.outfile + ".hir", params.outfile + ".o", CodegenOutput::StaticLibrary); + CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile + ".hir", *hir_crate); }); + // Generate a loadable .o + CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, CodegenOutput::StaticLibrary, trans_opt, *hir_crate, items, params.outfile + ".hir"); }); break; case ::AST::Crate::Type::RustDylib: - // Generate a .so - //CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".so", trans_opt, *hir_crate, items, CodegenOutput::DynamicLibrary); }); - CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".o", trans_opt, *hir_crate, items, /*is_executable=*/false); }); // Save a loadable HIR dump - CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile, *hir_crate); }); - // TODO: Add the metadata to the .so as a non-loadable segment - //Trans_Link(params.outfile, params.outfile + ".hir", params.outfile + ".o", CodegenOutput::DynamicLibrary); + CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile + ".hir", *hir_crate); }); + // Generate a .so + CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, CodegenOutput::DynamicLibrary, trans_opt, *hir_crate, items, params.outfile + ".hir"); }); break; case ::AST::Crate::Type::CDylib: // Generate a .so/.dll - CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, trans_opt, *hir_crate, items, /*is_executable=*/false); }); - // - No metadata file - //Trans_Link(params.outfile, "", params.outfile + ".o", CodegenOutput::DynamicLibrary); + CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, CodegenOutput::DynamicLibrary, trans_opt, *hir_crate, items, ""); }); break; case ::AST::Crate::Type::ProcMacro: { // Needs: An executable (the actual macro handler), metadata (for `extern crate foo;`) - // 1. Generate code for the .o file - // TODO: Is the .o actually needed for proc macros? - CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + ".o", trans_opt, *hir_crate, items, /*is_executable=*/false); }); - - // 2. Generate code for the plugin itself - TransList items2 = CompilePhase<TransList>("Trans Enumerate", [&]() { return Trans_Enumerate_Main(*hir_crate); }); - CompilePhaseV("Trans Monomorph", [&]() { Trans_Monomorphise_List(*hir_crate, items2); }); - CompilePhaseV("MIR Optimise Inline", [&]() { MIR_OptimiseCrate_Inlining(*hir_crate, items2); }); - CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile + "-plugin", trans_opt, *hir_crate, items2, /*is_executable=*/true); }); - + // 1. Generate code for the plugin itself + TransList items = CompilePhase<TransList>("Trans Enumerate", [&]() { return Trans_Enumerate_Main(*hir_crate); }); + CompilePhaseV("Trans Monomorph", [&]() { Trans_Monomorphise_List(*hir_crate, items); }); + CompilePhaseV("MIR Optimise Inline", [&]() { MIR_OptimiseCrate_Inlining(*hir_crate, items); }); // - Save a very basic HIR dump, making sure that there's no lang items in it (e.g. `mrustc-main`) - hir_crate->m_lang_items.clear(); - CompilePhaseV("HIR Serialise", [&]() { HIR_Serialise(params.outfile, *hir_crate); }); - //Trans_Link(params.outfile, params.outfile + ".hir", params.outfile + ".o", CodegenOutput::StaticLibrary); - //Trans_Link(params.outfile+"-plugin", "", params.outfile + "-plugin.o", CodegenOutput::StaticLibrary); + CompilePhaseV("HIR Serialise", [&]() { + auto saved_lang_items = ::std::move(hir_crate->m_lang_items); hir_crate->m_lang_items.clear(); + HIR_Serialise(params.outfile + ".hir", *hir_crate); + hir_crate->m_lang_items = ::std::move(saved_lang_items); + }); + CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, CodegenOutput::Executable, trans_opt, *hir_crate, items, params.outfile + ".hir"); }); break; } case ::AST::Crate::Type::Executable: - CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, trans_opt, *hir_crate, items, /*is_executable=*/true); }); - //Trans_Link(params.outfile, "", params.outfile + ".o", CodegenOutput::Executable); + CompilePhaseV("Trans Codegen", [&]() { Trans_Codegen(params.outfile, CodegenOutput::Executable, trans_opt, *hir_crate, items, ""); }); break; } } diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index b2b614a9..3a75e623 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -15,19 +15,23 @@ #include "codegen.hpp" #include "monomorphise.hpp" -void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const ::HIR::Crate& crate, const TransList& list, bool is_executable) +void Trans_Codegen(const ::std::string& outfile, CodegenOutput out_ty, const TransOptions& opt, const ::HIR::Crate& crate, const TransList& list, const ::std::string& hir_file) { static Span sp; - ::std::unique_ptr<CodeGenerator> codegen; + ::std::unique_ptr<CodeGenerator> codegen; if( opt.mode == "monomir" ) { codegen = Trans_Codegen_GetGenerator_MonoMir(crate, outfile); } - else + else if( opt.mode == "c" ) { codegen = Trans_Codegen_GetGeneratorC(crate, outfile); } + else + { + BUG(sp, "Unknown codegen mode '" << opt.mode << "'"); + } // 1. Emit structure/type definitions. // - Emit in the order they're needed. @@ -189,6 +193,6 @@ void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const } } - codegen->finalise(is_executable, opt); + codegen->finalise(opt, out_ty, hir_file); } diff --git a/src/trans/codegen.hpp b/src/trans/codegen.hpp index b769e350..070e0232 100644 --- a/src/trans/codegen.hpp +++ b/src/trans/codegen.hpp @@ -27,7 +27,7 @@ class CodeGenerator { public: virtual ~CodeGenerator() {} - virtual void finalise(bool is_executable, const TransOptions& opt) {} + virtual void finalise(const TransOptions& opt, CodegenOutput out_ty, const ::std::string& hir_file) {} // Called on all types directly mentioned (e.g. variables, arguments, and fields) // - Inner-most types are visited first. diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index c148c51f..b9f3f3ac 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -607,7 +607,7 @@ namespace { ~CodeGenerator_C() {} - void finalise(bool is_executable, const TransOptions& opt) override + void finalise(const TransOptions& opt, CodegenOutput out_ty, const ::std::string& hir_file) override { // Emit box drop glue after everything else to avoid definition ordering issues for(auto& e : m_box_glue_todo) @@ -615,10 +615,12 @@ namespace { emit_box_drop_glue( mv$(e.first), *e.second ); } + const bool create_shims = (out_ty == CodegenOutput::Executable); + // TODO: Support dynamic libraries too // - No main, but has the rest. // - Well... for cdylibs that's the case, for rdylibs it's not - if( is_executable ) + if( out_ty == CodegenOutput::Executable ) { // TODO: Define this function in MIR? m_of << "int main(int argc, const char* argv[]) {\n"; @@ -634,7 +636,11 @@ namespace { m_of << "\treturn " << Trans_Mangle(::HIR::GenericPath(c_start_path)) << "(argc, argv);\n"; } m_of << "}\n"; + } + // Auto-generated code/items for the "root" rust binary (cdylib or executable) + if( create_shims ) + { if( m_compiler == Compiler::Gcc ) { m_of @@ -643,7 +649,7 @@ namespace { ; } - // Allocator shims + // Allocator/panic shims if( TARGETVER_1_29 ) { const char* alloc_prefix = "__rdl_"; @@ -796,10 +802,23 @@ namespace { args.push_back("-g"); } args.push_back("-o"); - args.push_back(m_outfile_path .c_str()); + switch(out_ty) + { + case CodegenOutput::DynamicLibrary: + case CodegenOutput::Executable: + case CodegenOutput::Object: + args.push_back(m_outfile_path .c_str()); + break; + case CodegenOutput::StaticLibrary: + args.push_back(m_outfile_path+".o"); + break; + } args.push_back(m_outfile_path_c.c_str()); - if( is_executable ) + switch(out_ty) { + case CodegenOutput::DynamicLibrary: + args.push_back("-shared"); + case CodegenOutput::Executable: for( const auto& crate : m_crate.m_ext_crates ) { args.push_back(crate.second.m_path + ".o"); @@ -827,10 +846,12 @@ namespace { { args.push_back( a.c_str() ); } - } - else - { + // TODO: Include the HIR file as a magic object? + break; + case CodegenOutput::StaticLibrary: + case CodegenOutput::Object: args.push_back("-c"); + break; } break; case Compiler::Msvc: @@ -857,13 +878,25 @@ namespace { args.push_back("/DEBUG"); args.push_back("/Zi"); } - if(is_executable) + switch(out_ty) { + case CodegenOutput::Executable: + case CodegenOutput::DynamicLibrary: + switch(out_ty) + { + case CodegenOutput::Executable: + args.push_back("/link"); + break; + case CodegenOutput::DynamicLibrary: + args.push_back("/LD"); + break; + } + args.push_back(FMT("/Fe" << m_outfile_path)); for( const auto& crate : m_crate.m_ext_crates ) { - args.push_back(crate.second.m_path + ".o"); + args.push_back(crate.second.m_path + ".obj"); } // Crate-specified libraries for(const auto& lib : m_crate.m_ext_libs) { @@ -883,18 +916,20 @@ namespace { } args.push_back("kernel32.lib"); // Needed for Interlocked* - args.push_back("/link"); - // Command-line specified linker search directories for(const auto& path : link_dirs ) { args.push_back(FMT("/LIBPATH:" << path)); } - } - else - { + break; + case CodegenOutput::StaticLibrary: + args.push_back("/c"); + args.push_back(FMT("/Fo" << m_outfile_path << ".obj")); + break; + case CodegenOutput::Object: args.push_back("/c"); args.push_back(FMT("/Fo" << m_outfile_path)); + break; } break; } @@ -939,6 +974,16 @@ namespace { exit(1); } } + + // HACK! Static libraries aren't implemented properly yet, just touch the output file + if( out_ty == CodegenOutput::StaticLibrary ) + { + ::std::ofstream of( m_outfile_path ); + if( !of.good() ) + { + // TODO: Error? + } + } } void emit_box_drop(unsigned indent_level, const ::HIR::TypeRef& inner_type, const ::MIR::LValue& slot, bool run_destructor) diff --git a/src/trans/codegen_mmir.cpp b/src/trans/codegen_mmir.cpp index 23f333fd..76d79e93 100644 --- a/src/trans/codegen_mmir.cpp +++ b/src/trans/codegen_mmir.cpp @@ -156,9 +156,9 @@ namespace } } - void finalise(bool is_executable, const TransOptions& opt) override + void finalise(const TransOptions& opt, CodegenOutput out_ty, const ::std::string& hir_file) override { - if( is_executable ) + if( out_ty == CodegenOutput::Executable ) { m_of << "fn ::main#(isize, *const *const i8): isize {\n"; auto c_start_path = m_resolve.m_crate.get_lang_item_path_opt("mrustc-start"); diff --git a/src/trans/main_bindings.hpp b/src/trans/main_bindings.hpp index 096efe86..af33ef35 100644 --- a/src/trans/main_bindings.hpp +++ b/src/trans/main_bindings.hpp @@ -42,4 +42,4 @@ extern void Trans_AutoImpls(::HIR::Crate& crate, TransList& trans_list); extern void Trans_Monomorphise_List(const ::HIR::Crate& crate, TransList& list); -extern void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const ::HIR::Crate& crate, const TransList& list, bool is_executable); +extern void Trans_Codegen(const ::std::string& outfile, CodegenOutput out_ty, const TransOptions& opt, const ::HIR::Crate& crate, const TransList& list, const ::std::string& hir_file); |