in build/mage/golang/build.go [89:209]
func Build(name, packageName, version string, opts ...BuildOption) func() error {
const (
defaultCgoEnabled = false
defaultGoOs = runtime.GOOS
defaultGoArch = runtime.GOARCH
defaultGoArm = ""
)
// Default build options
defaultOpts := &buildOpts{
binaryName: name,
packageName: packageName,
cgoEnabled: defaultCgoEnabled,
goOS: defaultGoOs,
goArch: defaultGoArch,
goArm: defaultGoArm,
}
// Apply options
for _, o := range opts {
o(defaultOpts)
}
return func() error {
// Retrieve git info first
mg.SerialDeps(git.CollectInfo)
// Generate artifact name
artifactName := fmt.Sprintf("%s-%s-%s%s", name, defaultOpts.goOS, defaultOpts.goArch, defaultOpts.goArm)
// Compilation flags
compilationFlags := []string{}
// Check if fips is enabled
buildTags := "-tags=!fips"
if os.Getenv("HARP_BUILD_FIPS_MODE") == "1" {
artifactName = fmt.Sprintf("%s-fips", artifactName)
compilationFlags = append(compilationFlags, "fips")
buildTags = "-tags=fips"
}
// Check if CGO is enabled
if defaultOpts.cgoEnabled {
artifactName = fmt.Sprintf("%s-cgo", artifactName)
compilationFlags = append(compilationFlags, "cgo")
}
// Enable PIE if requested
buildMode := "-buildmode=exe"
if defaultOpts.pieEnabled {
buildMode = "-buildmode=pie"
artifactName = fmt.Sprintf("%s-pie", artifactName)
compilationFlags = append(compilationFlags, "pie")
}
// Check compilation flags
strCompilationFlags := "defaults"
if len(compilationFlags) > 0 {
strCompilationFlags = strings.Join(compilationFlags, ",")
}
// Inject version information
varsSetByLinker := map[string]string{
"github.com/elastic/harp/build/version.Name": name,
"github.com/elastic/harp/build/version.AppName": packageName,
"github.com/elastic/harp/build/version.Version": version,
"github.com/elastic/harp/build/version.Commit": git.Revision,
"github.com/elastic/harp/build/version.Branch": git.Branch,
"github.com/elastic/harp/build/version.BuildDate": time.Now().Format(time.RFC3339),
"github.com/elastic/harp/build/version.BuildTags": strCompilationFlags,
}
var linkerArgs []string
for name, value := range varsSetByLinker {
linkerArgs = append(linkerArgs, "-X", fmt.Sprintf("'%s=%s'", name, value))
}
// Strip and remove DWARF
linkerArgs = append(linkerArgs, "-s", "-w")
// Assemble ldflags
ldflagsValue := strings.Join(linkerArgs, " ")
// Build environment
env := map[string]string{
"GOOS": defaultOpts.goOS,
"GOARCH": defaultOpts.goArch,
"CGO_ENABLED": "0",
}
if defaultOpts.cgoEnabled {
env["CGO_ENABLED"] = "1"
}
if defaultOpts.goArm != "" {
env["GOARM"] = defaultOpts.goArm
}
// Create output directory
if errMkDir := os.Mkdir("bin", 0o744); errMkDir != nil {
if !errors.Is(errMkDir, os.ErrExist) {
return fmt.Errorf("unable to create output directory: %w", errMkDir)
}
}
// Generate output filename
filename := fmt.Sprintf("bin/%s", artifactName)
if defaultOpts.goOS == "windows" {
filename = fmt.Sprintf("%s.exe", filename)
}
fmt.Fprintf(os.Stdout, " > Generating SBOM %s [%s] [os:%s arch:%s%s flags:%v tag:%v]\n", defaultOpts.binaryName, defaultOpts.packageName, defaultOpts.goOS, defaultOpts.goArch, defaultOpts.goArm, strCompilationFlags, version)
// Generate SBOM
if err := sh.RunWith(env, "cyclonedx-gomod", "app", "-json", "-output", fmt.Sprintf("%s.sbom.json", filename), "-files", "-licenses", "-main", fmt.Sprintf("cmd/%s", defaultOpts.binaryName), "-packages"); err != nil {
return fmt.Errorf("unable to generate SBOM for artifact: %w", err)
}
fmt.Fprintf(os.Stdout, " > Building %s [%s] [os:%s arch:%s%s flags:%v tag:%v]\n", defaultOpts.binaryName, defaultOpts.packageName, defaultOpts.goOS, defaultOpts.goArch, defaultOpts.goArm, strCompilationFlags, version)
// Compile
return sh.RunWith(env, "go", "build", buildMode, buildTags, "-trimpath", "-mod=readonly", "-ldflags", ldflagsValue, "-o", filename, packageName)
}
}