@@ -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
@@ -797,18 +798,49 @@ func buildPkg(ctx *context, aPkg *aPackage, verbose bool) error {
797798 aPkg .LinkArgs = append (aPkg .LinkArgs , altLdflags ... )
798799 }
799800 if pkg .ExportFile != "" {
800- pkg .ExportFile += ".ll"
801- os .WriteFile (pkg .ExportFile , []byte (ret .String ()), 0644 )
801+ err := exportObject (ctx , pkg , ret , verbose )
802+ if err != nil {
803+ return fmt .Errorf ("export object of %v failed: %v" , pkgPath , err )
804+ }
802805 if debugBuild || verbose {
803806 fmt .Fprintf (os .Stderr , "==> Export %s: %s\n " , aPkg .PkgPath , pkg .ExportFile )
804807 }
805- if IsCheckEnable () {
808+ }
809+ return nil
810+ }
811+
812+ func exportObject (ctx * context , pkg * packages.Package , ret llssa.Package , verbose bool ) error {
813+ if ctx .buildConf .GenLL {
814+ pkg .ExportFile += ".ll"
815+ err := os .WriteFile (pkg .ExportFile , []byte (ret .String ()), 0644 )
816+ if err == nil && IsCheckEnable () {
806817 if msg , err := llcCheck (ctx .env , pkg .ExportFile ); err != nil {
807818 fmt .Fprintf (os .Stderr , "==> lcc %v: %v\n %v\n " , pkg .PkgPath , pkg .ExportFile , msg )
808819 }
809820 }
821+ return err
810822 }
811- return nil
823+ if ctx .buildConf .Goos == runtime .GOOS && runtime .GOOS == "darwin" {
824+ pkg .ExportFile += ".o"
825+ data , err := ret .CodeGen (llssa .ObjectFile )
826+ if err != nil {
827+ return err
828+ }
829+ return os .WriteFile (pkg .ExportFile , data , 0644 )
830+ }
831+ bcfile := pkg .ExportFile + ".ll"
832+ err := os .WriteFile (bcfile , []byte (ret .String ()), 0644 )
833+ if err != nil {
834+ return err
835+ }
836+ pkg .ExportFile += ".o"
837+ args := []string {"-o" , pkg .ExportFile , "-c" , bcfile , "-Wno-override-module" }
838+ args = append (args , ctx .crossCompile .CCFLAGS ... )
839+ if verbose {
840+ fmt .Fprintln (os .Stderr , "clang" , args )
841+ }
842+ cmd := ctx .compiler ()
843+ return cmd .Compile (args ... )
812844}
813845
814846func llcCheck (env * llvm.Env , exportFile string ) (msg string , err error ) {
@@ -1026,15 +1058,20 @@ func clFiles(ctx *context, files string, pkg *packages.Package, procFile func(li
10261058}
10271059
10281060func clFile (ctx * context , args []string , cFile , expFile string , procFile func (linkFile string ), verbose bool ) {
1029- llFile := expFile + filepath .Base (cFile ) + ".ll"
1061+ llFile := expFile + filepath .Base (cFile )
10301062 ext := filepath .Ext (cFile )
10311063
10321064 // default clang++ will use c++ to compile c file,will cause symbol be mangled
10331065 if ext == ".c" {
10341066 args = append (args , "-x" , "c" )
10351067 }
1036-
1037- args = append (args , "-emit-llvm" , "-S" , "-o" , llFile , "-c" , cFile )
1068+ if ctx .buildConf .GenLL {
1069+ llFile += ".ll"
1070+ args = append (args , "-emit-llvm" , "-S" , "-o" , llFile , "-c" , cFile )
1071+ } else {
1072+ llFile += ".o"
1073+ args = append (args , "-o" , llFile , "-c" , cFile )
1074+ }
10381075 args = append (args , ctx .crossCompile .CCFLAGS ... )
10391076 args = append (args , ctx .crossCompile .CFLAGS ... )
10401077 if verbose {
0 commit comments