youtubebeat/vendor/github.com/elastic/beats/dev-tools/mage/build.go

145 lines
3.9 KiB
Go

// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package mage
import (
"fmt"
"go/build"
"log"
"os"
"path/filepath"
"strings"
"github.com/magefile/mage/sh"
"github.com/pkg/errors"
)
// BuildArgs are the arguments used for the "build" target and they define how
// "go build" is invoked.
type BuildArgs struct {
Name string // Name of binary. (On Windows '.exe' is appended.)
OutputDir string
CGO bool
Static bool
Env map[string]string
LDFlags []string
Vars map[string]string // Vars that are passed as -X key=value with the ldflags.
ExtraFlags []string
}
// DefaultBuildArgs returns the default BuildArgs for use in builds.
func DefaultBuildArgs() BuildArgs {
args := BuildArgs{
Name: BeatName,
CGO: build.Default.CgoEnabled,
Vars: map[string]string{
"github.com/elastic/beats/libbeat/version.buildTime": "{{ date }}",
"github.com/elastic/beats/libbeat/version.commit": "{{ commit }}",
},
}
repo, err := GetProjectRepoInfo()
if err != nil {
panic(errors.Wrap(err, "failed to determine project repo info"))
}
if !repo.IsElasticBeats() {
// Assume libbeat is vendored and prefix the variables.
prefix := repo.RootImportPath + "/vendor/"
prefixedVars := map[string]string{}
for k, v := range args.Vars {
prefixedVars[prefix+k] = v
}
args.Vars = prefixedVars
}
return args
}
// DefaultGolangCrossBuildArgs returns the default BuildArgs for use in
// cross-builds.
func DefaultGolangCrossBuildArgs() BuildArgs {
args := DefaultBuildArgs()
args.Name += "-" + Platform.GOOS + "-" + Platform.Arch
args.OutputDir = filepath.Join("build", "golang-crossbuild")
if bp, found := BuildPlatforms.Get(Platform.Name); found {
args.CGO = bp.Flags.SupportsCGO()
}
return args
}
// GolangCrossBuild invokes "go build" inside of the golang-crossbuild Docker
// environment.
func GolangCrossBuild(params BuildArgs) error {
if os.Getenv("GOLANG_CROSSBUILD") != "1" {
return errors.New("Use the crossBuild target. golangCrossBuild can " +
"only be executed within the golang-crossbuild docker environment.")
}
defer DockerChown(filepath.Join(params.OutputDir, params.Name+binaryExtension(GOOS)))
return Build(params)
}
// Build invokes "go build" to produce a binary.
func Build(params BuildArgs) error {
fmt.Println(">> build: Building", params.Name)
binaryName := params.Name + binaryExtension(GOOS)
if params.OutputDir != "" {
if err := os.MkdirAll(params.OutputDir, 0755); err != nil {
return err
}
}
// Environment
env := params.Env
if env == nil {
env = map[string]string{}
}
cgoEnabled := "0"
if params.CGO {
cgoEnabled = "1"
}
env["CGO_ENABLED"] = cgoEnabled
// Spec
args := []string{
"build",
"-o",
filepath.Join(params.OutputDir, binaryName),
}
args = append(args, params.ExtraFlags...)
// ldflags
ldflags := params.LDFlags
if params.Static {
ldflags = append(ldflags, `-extldflags '-static'`)
}
for k, v := range params.Vars {
ldflags = append(ldflags, fmt.Sprintf("-X %v=%v", k, v))
}
if len(ldflags) > 0 {
args = append(args, "-ldflags")
args = append(args, MustExpand(strings.Join(ldflags, " ")))
}
log.Println("Adding build environment vars:", env)
return sh.RunWith(env, "go", args...)
}