diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-06-29 15:54:41 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-06-29 15:54:41 +0800 |
commit | 64af65a27097e17811c943dbac551ae741413954 (patch) | |
tree | 1ae96ce8b87ab54f03e06b47cca6b7981c43f7f6 | |
parent | 97763cebbdbe016a694840cc296c76b65576aa57 (diff) | |
download | mrust-64af65a27097e17811c943dbac551ae741413954.tar.gz |
Trans - Rework to potentially support dynamic libraries
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | minicargo.mk | 47 | ||||
-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 | ||||
-rw-r--r-- | tools/minicargo/build.cpp | 4 |
12 files changed, 139 insertions, 80 deletions
@@ -159,19 +159,19 @@ RUSTC_SRC_DL := $(RUSTCSRC)/dl-version MAKE_MINICARGO = $(MAKE) -f minicargo.mk RUSTC_VERSION=$(RUSTC_VERSION) RUSTC_CHANNEL=$(RUSTC_SRC_TY) OUTDIR_SUF=$(OUTDIR_SUF) -output$(OUTDIR_SUF)/libstd.hir: $(RUSTC_SRC_DL) $(BIN) +output$(OUTDIR_SUF)/libstd.rlib: $(RUSTC_SRC_DL) $(BIN) $(MAKE_MINICARGO) $@ -output$(OUTDIR_SUF)/libtest.hir output$(OUTDIR_SUF)/libpanic_unwind.hir output$(OUTDIR_SUF)/libproc_macro.hir: output$(OUTDIR_SUF)/libstd.hir +output$(OUTDIR_SUF)/libtest.rlib output$(OUTDIR_SUF)/libpanic_unwind.rlib output$(OUTDIR_SUF)/libproc_macro.rlib: output$(OUTDIR_SUF)/libstd.rlib $(MAKE_MINICARGO) $@ -output$(OUTDIR_SUF)/rustc output$(OUTDIR_SUF)/cargo: output$(OUTDIR_SUF)/libtest.hir +output$(OUTDIR_SUF)/rustc output$(OUTDIR_SUF)/cargo: output$(OUTDIR_SUF)/libtest.rlib $(MAKE_MINICARGO) $@ -TEST_DEPS := output$(OUTDIR_SUF)/libstd.hir output$(OUTDIR_SUF)/libtest.hir output$(OUTDIR_SUF)/libpanic_unwind.hir +TEST_DEPS := output$(OUTDIR_SUF)/libstd.rlib output$(OUTDIR_SUF)/libtest.rlib output$(OUTDIR_SUF)/libpanic_unwind.rlib ifeq ($(RUSTC_VERSION),1.19.0) TEST_DEPS += output$(OUTDIR_SUF)/librust_test_helpers.a endif -fcn_extcrate = $(patsubst %,output$(OUTDIR_SUF)/lib%.hir,$(1)) +fcn_extcrate = $(patsubst %,output$(OUTDIR_SUF)/lib%.rlib,$(1)) fn_getdeps = \ $(shell cat $1 \ diff --git a/minicargo.mk b/minicargo.mk index 14773e60..15b25336 100644 --- a/minicargo.mk +++ b/minicargo.mk @@ -43,7 +43,7 @@ LLVM_TARGETS ?= X86;ARM;AArch64#;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVP OVERRIDE_DIR := script-overrides/$(RUSTC_CHANNEL)-$(RUSTC_VERSION)$(OVERRIDE_SUFFIX)/ .PHONY: bin/mrustc tools/bin/minicargo -.PHONY: $(OUTDIR)libstd.hir $(OUTDIR)libtest.hir $(OUTDIR)libpanic_unwind.hir $(OUTDIR)libproc_macro.hir +.PHONY: $(OUTDIR)libstd.rlib $(OUTDIR)libtest.rlib $(OUTDIR)libpanic_unwind.rlib $(OUTDIR)libproc_macro.rlib .PHONY: $(OUTDIR)rustc $(OUTDIR)cargo .PHONY: all LIBS @@ -51,7 +51,7 @@ OVERRIDE_DIR := script-overrides/$(RUSTC_CHANNEL)-$(RUSTC_VERSION)$(OVERRIDE_SUF all: $(OUTDIR)rustc -LIBS: $(OUTDIR)libstd.hir $(OUTDIR)libtest.hir $(OUTDIR)libpanic_unwind.hir $(OUTDIR)libproc_macro.hir +LIBS: $(OUTDIR)libstd.rlib $(OUTDIR)libtest.rlib $(OUTDIR)libpanic_unwind.rlib $(OUTDIR)libproc_macro.rlib $(MRUSTC): $(MAKE) -f Makefile all @@ -64,20 +64,20 @@ $(MINICARGO): # Standard library crates # - libstd, libpanic_unwind, libtest and libgetopts # - libproc_macro (mrustc) -$(OUTDIR)libstd.hir: $(MRUSTC) $(MINICARGO) +$(OUTDIR)libstd.rlib: $(MRUSTC) $(MINICARGO) $(MINICARGO) $(RUSTCSRC)src/libstd --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) @test -e $@ -$(OUTDIR)libpanic_unwind.hir: $(MRUSTC) $(MINICARGO) $(OUTDIR)libstd.hir +$(OUTDIR)libpanic_unwind.rlib: $(MRUSTC) $(MINICARGO) $(OUTDIR)libstd.rlib $(MINICARGO) $(RUSTCSRC)src/libpanic_unwind --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) @test -e $@ -$(OUTDIR)libtest.hir: $(MRUSTC) $(MINICARGO) $(OUTDIR)libstd.hir $(OUTDIR)libpanic_unwind.hir +$(OUTDIR)libtest.rlib: $(MRUSTC) $(MINICARGO) $(OUTDIR)libstd.rlib $(OUTDIR)libpanic_unwind.rlib $(MINICARGO) $(RUSTCSRC)src/libtest --vendor-dir $(RUSTCSRC)src/vendor --output-dir $(OUTDIR) $(MINICARGO_FLAGS) @test -e $@ -$(OUTDIR)libgetopts.hir: $(MRUSTC) $(MINICARGO) $(OUTDIR)libstd.hir +$(OUTDIR)libgetopts.rlib: $(MRUSTC) $(MINICARGO) $(OUTDIR)libstd.rlib $(MINICARGO) $(RUSTCSRC)src/libgetopts --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) @test -e $@ # MRustC custom version of libproc_macro -$(OUTDIR)libproc_macro.hir: $(MRUSTC) $(MINICARGO) $(OUTDIR)libstd.hir +$(OUTDIR)libproc_macro.rlib: $(MRUSTC) $(MINICARGO) $(OUTDIR)libstd.rlib $(MINICARGO) lib/libproc_macro --output-dir $(OUTDIR) $(MINICARGO_FLAGS) @test -e $@ @@ -119,15 +119,36 @@ $(RUSTCSRC)build/Makefile: $(RUSTCSRC)src/llvm/CMakeLists.txt # # Developement-only targets # -$(OUTDIR)rustc-build/librustdoc.hir: $(MRUSTC) LIBS +$(OUTDIR)liballoc.rlib: $(MRUSTC) $(MINICARGO) + $(MINICARGO) $(RUSTCSRC)src/liballoc --script-overrides $(OVERRIDE_DIR) --output-dir $(OUTDIR) $(MINICARGO_FLAGS) +$(OUTDIR)rustc-build/librustdoc.rlib: $(MRUSTC) LIBS $(MINICARGO) $(RUSTCSRC)src/librustdoc --vendor-dir $(RUSTCSRC)src/vendor --output-dir $(dir $@) -L $(OUTDIR) $(MINICARGO_FLAGS) -#$(OUTDIR)cargo-build/libserde-1_0_6.hir: $(MRUSTC) LIBS +#$(OUTDIR)cargo-build/libserde-1_0_6.rlib: $(MRUSTC) LIBS # $(MINICARGO) $(RUSTCSRC)src/vendor/serde --vendor-dir $(RUSTCSRC)src/vendor --output-dir $(dir $@) -L $(OUTDIR) $(MINICARGO_FLAGS) -$(OUTDIR)cargo-build/libgit2-0_6_6.hir: $(MRUSTC) LIBS +$(OUTDIR)cargo-build/libgit2-0_6_6.rlib: $(MRUSTC) LIBS $(MINICARGO) $(RUSTCSRC)src/vendor/git2 --vendor-dir $(RUSTCSRC)src/vendor --output-dir $(dir $@) -L $(OUTDIR) --features ssh,https,curl,openssl-sys,openssl-probe $(MINICARGO_FLAGS) -$(OUTDIR)cargo-build/libserde_json-1_0_2.hir: $(MRUSTC) LIBS +$(OUTDIR)cargo-build/libserde_json-1_0_2.rlib: $(MRUSTC) LIBS $(MINICARGO) $(RUSTCSRC)src/vendor/serde_json --vendor-dir $(RUSTCSRC)src/vendor --output-dir $(dir $@) -L $(OUTDIR) $(MINICARGO_FLAGS) -$(OUTDIR)cargo-build/libcurl-0_4_6.hir: $(MRUSTC) LIBS +$(OUTDIR)cargo-build/libcurl-0_4_6.rlib: $(MRUSTC) LIBS $(MINICARGO) $(RUSTCSRC)src/vendor/curl --vendor-dir $(RUSTCSRC)src/vendor --output-dir $(dir $@) -L $(OUTDIR) $(MINICARGO_FLAGS) -$(OUTDIR)cargo-build/libterm-0_4_5.hir: $(MRUSTC) LIBS +$(OUTDIR)cargo-build/libterm-0_4_5.rlib: $(MRUSTC) LIBS $(MINICARGO) $(RUSTCSRC)src/vendor/term --vendor-dir $(RUSTCSRC)src/vendor --output-dir $(dir $@) -L $(OUTDIR) $(MINICARGO_FLAGS) + +# +# Testing +# +.PHONY: rust_tests-libs + +LIB_TESTS := alloc std +#LIB_TESTS += rustc_data_structures +rust_tests-libs: $(patsubst %,$(OUTDIR)stdtest/%-test_out.txt, $(LIB_TESTS)) + +RUNTIME_ARGS_$(OUTDIR)stdtest/alloc-test := --test-threads 1 +RUNTIME_ARGS_$(OUTdIR)stdtest/std-test := --test-threads 1 +RUNTIME_ARGS_$(OUTDIR)stdtest/std-test += --skip ::io::stdio::tests::panic_doesnt_poison # Requires destructors + +$(OUTDIR)stdtest/%-test: $(RUSTCSRC)src/lib%/lib.rs LIBS + $(MINICARGO) --test $(RUSTCSRC)src/lib$* --vendor-dir $(RUSTCSRC)src/vendor --output-dir $(dir $@) -L $(OUTDIR) +$(OUTDIR)%_out.txt: $(OUTDIR)% + @echo "--- [$<]" + $V./$< $(RUNTIME_ARGS_$<) > $@ || (tail -n 1 $@; mv $@ $@_fail; false) 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); diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp index 3b0b9c3e..c63a7115 100644 --- a/tools/minicargo/build.cpp +++ b/tools/minicargo/build.cpp @@ -644,7 +644,7 @@ Builder::Builder(const BuildOptions& opts, size_t total_targets): { case PackageTarget::CrateType::proc_macro: if(crate_type) *crate_type = "proc-macro"; - outfile /= ::format("lib", target.m_name, crate_suffix, ".hir"); // TODO: .rlib instead + outfile /= ::format("lib", target.m_name, crate_suffix, "-plugin" EXESUF); break; case PackageTarget::CrateType::dylib: //if(crate_type) *crate_type = "dylib"; @@ -652,7 +652,7 @@ Builder::Builder(const BuildOptions& opts, size_t total_targets): //break; case PackageTarget::CrateType::rlib: if(crate_type) *crate_type = "rlib"; - outfile /= ::format("lib", target.m_name, crate_suffix, ".hir"); // TODO: .rlib instead + outfile /= ::format("lib", target.m_name, crate_suffix, ".rlib"); break; default: throw ""; |