diff --git a/divine/cc/native.cpp b/divine/cc/native.cpp index 16ac94e10c9bcca50e916764a21c0b9b61355da0..7fc4e1162fa8bfc09cd045bcb5751dfef8f44a12 100644 --- a/divine/cc/native.cpp +++ b/divine/cc/native.cpp @@ -16,11 +16,16 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <divine/cc/driver.hpp> #include <divine/cc/codegen.hpp> #include <divine/cc/link.hpp> #include <divine/cc/native.hpp> #include <divine/cc/options.hpp> +DIVINE_RELAX_WARNINGS +#include "lld/Common/Driver.h" +DIVINE_UNRELAX_WARNINGS + #include <brick-proc> namespace divine::cc @@ -38,4 +43,52 @@ namespace divine::cc } return 0; } + + void Native::init_ld_args() + { + _ld_args = cc::ld_args( _po, _files ); + } + + void Native::link() + { + auto drv = std::make_unique< cc::Driver >( _clang.context() ); + std::vector< const char * > ld_args_c; + + ld_args_c.reserve( _ld_args.size() ); + for ( size_t i = 0; i < _ld_args.size(); ++i ) + ld_args_c.push_back( _ld_args[i].c_str() ); + + auto ld_job = drv->getJobs( ld_args_c ).back(); + if ( _po.use_system_ld ) + { + ld_job.args.insert( ld_job.args.begin(), ld_job.name ); + auto r = brick::proc::spawnAndWait( brick::proc::CaptureStderr, ld_job.args ); + if ( !r ) + throw cc::CompileError( "failed to link, ld exited with " + to_string( r ) ); + } + else + { + ld_job.args.insert( ld_job.args.begin(), "divcc" ); + std::vector< const char * > lld_job_c; + lld_job_c.reserve( ld_job.args.size() ); + for ( size_t i = 0; i < ld_job.args.size(); ++i ) + lld_job_c.push_back( ld_job.args[i].c_str() ); + + bool linked = lld::elf::link( lld_job_c, false ); + if ( !linked ) + throw cc::CompileError( "lld failed, not linked" ); + } + } + + Native::~Native() + { + if ( !_po.toObjectOnly ) + for ( auto file : _files ) + { + if ( cc::is_object_type( file.first ) ) + continue; + std::string ofn = file.second; + unlink( ofn.c_str() ); + } + } } diff --git a/divine/cc/native.hpp b/divine/cc/native.hpp index feadce62d3958d29be1ddbd4e8cb841fd6c93e68..feb235f6412e654d5379ecc87ca7a0acd30d0166 100644 --- a/divine/cc/native.hpp +++ b/divine/cc/native.hpp @@ -33,11 +33,14 @@ namespace divine::cc struct Native { int compileFiles(); + void init_ld_args(); + void link(); cc::ParsedOpts _po; PairedFiles _files; std::vector< std::string > _ld_args; cc::CC1 _clang; - bool _cxx; + + ~Native(); }; } diff --git a/tools/divcc.cpp b/tools/divcc.cpp index 156b24f7eee1df3ba3237c4e9d954a1e8257050c..681306f913c4b3587f0f3caebf15b3905f373cff 100644 --- a/tools/divcc.cpp +++ b/tools/divcc.cpp @@ -33,7 +33,7 @@ DIVINE_RELAX_WARNINGS #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Object/IRObjectFile.h" #include "llvm-c/Target.h" -#include "lld/Common/Driver.h" + DIVINE_UNRELAX_WARNINGS #include <brick-llvm> @@ -69,56 +69,6 @@ auto link_dios_native( std::vector< std::string > &args, bool cxx ) return tmpdir; } -int link( cc::ParsedOpts& po, cc::CC1& clang, cc::PairedFiles& objFiles, bool cxx = false ) -{ - auto drv = std::make_unique< cc::Driver >( clang.context() ); - std::vector< const char * > ld_args_c; - - std::vector< std::string > args = cc::ld_args( po, objFiles ); - - auto tmpdir = link_dios_native( args, cxx ); - ld_args_c.reserve( args.size() ); - for ( size_t i = 0; i < args.size(); ++i ) - ld_args_c.push_back( args[i].c_str() ); - - auto ld_job = drv->getJobs( ld_args_c ).back(); - if ( po.use_system_ld ) - { - ld_job.args.insert( ld_job.args.begin(), ld_job.name ); - auto r = brick::proc::spawnAndWait( brick::proc::CaptureStderr, ld_job.args ); - if ( !r ) - throw cc::CompileError( "failed to link, ld exited with " + to_string( r ) ); - } - else - { - ld_job.args.insert( ld_job.args.begin(), "divcc" ); - std::vector< const char * > lld_job_c; - lld_job_c.reserve( ld_job.args.size() ); - for ( size_t i = 0; i < ld_job.args.size(); ++i ) - lld_job_c.push_back( ld_job.args[i].c_str() ); - - bool linked = lld::elf::link( lld_job_c, false ); - if ( !linked ) - throw cc::CompileError( "lld failed, not linked" ); - } - - std::unique_ptr< llvm::Module > mod = cc::link_bitcode< rt::DiosCC, true >( objFiles, clang, po.libSearchPath ); - std::string file_out = po.outputFile != "" ? po.outputFile : "a.out"; - - cc::addSection( file_out, cc::llvm_section_name, clang.serializeModule( *mod ) ); - - for ( auto file : objFiles ) - { - if ( cc::is_object_type( file.first ) ) - continue; - std::string ofn = file.second; - unlink( ofn.c_str() ); - } - - return 0; -} - - /* usage: same as gcc */ int main( int argc, char **argv ) { @@ -137,11 +87,11 @@ int main( int argc, char **argv ) using namespace brick::fs; using divine::rt::includeDir; - auto drv = std::make_unique< cc::Driver >( clang.context() ); + auto driver = std::make_unique< cc::Driver >( clang.context() ); po.opts.insert( po.opts.end(), - drv->commonFlags.begin(), - drv->commonFlags.end() ); + driver->commonFlags.begin(), + driver->commonFlags.end() ); po.opts.insert( po.opts.end(), { "-isystem", joinPath( includeDir, "libcxx/include" ) @@ -215,7 +165,15 @@ int main( int argc, char **argv ) else { nativeCC.compileFiles(); - return link( po, clang, pairedFiles, brick::string::endsWith( argv[0], "divc++" ) ); + nativeCC.init_ld_args(); + auto tmpdir = link_dios_native( nativeCC._ld_args, brick::string::endsWith( argv[0], "divc++" ) ); + nativeCC.link(); + + std::unique_ptr< llvm::Module > mod = cc::link_bitcode< rt::DiosCC, true >( pairedFiles, clang, po.libSearchPath ); + std::string file_out = po.outputFile != "" ? po.outputFile : "a.out"; + + cc::addSection( file_out, cc::llvm_section_name, clang.serializeModule( *mod ) ); + return 0; } } catch ( cc::CompileError &err ) {