Skip to content

Commit

Permalink
feat: add asm support to please_go_install (#1484)
Browse files Browse the repository at this point in the history
* chore: fix cgo file name typo

Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>

* refactor: return go files from toolchain cgo

Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>

* refactor: return c files from toolchain cgo

Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>

* refactor: return object files from toolchain cgo and c compile

Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>

* feat: add asm support to please_go_install

Signed-off-by: Mark Sagi-Kazar <mark.sagikazar@gmail.com>

* Fix duplicate objects passed to pack

* Add test and clean up

* Lint fixes

Co-authored-by: tatskaari <jpoole@thoughtmachine.net>
  • Loading branch information
sagikazarmark and Tatskaari authored Feb 1, 2021
1 parent 93eda04 commit 08ae34a
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 33 deletions.
1 change: 1 addition & 0 deletions test/go_modules/test_repo/src/BUILD_FILE
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ go_test (
"//third_party/go:cli-init",
"//third_party/go:zstd",
"//third_party/go:go-sqlite3",
"//third_party/go:snappy",
]
)
5 changes: 5 additions & 0 deletions test/go_modules/test_repo/src/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/DataDog/zstd"
"github.com/golang/snappy"
"github.com/mattn/go-sqlite3"
"github.com/peterebden/go-cli-init/v2"
)
Expand All @@ -18,4 +19,8 @@ func TestZSTImport(t *testing.T) {

func TestSQLLite3(t *testing.T) {
_ = sqlite3.SQLiteStmt{}
}

func TestSnappy(t *testing.T) {
_ = snappy.MaxEncodedLen(1234)
}
6 changes: 6 additions & 0 deletions test/go_modules/test_repo/third_party/go/BUILD_FILE
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,9 @@ go_module(
strip = ["testdata"],
version = "v3.21.0",
)

go_module(
name = "snappy",
module = "github.com/golang/snappy",
version = "v0.0.2",
)
30 changes: 26 additions & 4 deletions tools/please_go_install/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,35 @@ func compilePackage(target string, pkg *build.Package) {
fmt.Printf("mkdir -p %s\n", filepath.Dir(out))
fmt.Printf("ln %s %s\n", fullPaths(allSrcs, pkg.Dir), workDir)

goFiles := pkg.GoFiles

var objFiles []string

if len(pkg.CgoFiles) > 0 {
tc.cgo(pkg.Dir, workDir, pkg.CgoFiles)
tc.cCompile(workDir, pkg.CFiles, pkg.CgoFiles)
cFiles := pkg.CFiles

cgoGoFiles, cgoCFiles := tc.cgo(pkg.Dir, workDir, pkg.CgoFiles)
goFiles = append(goFiles, cgoGoFiles...)
cFiles = append(cFiles, cgoCFiles...)

cObjFiles := tc.cCompile(workDir, cFiles, pkg.CgoCFLAGS)
objFiles = append(objFiles, cObjFiles...)
}

tc.goCompile(workDir, opts.ImportConfig, out, pkg.GoFiles, pkg.CgoFiles)
tc.pack(workDir, out, pkg.CFiles, pkg.CgoFiles)
if len(pkg.SFiles) > 0 {
asmH, symabis := tc.symabis(pkg.Dir, workDir, pkg.SFiles)

tc.goAsmCompile(workDir, opts.ImportConfig, out, goFiles, asmH, symabis)

asmObjFiles := tc.asm(pkg.Dir, workDir, pkg.SFiles)
objFiles = append(objFiles, asmObjFiles...)
} else {
tc.goCompile(workDir, opts.ImportConfig, out, goFiles)
}

if len(objFiles) > 0 {
tc.pack(workDir, out, objFiles)
}

fmt.Printf("echo \"packagefile %s=%s\" >> %s\n", target, out, opts.ImportConfig)

Expand Down
87 changes: 58 additions & 29 deletions tools/please_go_install/toolchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"fmt"
"go/build"
"path/filepath"
"strings"
)
Expand All @@ -24,48 +25,76 @@ func paths(ps []string) string {
}

// cgo invokes go tool cgo to generate cgo sources and objects into the target directory
func (tc *toolchain) cgo(sourceDir string, objectDir string, cgoFiles []string) {
func (tc *toolchain) cgo(sourceDir string, objectDir string, cgoFiles []string) ([]string, []string) {
goFiles := []string{"_cgo_gotypes.go"}
cFiles := []string{"_cgo_export.c"}

for _, cgoFile := range cgoFiles {
goFiles = append(goFiles, strings.TrimSuffix(cgoFile, ".go")+".cgo1.go")
cFiles = append(cFiles, strings.TrimSuffix(cgoFile, ".go")+".cgo2.c")
}

fmt.Printf("(cd %s; %s tool cgo -objdir $OLDPWD/%s %s)\n", sourceDir, tc.goTool, objectDir, paths(cgoFiles))

return goFiles, cFiles
}

// goCompile will compile the go sources and the generated .cgo2.go sources for the cgo files (if any)
func (tc *toolchain) goCompile(dir, importcfg, out string, goFiles, cgoFiles []string) {
files := goFiles
if len(cgoFiles) > 0 {
files = append(files, "_cgo_gotypes.go")
for _, cgo := range cgoFiles {
files = append(files, strings.TrimSuffix(cgo, ".go")+".cgo1.go")
}
}
fmt.Printf("%s tool compile -pack -importcfg %s -o %s %s\n", tc.goTool, importcfg, out, fullPaths(files, dir))
// goCompile will compile the go sources and the generated .cgo1.go sources for the cgo files (if any)
func (tc *toolchain) goCompile(dir, importcfg, out string, goFiles []string) {
fmt.Printf("%s tool compile -pack -importcfg %s -o %s %s\n", tc.goTool, importcfg, out, fullPaths(goFiles, dir))
}

// cCompile will compile c sources as well as the .cgo1.c files generated by go tool cgo (if any)
func (tc *toolchain) cCompile(dir string, cFiles, cgoFiles []string) {
files := cFiles
for _, cgo := range cgoFiles {
files = append(files, strings.TrimSuffix(cgo, ".go")+".cgo2.c")
}
fmt.Printf("(cd %s; %s -Wno-error -ldl -Wno-unused-parameter -c -I . _cgo_export.c %s)\n", dir, tc.ccTool, paths(files))
// goAsmCompile will compile the go sources linking to the the abi symbols generated from symabis()
func (tc *toolchain) goAsmCompile(dir, importcfg, out string, goFiles []string, asmH, symabys string) {
fmt.Printf("%s tool compile -pack -importcfg %s -asmhdr %s -symabis %s -o %s %s\n", tc.goTool, importcfg, asmH, symabys, out, fullPaths(goFiles, dir))
}

func (tc *toolchain) pack(dir, out string, cFiles, cgoFiles []string) {
objs := []string{"_cgo_export.o"}
for _, o := range cFiles {
objs = append(objs, strings.TrimSuffix(o, ".c")+".o")
}
// cCompile will compile c sources and return the object files that will be generated
func (tc *toolchain) cCompile(dir string, cFiles []string, cFlags []string) []string {
objFiles := make([]string, len(cFiles))

for _, o := range cgoFiles {
objs = append(objs, strings.TrimSuffix(o, ".go")+".cgo2.o")
for i, cFile := range cFiles {
objFiles[i] = strings.TrimSuffix(cFile, ".c") + ".o"
}

if len(objs) == 1 {
return
}
fmt.Printf("(cd %s; %s -Wno-error -Wno-unused-parameter -c %s -I . _cgo_export.c %s)\n", dir, tc.ccTool, strings.Join(cFlags, " "), paths(cFiles))

fmt.Printf("%s tool pack r %s %s\n", tc.goTool, out, fullPaths(objs, dir))
return objFiles
}

// pack will add the object files in dir to the archive
func (tc *toolchain) pack(dir, archive string, objFiles []string) {
fmt.Printf("%s tool pack r %s %s\n", tc.goTool, archive, fullPaths(objFiles, dir))
}

// link will link the archive into an executable
func (tc *toolchain) link(archive, out string) {
fmt.Printf("%s tool link -importcfg %s -o %s %s", opts.GoTool, opts.ImportConfig, out, archive)
}

// symabis will generate the asm header as well as the abi symbol file for the provided asm files.
func (tc *toolchain) symabis(sourceDir, objectDir string, asmFiles []string) (string, string) {
asmH := fmt.Sprintf("%s/go_asm.h", objectDir)
symabis := fmt.Sprintf("%s/symabis", objectDir)

// the gc toolchain does this
fmt.Printf("touch %s\n", asmH)

fmt.Printf("(cd %s; %s tool asm -I . -I %s/pkg/include -D GOOS_%s -D GOARCH_%s -gensymabis -o $OLDPWD/%s %s)\n", sourceDir, opts.GoTool, build.Default.GOROOT, build.Default.GOOS, build.Default.GOARCH, symabis, paths(asmFiles))

return asmH, symabis
}

// asm will compile the asm files and return the objects that are generated
func (tc *toolchain) asm(sourceDir, objectDir string, asmFiles []string) []string {
objFiles := make([]string, len(asmFiles))

for i, asmFile := range asmFiles {
objFile := strings.TrimSuffix(asmFile, ".s") + ".o"
objFiles[i] = objFile

fmt.Printf("(cd %s; %s tool asm -I . -I %s/pkg/include -D GOOS_%s -D GOARCH_%s -o $OLDPWD/%s/%s %s)\n", sourceDir, opts.GoTool, build.Default.GOROOT, build.Default.GOOS, build.Default.GOARCH, objectDir, objFile, asmFile)
}

return objFiles
}

0 comments on commit 08ae34a

Please sign in to comment.