// The front-end.
// Its job, as of now, is to take the source file name from the command line,
// and compile it into an executable file of the same name, with the .out suffix.
//
// There is zero goal of portability yet, all of this is linux specific.
//
// It will become more sophisticated later on as library facilities become available
// and allow to implement more intelligence here.
// Create the module
var module = CGModuleCreate( SourceToCompile )
// Setup the target.
if !CGModuleSetupTarget( module )
{
Print( "Failed to setup llvm target.\n" )
return 1
}
// Define the exit external function.
using exit = ExternalFunction( void( uint( 32 ) returnCode ), "_exit" )
using main = #CompileFileToFunction( SourceToCompile, uint( 32 ), 0, () )
// The entry point of the binary.
// We have to use "using" and an anonymous function, because otherwise
// it would create an overloadset and CGGenerateFunction wouldn't know
// how to deal with that.
// This is basically the "crt0". Dunno yet if it's a good idea to build it myself
// or just to link to an existing crt0.o. This has the advantage of flexibility
// to add features later on, but may require more compile time conditional magic
// to handle various platforms.
// Right now it has the advantage of avoiding yet another external dependency.
using entryPoint = void()
{
exit( main() )
}
if !CGGenerateFunction( module, entryPoint, "_start" )
{
Print( "Frontend: codegen failed.\n" )
return 1
}
// Run the llvm optimization passes
CGModuleOptimize( module )
// Output the llvm ir and the asm for inspection.
CGModuleEmitLLVMIr( module, strcat( SourceToCompile, ".ll" ) )
if !CGModuleEmitAsm( module, strcat( SourceToCompile, ".s" ) )
{
Print( strcat( "Failed to write ", strcat( SourceToCompile, ".s\n" ) ) )
return 1
}
// Output the object file.
if !CGModuleEmitObj( module, strcat( SourceToCompile, ".o" ) )
{
Print( strcat( "Failed to write ", strcat( SourceToCompile, ".o\n" ) ) )
return 1
}
// Link it and produce an executable file.
var linkerArgs = (
strcat( SourceToCompile, ".o" ),
"-o", strcat( SourceToCompile, ".out" ),
"-L/lib/x86_64-linux-gnu", "-lc",
"--dynamic-linker=/lib64/ld-linux-x86-64.so.2"
)
if !CGLinkerELF( linkerArgs )
return 1
Print( strcat( "Built executable ", strcat( SourceToCompile, ".out\n" ) ) )