@@ -17,6 +17,7 @@ import (
1717 "github.com/tinygo-org/tinygo/goenv"
1818 "github.com/tinygo-org/tinygo/interp"
1919 "github.com/tinygo-org/tinygo/transform"
20+ "tinygo.org/x/go-llvm"
2021)
2122
2223// Build performs a single package to executable Go build. It takes in a package
@@ -26,34 +27,34 @@ import (
2627// The error value may be of type *MultiError. Callers will likely want to check
2728// for this case and print such errors individually.
2829func Build (pkgName , outpath string , config * compileopts.Config , action func (string ) error ) error {
29- c , err := compiler .NewCompiler (pkgName , config )
30+ // Compile Go code to IR.
31+ machine , err := compiler .NewTargetMachine (config )
3032 if err != nil {
3133 return err
3234 }
33-
34- // Compile Go code to IR.
35- errs := c .Compile (pkgName )
36- if len (errs ) != 0 {
35+ mod , extraFiles , errs := compiler .Compile (pkgName , machine , config )
36+ if errs != nil {
3737 return newMultiError (errs )
3838 }
39+
3940 if config .Options .PrintIR {
4041 fmt .Println ("; Generated LLVM IR:" )
41- fmt .Println (c . IR ())
42+ fmt .Println (mod . String ())
4243 }
43- if err := c . Verify ( ); err != nil {
44+ if err := llvm . VerifyModule ( mod , llvm . PrintMessageAction ); err != nil {
4445 return errors .New ("verification error after IR construction" )
4546 }
4647
47- err = interp .Run (c . Module () , config .DumpSSA ())
48+ err = interp .Run (mod , config .DumpSSA ())
4849 if err != nil {
4950 return err
5051 }
51- if err := c . Verify ( ); err != nil {
52+ if err := llvm . VerifyModule ( mod , llvm . PrintMessageAction ); err != nil {
5253 return errors .New ("verification error after interpreting runtime.initAll" )
5354 }
5455
5556 if config .GOOS () != "darwin" {
56- transform .ApplyFunctionSections (c . Module () ) // -ffunction-sections
57+ transform .ApplyFunctionSections (mod ) // -ffunction-sections
5758 }
5859
5960 // Browsers cannot handle external functions that have type i64 because it
@@ -62,7 +63,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
6263 // stack-allocated values.
6364 // Use -wasm-abi=generic to disable this behaviour.
6465 if config .Options .WasmAbi == "js" && strings .HasPrefix (config .Triple (), "wasm" ) {
65- err := transform .ExternalInt64AsPtr (c . Module () )
66+ err := transform .ExternalInt64AsPtr (mod )
6667 if err != nil {
6768 return err
6869 }
@@ -73,22 +74,22 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
7374 errs = nil
7475 switch config .Options .Opt {
7576 case "none" , "0" :
76- errs = transform .Optimize (c . Module () , config , 0 , 0 , 0 ) // -O0
77+ errs = transform .Optimize (mod , config , 0 , 0 , 0 ) // -O0
7778 case "1" :
78- errs = transform .Optimize (c . Module () , config , 1 , 0 , 0 ) // -O1
79+ errs = transform .Optimize (mod , config , 1 , 0 , 0 ) // -O1
7980 case "2" :
80- errs = transform .Optimize (c . Module () , config , 2 , 0 , 225 ) // -O2
81+ errs = transform .Optimize (mod , config , 2 , 0 , 225 ) // -O2
8182 case "s" :
82- errs = transform .Optimize (c . Module () , config , 2 , 1 , 225 ) // -Os
83+ errs = transform .Optimize (mod , config , 2 , 1 , 225 ) // -Os
8384 case "z" :
84- errs = transform .Optimize (c . Module () , config , 2 , 2 , 5 ) // -Oz, default
85+ errs = transform .Optimize (mod , config , 2 , 2 , 5 ) // -Oz, default
8586 default :
8687 errs = []error {errors .New ("unknown optimization level: -opt=" + config .Options .Opt )}
8788 }
8889 if len (errs ) > 0 {
8990 return newMultiError (errs )
9091 }
91- if err := c . Verify ( ); err != nil {
92+ if err := llvm . VerifyModule ( mod , llvm . PrintMessageAction ); err != nil {
9293 return errors .New ("verification failure after LLVM optimization passes" )
9394 }
9495
@@ -98,8 +99,8 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
9899 // pointers are flash and which are in RAM so that pointers can have a
99100 // correct address space parameter (address space 1 is for flash).
100101 if strings .HasPrefix (config .Triple (), "avr" ) {
101- transform .NonConstGlobals (c . Module () )
102- if err := c . Verify ( ); err != nil {
102+ transform .NonConstGlobals (mod )
103+ if err := llvm . VerifyModule ( mod , llvm . PrintMessageAction ); err != nil {
103104 return errors .New ("verification error after making all globals non-constant on AVR" )
104105 }
105106 }
@@ -108,11 +109,17 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
108109 outext := filepath .Ext (outpath )
109110 switch outext {
110111 case ".o" :
111- return c .EmitObject (outpath )
112+ llvmBuf , err := machine .EmitToMemoryBuffer (mod , llvm .ObjectFile )
113+ if err != nil {
114+ return err
115+ }
116+ return ioutil .WriteFile (outpath , llvmBuf .Bytes (), 0666 )
112117 case ".bc" :
113- return c .EmitBitcode (outpath )
118+ data := llvm .WriteBitcodeToMemoryBuffer (mod ).Bytes ()
119+ return ioutil .WriteFile (outpath , data , 0666 )
114120 case ".ll" :
115- return c .EmitText (outpath )
121+ data := []byte (mod .String ())
122+ return ioutil .WriteFile (outpath , data , 0666 )
116123 default :
117124 // Act as a compiler driver.
118125
@@ -125,7 +132,11 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
125132
126133 // Write the object file.
127134 objfile := filepath .Join (dir , "main.o" )
128- err = c .EmitObject (objfile )
135+ llvmBuf , err := machine .EmitToMemoryBuffer (mod , llvm .ObjectFile )
136+ if err != nil {
137+ return err
138+ }
139+ err = ioutil .WriteFile (objfile , llvmBuf .Bytes (), 0666 )
129140 if err != nil {
130141 return err
131142 }
@@ -167,16 +178,13 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
167178 }
168179
169180 // Compile C files in packages.
170- for i , pkg := range c .Packages () {
171- for _ , file := range pkg .CFiles {
172- path := filepath .Join (pkg .Package .Dir , file )
173- outpath := filepath .Join (dir , "pkg" + strconv .Itoa (i )+ "-" + file + ".o" )
174- err := runCCompiler (config .Target .Compiler , append (config .CFlags (), "-c" , "-o" , outpath , path )... )
175- if err != nil {
176- return & commandError {"failed to build" , path , err }
177- }
178- ldflags = append (ldflags , outpath )
181+ for i , file := range extraFiles {
182+ outpath := filepath .Join (dir , "pkg" + strconv .Itoa (i )+ "-" + filepath .Base (file )+ ".o" )
183+ err := runCCompiler (config .Target .Compiler , append (config .CFlags (), "-c" , "-o" , outpath , file )... )
184+ if err != nil {
185+ return & commandError {"failed to build" , file , err }
179186 }
187+ ldflags = append (ldflags , outpath )
180188 }
181189
182190 // Link the object files together.
0 commit comments