in tools/build_gcsfuse/main.go [53:190]
func buildBinaries(dstDir, srcDir, version string, buildArgs []string) (err error) {
osys := runtime.GOOS
// Create the target structure.
{
dirs := []string{
"bin",
"sbin",
}
for _, d := range dirs {
err = os.Mkdir(path.Join(dstDir, d), 0755)
if err != nil {
err = fmt.Errorf("mkdir: %w", err)
return
}
}
}
pathEnv, exists := os.LookupEnv("PATH")
if !exists {
err = fmt.Errorf("$PATH not found in OS")
return
}
// Create a directory to become GOPATH for our build below.
gopath, err := os.MkdirTemp("", "build_gcsfuse_gopath")
if err != nil {
err = fmt.Errorf("TempDir: %w", err)
return
}
defer os.RemoveAll(gopath)
// Create a directory to become GOCACHE for our build below.
var gocache string
gocache, err = os.MkdirTemp("", "build_gcsfuse_gocache")
if err != nil {
err = fmt.Errorf("TempDir: %w", err)
return
}
defer os.RemoveAll(gocache)
// Make it appear as if the source directory is at the appropriate position
// in $GOPATH.
gcsfuseDir := path.Join(gopath, "src/github.com/googlecloudplatform/gcsfuse")
err = os.MkdirAll(path.Dir(gcsfuseDir), 0700)
if err != nil {
err = fmt.Errorf("MkdirAll: %w", err)
return
}
err = os.Symlink(srcDir, gcsfuseDir)
if err != nil {
err = fmt.Errorf("symlink: %w", err)
return
}
// mount(8) expects a different name format on Linux.
mountHelperName := "mount_gcsfuse"
if osys == "linux" {
mountHelperName = "mount.gcsfuse"
}
// Build the binaries.
binaries := []struct {
goTarget string
outputPath string
}{
{
"github.com/googlecloudplatform/gcsfuse/v2",
"bin/gcsfuse",
},
{
"github.com/googlecloudplatform/gcsfuse/v2/tools/mount_gcsfuse",
path.Join("sbin", mountHelperName),
},
}
for _, bin := range binaries {
log.Printf("Building %s to %s", bin.goTarget, bin.outputPath)
// Set up arguments.
cmd := exec.Command(
"go",
"build",
"-C",
srcDir,
"-o",
path.Join(dstDir, bin.outputPath))
if path.Base(bin.outputPath) == "gcsfuse" {
cmd.Args = append(
cmd.Args,
"-ldflags",
fmt.Sprintf("-X github.com/googlecloudplatform/gcsfuse/v2/common.gcsfuseVersion=%s", version),
)
cmd.Args = append(cmd.Args, buildArgs...)
}
cmd.Args = append(cmd.Args, bin.goTarget)
// Set up environment.
cmd.Env = append(
os.Environ(),
"GO15VENDOREXPERIMENT=1",
"GO111MODULE=auto",
fmt.Sprintf("PATH=%s", pathEnv),
fmt.Sprintf("GOROOT=%s", runtime.GOROOT()),
fmt.Sprintf("GOPATH=%s", gopath),
fmt.Sprintf("GOCACHE=%s", gocache),
"CGO_ENABLED=0",
)
// Build.
var output []byte
output, err = cmd.CombinedOutput()
if err != nil {
err = fmt.Errorf("%v: %w\nOutput:\n%s", cmd, err, output)
if strings.Contains(string(output), "flag provided but not defined: -C") {
err = fmt.Errorf("%v: %w\nOutput:\n%s\nPlease upgrade to go version 1.20 or higher", cmd, err, output)
}
return
}
}
// On Linux, also support `mount -t fuse.gcsfuse`. If there's no explicit
// helper for this type, /sbin/mount.fuse will call the gcsfuse executable
// directly, but it doesn't support the right argument format. So we install
// an explicit helper.
if osys == "linux" {
err = os.Symlink("mount.gcsfuse", path.Join(dstDir, "sbin/mount.fuse.gcsfuse"))
if err != nil {
err = fmt.Errorf("symlink: %w", err)
return
}
}
return
}