Merge pull request #3383 from cli/build-env
Tweak build scripts to enable cross-compiling
This commit is contained in:
commit
a9bebff03f
3 changed files with 70 additions and 25 deletions
17
Makefile
17
Makefile
|
|
@ -5,22 +5,27 @@ export CGO_CFLAGS
|
|||
CGO_LDFLAGS ?= $(filter -g -L% -l% -O%,${LDFLAGS})
|
||||
export CGO_LDFLAGS
|
||||
|
||||
EXE =
|
||||
ifeq ($(GOOS),windows)
|
||||
EXE = .exe
|
||||
endif
|
||||
|
||||
## The following tasks delegate to `script/build.go` so they can be run cross-platform.
|
||||
|
||||
.PHONY: bin/gh
|
||||
bin/gh: script/build
|
||||
@script/build bin/gh
|
||||
.PHONY: bin/gh$(EXE)
|
||||
bin/gh$(EXE): script/build
|
||||
@script/build $@
|
||||
|
||||
script/build: script/build.go
|
||||
go build -o script/build script/build.go
|
||||
GOOS= GOARCH= GOARM= GOFLAGS= CGO_ENABLED= go build -o $@ $<
|
||||
|
||||
.PHONY: clean
|
||||
clean: script/build
|
||||
@script/build clean
|
||||
@script/build $@
|
||||
|
||||
.PHONY: manpages
|
||||
manpages: script/build
|
||||
@script/build manpages
|
||||
@script/build $@
|
||||
|
||||
# just a convenience task around `go test`
|
||||
.PHONY: test
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
```
|
||||
|
||||
#### Windows
|
||||
```sh
|
||||
```pwsh
|
||||
# build the `bin\gh.exe` binary
|
||||
> go run script/build.go
|
||||
> go run script\build.go
|
||||
```
|
||||
There is no install step available on Windows.
|
||||
|
||||
|
|
@ -37,3 +37,23 @@
|
|||
|
||||
#### Windows
|
||||
Run `bin\gh version` to check if it worked.
|
||||
|
||||
## Cross-compiling binaries for different platforms
|
||||
|
||||
You can use any platform with Go installed to build a binary that is intended for another platform
|
||||
or CPU architecture. This is achieved by setting environment variables such as GOOS and GOARCH.
|
||||
|
||||
For example, to compile the `gh` binary for the 32-bit Raspberry Pi OS:
|
||||
```sh
|
||||
# on a Unix-like system:
|
||||
$ GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=0 make clean bin/gh
|
||||
```
|
||||
```pwsh
|
||||
# on Windows, pass environment variables as arguments to the build script:
|
||||
> go run script\build.go clean bin\gh GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=0
|
||||
```
|
||||
|
||||
Run `go tool dist list` to list all supported values of GOOS/GOARCH.
|
||||
|
||||
Tip: to reduce the size of the resulting binary, you can use `GO_LDFLAGS="-s -w"`. This omits
|
||||
symbol tables used for debugging. See the list of [supported linker flags](https://golang.org/cmd/link/).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Build tasks for the GitHub CLI project.
|
||||
//
|
||||
// Usage: go run script/build.go [<task>]
|
||||
// Usage: go run script/build.go [<tasks>...] [<env>...]
|
||||
//
|
||||
// Known tasks are:
|
||||
//
|
||||
|
|
@ -65,34 +65,54 @@ var tasks = map[string]func(string) error{
|
|||
var self string
|
||||
|
||||
func main() {
|
||||
task := "bin/gh"
|
||||
if runtime.GOOS == "windows" {
|
||||
task = "bin\\gh.exe"
|
||||
args := os.Args[:1]
|
||||
for _, arg := range os.Args[1:] {
|
||||
if idx := strings.IndexRune(arg, '='); idx >= 0 {
|
||||
os.Setenv(arg[:idx], arg[idx+1:])
|
||||
} else {
|
||||
args = append(args, arg)
|
||||
}
|
||||
}
|
||||
|
||||
if len(os.Args) > 1 {
|
||||
task = os.Args[1]
|
||||
if len(args) < 2 {
|
||||
if isWindowsTarget() {
|
||||
args = append(args, filepath.Join("bin", "gh.exe"))
|
||||
} else {
|
||||
args = append(args, "bin/gh")
|
||||
}
|
||||
}
|
||||
|
||||
self = filepath.Base(os.Args[0])
|
||||
self = filepath.Base(args[0])
|
||||
if self == "build" {
|
||||
self = "build.go"
|
||||
}
|
||||
|
||||
t := tasks[normalizeTask(task)]
|
||||
if t == nil {
|
||||
fmt.Fprintf(os.Stderr, "Don't know how to build task `%s`.\n", task)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, task := range args[1:] {
|
||||
t := tasks[normalizeTask(task)]
|
||||
if t == nil {
|
||||
fmt.Fprintf(os.Stderr, "Don't know how to build task `%s`.\n", task)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err := t(task)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintf(os.Stderr, "%s: building task `%s` failed.\n", self, task)
|
||||
os.Exit(1)
|
||||
err := t(task)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintf(os.Stderr, "%s: building task `%s` failed.\n", self, task)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isWindowsTarget() bool {
|
||||
if os.Getenv("GOOS") == "windows" {
|
||||
return true
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func version() string {
|
||||
if versionEnv := os.Getenv("GH_VERSION"); versionEnv != "" {
|
||||
return versionEnv
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue