added various new arguments + LICENSE and README
This commit is contained in:
parent
5caf8fe9fa
commit
252d0b7278
19
LICENSE.md
Normal file
19
LICENSE.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2022 Mila Ringwald
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
131
README.md
Normal file
131
README.md
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# gocc
|
||||||
|
|
||||||
|
A high-performance cross compiler for Go
|
||||||
|
|
||||||
|
## Source code
|
||||||
|
|
||||||
|
You can find the source code here: [git.milar.in](https://git.milar.in/milarin/gocc)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
If you have Go installed, you can simply go install the program: `go install git.milar.in/milarin/gocc@latest`
|
||||||
|
|
||||||
|
There are pre-compiled executables for various platforms on the [repository](https://git.milar.in/milarin/gocc/releases).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Distributed under the MIT License. See [LICENSE.md](https://git.milar.in/milarin/gocc/src/branch/main/LICENSE.md)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic syntax
|
||||||
|
|
||||||
|
`gocc [<arguments>] [<module>]`
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
Using `--help` shows a description for all available arguments:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ gocc --help
|
||||||
|
Usage of ./gocc:
|
||||||
|
-arch string
|
||||||
|
comma-separated list of architectures to compile for (empty for all)
|
||||||
|
-c dont compress any executables
|
||||||
|
-f string
|
||||||
|
go template for filenames (default "{{.Name}}-{{.OS}}-{{.Arch}}{{.Ext}}")
|
||||||
|
-findconfig
|
||||||
|
print config file path and exit
|
||||||
|
-ignoreconfig
|
||||||
|
dont read any config file
|
||||||
|
-o string
|
||||||
|
output directory (default "output")
|
||||||
|
-os string
|
||||||
|
comma-separated list of operating systems to compile for (empty for all)
|
||||||
|
-s silent mode (no output)
|
||||||
|
-saveconfig
|
||||||
|
save config file with current configuration and exit
|
||||||
|
-t int
|
||||||
|
amount of threads (0 = infinite) (default 16)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Providing a Go module
|
||||||
|
|
||||||
|
By default, `gocc` compiles the module in the current working directory.
|
||||||
|
You can provide a custom module path after all other arguments.
|
||||||
|
|
||||||
|
For example: `gocc -t 4 -ignoreconfig path/to/go/module`
|
||||||
|
|
||||||
|
#### Choosing Operating systems
|
||||||
|
|
||||||
|
You can decide, for which operating systems `gocc` should compile for via `-os`.
|
||||||
|
Provide the operating systems as a comma-separated list.
|
||||||
|
|
||||||
|
For example: `gocc -os "windows,linux"`
|
||||||
|
|
||||||
|
For a list of supported operating systems, run `go tool dist list`
|
||||||
|
|
||||||
|
#### Choosing architectures
|
||||||
|
|
||||||
|
Analogous to operating systems, you can provide architectures via `-arch`.
|
||||||
|
|
||||||
|
For example: `gocc -arch "amd64,386"`
|
||||||
|
|
||||||
|
For a list of supported architectures, run `go tool dist list`
|
||||||
|
|
||||||
|
#### Output path
|
||||||
|
|
||||||
|
By default, `gocc` will save all executables in the folder `output` in the current working directory.
|
||||||
|
You can set a custom path via `-o`
|
||||||
|
|
||||||
|
#### Disable compression
|
||||||
|
|
||||||
|
All executables will be compressed automatically if `upx` is found in `$PATH`.
|
||||||
|
This behavior can be disabled via `-c`.
|
||||||
|
|
||||||
|
#### Multithreaded compilation
|
||||||
|
|
||||||
|
Compilation is multi-threaded by default. You can set the amount of concurrent compilations via `-t <threads>`.
|
||||||
|
If no thread count is provided, the amount of CPU cores will be used.
|
||||||
|
(the default value shown with `--help` is always the amount of CPU cores on the current machine)
|
||||||
|
|
||||||
|
A thread count of `0` runs all tasks at the same time. This could lead to lags and freezes on your machine!
|
||||||
|
|
||||||
|
If you want to disable multi-threaded compilation, just use `-t 1`
|
||||||
|
|
||||||
|
#### Silent mode
|
||||||
|
|
||||||
|
Providing `-s` enables silent mode. When enabled, `gocc` will never show any output.
|
||||||
|
A non-zero exit code indicates errors.
|
||||||
|
|
||||||
|
#### Customize default behavior
|
||||||
|
|
||||||
|
You can change the default values of all other arguments with `-saveconfig`.
|
||||||
|
Simply provide all arguments as you like and save your config in a json file.
|
||||||
|
Next time `gocc` is run, the config file will be loaded and your preferred command line arguments will be automatically set.
|
||||||
|
|
||||||
|
You can still manually overwrite arguments by providing them directly.
|
||||||
|
But that will not always result in the default behavior if no config file exists.
|
||||||
|
For these cases you can use `-ignoreconfig`.
|
||||||
|
|
||||||
|
If you want to get rid of your config file or you want to edit it manually, you can find it by running `gocc -findconfig`
|
||||||
|
|
||||||
|
**No compilation will be done if `-saveconfig` is provided!**
|
||||||
|
|
||||||
|
**`-findconfig` does not work with silent mode (`-s`)!**
|
||||||
|
|
||||||
|
**Always use `-ignoreconfig` in scripts! You don't know what config file your user might have!**
|
||||||
|
|
||||||
|
#### Change executable filename pattern
|
||||||
|
|
||||||
|
You can provide a custom filename pattern for the compiled executables via `-f`.
|
||||||
|
The value feeded into `-f` is a Go template.
|
||||||
|
See the official Go docs for [Go templates](https://pkg.go.dev/text/template) for more information.
|
||||||
|
|
||||||
|
The following values are available inside the template:
|
||||||
|
- `Name`: the module name
|
||||||
|
- `OS`: the operating system
|
||||||
|
- `Arch`: the architecture
|
||||||
|
- `Ext`: the file extension (for windows: `.exe`, for any other operating system: ``)
|
||||||
|
|
||||||
|
The default value is `{{.Name}}-{{.OS}}-{{.Arch}}{{.Ext}}`
|
17
compile.go
17
compile.go
@ -1,14 +1,27 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
|
func Compile(cfg *CompileConfig, ch chan<- *CompileReport, wg *sync.WaitGroup) {
|
||||||
filePath := filepath.Join(*OutputDir, fmt.Sprintf("%s_%s_%s%s", ProjectName, cfg.OS, cfg.Arch, cfg.FileExt))
|
b := new(strings.Builder)
|
||||||
|
data := &OutputFileTmplData{
|
||||||
|
Name: ProjectName,
|
||||||
|
OS: cfg.OS,
|
||||||
|
Arch: cfg.Arch,
|
||||||
|
Ext: cfg.FileExt,
|
||||||
|
}
|
||||||
|
if err := OutputFileTmpl.Execute(b, data); err != nil {
|
||||||
|
ch <- &CompileReport{Config: cfg, State: StateCompileError}
|
||||||
|
wg.Done()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := filepath.Join(*OutputDir, b.String())
|
||||||
|
|
||||||
filePath, err := filepath.Abs(filePath)
|
filePath, err := filepath.Abs(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
22
config.go
22
config.go
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
OutputDir string `json:"output_dir"`
|
OutputDir string `json:"output_dir"`
|
||||||
|
OutputFile string `json:"output_file"`
|
||||||
|
|
||||||
OS []string `json:"os"`
|
OS []string `json:"os"`
|
||||||
Arch []string `json:"arch"`
|
Arch []string `json:"arch"`
|
||||||
@ -20,6 +21,12 @@ type Config struct {
|
|||||||
NumThreads int `json:"num_threads"`
|
NumThreads int `json:"num_threads"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetFlagIfDefault[T comparable](flag *T, newValue T, defaultValue T) {
|
||||||
|
if *flag == defaultValue {
|
||||||
|
*flag = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func LoadConfig() error {
|
func LoadConfig() error {
|
||||||
configFilePath, err := configfile.Path("json")
|
configFilePath, err := configfile.Path("json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -37,12 +44,14 @@ func LoadConfig() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*OutputDir = cfg.OutputDir
|
SetFlagIfDefault(OutputDir, cfg.OutputDir, DefaultOutputDir)
|
||||||
*OS = strings.Join(cfg.OS, ",")
|
SetFlagIfDefault(OutputFile, cfg.OutputFile, DefaultOutputFile)
|
||||||
*Arch = strings.Join(cfg.Arch, ",")
|
SetFlagIfDefault(OS, strings.Join(cfg.OS, ","), DefaultOS)
|
||||||
*Silent = cfg.Silent
|
SetFlagIfDefault(Arch, strings.Join(cfg.Arch, ","), DefaultArch)
|
||||||
*NoCompress = cfg.NoCompress
|
SetFlagIfDefault(Silent, cfg.Silent, DefaultSilent)
|
||||||
*NumThreads = cfg.NumThreads
|
SetFlagIfDefault(NoCompress, cfg.NoCompress, DefaultNoCompress)
|
||||||
|
SetFlagIfDefault(NumThreads, cfg.NumThreads, DefaultNumThreads)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +76,7 @@ func SaveConfig() (string, error) {
|
|||||||
|
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
OutputDir: *OutputDir,
|
OutputDir: *OutputDir,
|
||||||
|
OutputFile: *OutputFile,
|
||||||
OS: strings.Split(*OS, ","),
|
OS: strings.Split(*OS, ","),
|
||||||
Arch: strings.Split(*Arch, ","),
|
Arch: strings.Split(*Arch, ","),
|
||||||
Silent: *Silent,
|
Silent: *Silent,
|
||||||
|
13
init.go
13
init.go
@ -7,12 +7,21 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"git.milar.in/milarin/configfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
if *FindConfigFile {
|
||||||
|
if configFilePath, err := configfile.Path("json"); err == nil {
|
||||||
|
Println(configFilePath)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if *SaveConfigFile {
|
if *SaveConfigFile {
|
||||||
if configFilePath, err := SaveConfig(); err == nil {
|
if configFilePath, err := SaveConfig(); err == nil {
|
||||||
Println(ColorDone.Sprintf("config file saved at '%s'", configFilePath))
|
Println(ColorDone.Sprintf("config file saved at '%s'", configFilePath))
|
||||||
@ -21,12 +30,14 @@ func Init() {
|
|||||||
Println(ColorError.Sprint(fmt.Errorf("saving config file failed: %w", err)))
|
Println(ColorError.Sprint(fmt.Errorf("saving config file failed: %w", err)))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
} else {
|
} else if !*IgnoreConfigFile {
|
||||||
if err := LoadConfig(); err != nil {
|
if err := LoadConfig(); err != nil {
|
||||||
Println(ColorError.Sprint(fmt.Errorf("loading config file failed: %w", err)))
|
Println(ColorError.Sprint(fmt.Errorf("loading config file failed: %w", err)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutputFileTmpl.Parse(*OutputFile)
|
||||||
|
|
||||||
ModulePath, err = filepath.Abs(flag.Arg(0))
|
ModulePath, err = filepath.Abs(flag.Arg(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Println(ColorError.Sprint("determining module path failed"))
|
Println(ColorError.Sprint("determining module path failed"))
|
||||||
|
7
main.go
7
main.go
@ -10,6 +10,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.milar.in/milarin/channel"
|
"git.milar.in/milarin/channel"
|
||||||
@ -17,6 +18,8 @@ import (
|
|||||||
|
|
||||||
// globals
|
// globals
|
||||||
var (
|
var (
|
||||||
|
OutputFileTmpl = template.New("output-file")
|
||||||
|
|
||||||
ModulePath string
|
ModulePath string
|
||||||
ProjectName string
|
ProjectName string
|
||||||
Runner channel.Runner
|
Runner channel.Runner
|
||||||
@ -27,6 +30,7 @@ var (
|
|||||||
// command line arguments default values
|
// command line arguments default values
|
||||||
var (
|
var (
|
||||||
DefaultOutputDir = "output"
|
DefaultOutputDir = "output"
|
||||||
|
DefaultOutputFile = "{{.Name}}-{{.OS}}-{{.Arch}}{{.Ext}}"
|
||||||
DefaultOS = ""
|
DefaultOS = ""
|
||||||
DefaultArch = ""
|
DefaultArch = ""
|
||||||
DefaultSilent = false
|
DefaultSilent = false
|
||||||
@ -37,6 +41,7 @@ var (
|
|||||||
// command line arguments
|
// command line arguments
|
||||||
var (
|
var (
|
||||||
OutputDir = flag.String("o", DefaultOutputDir, "output directory")
|
OutputDir = flag.String("o", DefaultOutputDir, "output directory")
|
||||||
|
OutputFile = flag.String("f", DefaultOutputFile, "go template for filenames")
|
||||||
|
|
||||||
OS = flag.String("os", DefaultOS, "comma-separated list of operating systems to compile for (empty for all)")
|
OS = flag.String("os", DefaultOS, "comma-separated list of operating systems to compile for (empty for all)")
|
||||||
Arch = flag.String("arch", DefaultArch, "comma-separated list of architectures to compile for (empty for all)")
|
Arch = flag.String("arch", DefaultArch, "comma-separated list of architectures to compile for (empty for all)")
|
||||||
@ -46,6 +51,8 @@ var (
|
|||||||
NumThreads = flag.Int("t", DefaultNumThreads, "amount of threads (0 = infinite)")
|
NumThreads = flag.Int("t", DefaultNumThreads, "amount of threads (0 = infinite)")
|
||||||
|
|
||||||
SaveConfigFile = flag.Bool("saveconfig", false, "save config file with current configuration and exit")
|
SaveConfigFile = flag.Bool("saveconfig", false, "save config file with current configuration and exit")
|
||||||
|
IgnoreConfigFile = flag.Bool("ignoreconfig", false, "dont read any config file")
|
||||||
|
FindConfigFile = flag.Bool("findconfig", false, "print config file path and exit")
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
8
output_file_data.go
Normal file
8
output_file_data.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type OutputFileTmplData struct {
|
||||||
|
Name string
|
||||||
|
OS string
|
||||||
|
Arch string
|
||||||
|
Ext string
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user