github.com/bir3/gocompiler@v0.3.205/README.md (about)

     1  
     2  # gocompiler
     3  
     4  The Go compiler as a package
     5  
     6  
     7  
     8  # Example
     9  
    10  ```bash
    11  # go1.20.5
    12  go get github.com/bir3/gocompiler@v0.3.205
    13  ```
    14  
    15  ```go
    16  package main
    17  
    18  import (
    19  	"fmt"
    20  	"log"
    21  	"os"
    22  
    23  	"github.com/bir3/gocompiler"
    24  )
    25  
    26  var goCodeStr string = `
    27  package main
    28  
    29  import "fmt"
    30  
    31  func main() {
    32  	fmt.Println("This code was compiled standalone")
    33  }
    34  `
    35  
    36  func main() {
    37  
    38  	// the go toolchain is built into the executable and must be given a chance to run
    39  	// => avoid side effects in init() and global variable initialization
    40  	//    as they will occur multiple times during compilation
    41  	if gocompiler.IsRunToolchainRequest() {
    42  		gocompiler.RunToolchain()
    43  		return
    44  	}
    45  
    46  	err := os.WriteFile("temp.go", []byte(goCodeStr), 0644)
    47  	if err != nil {
    48  		log.Fatal(err)
    49  	}
    50  
    51  	result, err := gocompiler.Run("go", "run", "temp.go")
    52  	fmt.Fprintf(os.Stdout, "%s", result.Stdout)
    53  	fmt.Fprintf(os.Stderr, "%s", result.Stderr)
    54  	if err != nil {
    55  		log.Fatal(err)
    56  	}
    57  	os.Remove("temp.go")
    58  }
    59  ```
    60  
    61  
    62  # Limitations
    63  
    64  - avoid side effects in init() and global variable initializations
    65  
    66  Reason: Your executable will serve two purposes: 
    67  - run your application
    68  - run the Go compiler toolchain via `gocompiler.RunToolchain()`
    69  
    70  Side effects in init() and global variable initializations occur every time the executable is started.  
    71  The embedded Go toolchain will repeatedly start the executable during compilation to compile Go source code.  
    72  This means that global side effects like opening a http port, writing to a file or connecting to a database is likely to cause problems.
    73  
    74  ## example bug due to side effects : creating a log file in a init() function
    75  
    76  The main function may write a few lines to the logfile, then when we compile code, the subprocesses
    77  that are also hosted in the main executable will also open and possibly write or truncate the logfile
    78  creating confusion on why something as simple as writing to a logfile can fail to work !
    79  
    80  # gocompiler as a package vs. the official Go toolchain
    81  
    82  |                      | "github.com/bir3/gocompiler"  | official go toolchain |                           |
    83  | -------------------  | ----------------------------- | --------------------- | ------------------------- |
    84  | Size on disk         | 44 MB (standalone executable) | 262 MB                |                           |
    85  | Performance, compile | 12.9 sec                      | 12.4 sec              | macbook M1, `go build -a` |
    86  
    87  Note that this package is only focused on compiling Go source code into an executable, while the official Go toolchain provides many more tools.
    88  
    89  # Acknowledgments
    90  
    91  * The Go Authors. https://github.com/golang/go 
    92  * Klaus Post, zstd decompression: https://github.com/klauspost/compress