From 9725f2258b27f901afbcab2e6214d30e90e82a91 Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Fri, 10 Apr 2015 09:11:03 -0400 Subject: [PATCH] cmd/go: -buildmode=c-archive support Change-Id: I469254384b0f4e5b5f08a18658934e19259935f9 Reviewed-on: https://go-review.googlesource.com/8718 Reviewed-by: Ian Lance Taylor Run-TryBot: David Crawshaw TryBot-Result: Gobot Gobot --- src/cmd/go/build.go | 49 ++++++++++++++++++++++++++++++++------------- src/cmd/go/doc.go | 6 ++++++ src/cmd/go/help.go | 6 ++++++ 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index e9347525a6..2bb9924995 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -286,22 +286,48 @@ func (v *stringsFlag) String() string { return "" } -var pkgFilter = func(p *Package) bool { return true } +func pkgsMain(pkgs []*Package) (res []*Package) { + for _, p := range pkgs { + if p.Name == "main" { + res = append(res, p) + } + } + return res +} + +func pkgsNotMain(pkgs []*Package) (res []*Package) { + for _, p := range pkgs { + if p.Name != "main" { + res = append(res, p) + } + } + return res +} + +var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs } func buildModeInit() { var codegenArg, ldBuildmode string switch buildBuildmode { case "archive": - pkgFilter = func(p *Package) bool { return p.Name != "main" } + pkgsFilter = pkgsNotMain + case "c-archive": + pkgsFilter = func(p []*Package) []*Package { + if len(p) != 1 || p[0].Name != "main" { + fatalf("-buildmode=c-archive requires exactly one main package") + } + return p + } + exeSuffix = ".a" + ldBuildmode = "c-archive" case "c-shared": - pkgFilter = func(p *Package) bool { return p.Name == "main" } + pkgsFilter = pkgsMain platform := goos + "/" + goarch switch platform { case "linux/amd64": case "android/arm": default: - fmt.Fprintf(os.Stderr, "go %s: -buildmode=c-shared not supported on %s\n", platform) - os.Exit(2) + fatalf("-buildmode=c-shared not supported on %s\n", platform) } if goarch == "amd64" { codegenArg = "-shared" @@ -310,7 +336,7 @@ func buildModeInit() { case "default": ldBuildmode = "exe" case "exe": - pkgFilter = func(p *Package) bool { return p.Name == "main" } + pkgsFilter = pkgsMain ldBuildmode = "exe" default: fatalf("buildmode=%s not supported", buildBuildmode) @@ -385,10 +411,8 @@ func runBuild(cmd *Command, args []string) { } a := &action{} - for _, p := range packages(args) { - if pkgFilter(p) { - a.deps = append(a.deps, b.action(modeBuild, depMode, p)) - } + for _, p := range pkgsFilter(packages(args)) { + a.deps = append(a.deps, b.action(modeBuild, depMode, p)) } b.do(a) } @@ -409,7 +433,7 @@ See also: go build, go get, go clean. func runInstall(cmd *Command, args []string) { raceInit() - pkgs := packagesForBuild(args) + pkgs := pkgsFilter(packagesForBuild(args)) for _, p := range pkgs { if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") { @@ -429,9 +453,6 @@ func runInstall(cmd *Command, args []string) { a := &action{} var tools []*action for _, p := range pkgs { - if !pkgFilter(p) { - continue - } // If p is a tool, delay the installation until the end of the build. // This avoids installing assemblers/compilers that are being executed // by other steps in the build. diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go index e880a238c8..a9dfe4355d 100644 --- a/src/cmd/go/doc.go +++ b/src/cmd/go/doc.go @@ -657,6 +657,12 @@ are: Build the listed non-main packages into .a files. Packages named main are ignored. + -buildmode=c-archive + Build the listed main package, plus all packages it imports, + into a C archive file. The only callable symbols will be those + functions marked as exported. Requires exactly one main package + to be listed. + -buildmode=c-shared Build the listed main packages, plus all packages that they import, into C shared libraries. The only callable symbols will diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go index dafebd0141..254d08a906 100644 --- a/src/cmd/go/help.go +++ b/src/cmd/go/help.go @@ -376,6 +376,12 @@ are: Build the listed non-main packages into .a files. Packages named main are ignored. + -buildmode=c-archive + Build the listed main package, plus all packages it imports, + into a C archive file. The only callable symbols will be those + functions marked as exported. Requires exactly one main package + to be listed. + -buildmode=c-shared Build the listed main packages, plus all packages that they import, into C shared libraries. The only callable symbols will