@@ -77,6 +77,7 @@ type Config struct {
7777 Mode Mode
7878 GenExpect bool // only valid for ModeCmpTest
7979 Verbose bool
80+ GenLL bool // generate pkg .ll files
8081 Tags string
8182 GlobalNames map [string ][]string // pkg => names
8283 GlobalDatas map [string ]string // pkg.name => data
@@ -252,7 +253,17 @@ func Do(args []string, conf *Config) ([]Package, error) {
252253 output := conf .OutFile != ""
253254 export , err := crosscompile .Use (conf .Goos , conf .Goarch , IsWasiThreadsEnabled (), IsRpathChangeEnabled ())
254255 check (err )
255- ctx := & context {env , cfg , progSSA , prog , dedup , patches , make (map [string ]none ), initial , mode , 0 , output , make (map [* packages.Package ]bool ), make (map [* packages.Package ]bool ), conf , export }
256+ ctx := & context {env : env , conf : cfg , progSSA : progSSA , prog : prog , dedup : dedup ,
257+ patches : patches , built : make (map [string ]none ), initial : initial , mode : mode ,
258+ output : output ,
259+ needRt : make (map [* packages.Package ]bool ),
260+ needPyInit : make (map [* packages.Package ]bool ),
261+ buildConf : conf ,
262+ crossCompile : export ,
263+ isDbgEnabled : IsDbgEnabled (),
264+ isDbgSymsEnabled : IsDbgSymsEnabled (),
265+ isCheckEnable : IsCheckEnable (),
266+ }
256267 pkgs , err := buildAllPkgs (ctx , initial , verbose )
257268 check (err )
258269 if mode == ModeGen {
@@ -337,6 +348,10 @@ type context struct {
337348 nLibdir int
338349 output bool
339350
351+ isDbgEnabled bool
352+ isDbgSymsEnabled bool
353+ isCheckEnable bool
354+
340355 needRt map [* packages.Package ]bool
341356 needPyInit map [* packages.Package ]bool
342357
@@ -797,20 +812,56 @@ func buildPkg(ctx *context, aPkg *aPackage, verbose bool) error {
797812 aPkg .LinkArgs = append (aPkg .LinkArgs , altLdflags ... )
798813 }
799814 if pkg .ExportFile != "" {
800- pkg .ExportFile += ".ll"
801- os .WriteFile (pkg .ExportFile , []byte (ret .String ()), 0644 )
815+ err := exportObject (ctx , pkg , ret , verbose )
816+ if err != nil {
817+ return fmt .Errorf ("export object of %v failed: %v" , pkgPath , err )
818+ }
802819 if debugBuild || verbose {
803820 fmt .Fprintf (os .Stderr , "==> Export %s: %s\n " , aPkg .PkgPath , pkg .ExportFile )
804821 }
805- if IsCheckEnable () {
806- if msg , err := llcCheck (ctx .env , pkg .ExportFile ); err != nil {
807- fmt .Fprintf (os .Stderr , "==> lcc %v: %v\n %v\n " , pkg .PkgPath , pkg .ExportFile , msg )
808- }
809- }
810822 }
811823 return nil
812824}
813825
826+ func exportObject (ctx * context , pkg * packages.Package , ret llssa.Package , verbose bool ) error {
827+ f , err := os .CreateTemp ("" , "llgo-*.ll" )
828+ if err != nil {
829+ return err
830+ }
831+ f .Write ([]byte (ret .String ()))
832+ err = f .Close ()
833+ if err != nil {
834+ return err
835+ }
836+ if ctx .isCheckEnable {
837+ if msg , err := llcCheck (ctx .env , f .Name ()); err != nil {
838+ fmt .Fprintf (os .Stderr , "==> lcc %v: %v\n %v\n " , pkg .PkgPath , f .Name (), msg )
839+ }
840+ }
841+ var llfile string
842+ if ctx .buildConf .GenLL {
843+ llfile = pkg .ExportFile + ".ll"
844+ err = os .Chmod (llfile , 0644 )
845+ if err != nil {
846+ return err
847+ }
848+ err = os .Rename (f .Name (), llfile )
849+ if err != nil {
850+ return err
851+ }
852+ } else {
853+ llfile = f .Name ()
854+ }
855+ pkg .ExportFile += ".o"
856+ args := []string {"-o" , pkg .ExportFile , "-c" , llfile , "-Wno-override-module" }
857+ args = append (args , ctx .crossCompile .CCFLAGS ... )
858+ if verbose {
859+ fmt .Fprintln (os .Stderr , "clang" , args )
860+ }
861+ cmd := ctx .compiler ()
862+ return cmd .Compile (args ... )
863+ }
864+
814865func llcCheck (env * llvm.Env , exportFile string ) (msg string , err error ) {
815866 bin := filepath .Join (env .BinDir (), "llc" )
816867 cmd := exec .Command (bin , "-filetype=null" , exportFile )
@@ -1026,15 +1077,20 @@ func clFiles(ctx *context, files string, pkg *packages.Package, procFile func(li
10261077}
10271078
10281079func clFile (ctx * context , args []string , cFile , expFile string , procFile func (linkFile string ), verbose bool ) {
1029- llFile := expFile + filepath .Base (cFile ) + ".ll"
1080+ llFile := expFile + filepath .Base (cFile )
10301081 ext := filepath .Ext (cFile )
10311082
10321083 // default clang++ will use c++ to compile c file,will cause symbol be mangled
10331084 if ext == ".c" {
10341085 args = append (args , "-x" , "c" )
10351086 }
1036-
1037- args = append (args , "-emit-llvm" , "-S" , "-o" , llFile , "-c" , cFile )
1087+ if ctx .buildConf .GenLL {
1088+ llFile += ".ll"
1089+ args = append (args , "-emit-llvm" , "-S" , "-o" , llFile , "-c" , cFile )
1090+ } else {
1091+ llFile += ".o"
1092+ args = append (args , "-o" , llFile , "-c" , cFile )
1093+ }
10381094 args = append (args , ctx .crossCompile .CCFLAGS ... )
10391095 args = append (args , ctx .crossCompile .CFLAGS ... )
10401096 if verbose {
0 commit comments