github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/ci/packages/build.go (about)

     1  /*
     2   * Copyright (C) 2020 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package packages
    19  
    20  import (
    21  	"fmt"
    22  	"os"
    23  	"path"
    24  	"path/filepath"
    25  	"runtime"
    26  	"strings"
    27  
    28  	"github.com/magefile/mage/sh"
    29  	"github.com/mysteriumnetwork/go-ci/env"
    30  	"github.com/mysteriumnetwork/node/logconfig"
    31  	"github.com/mysteriumnetwork/node/utils/fileutil"
    32  	"github.com/rs/zerolog/log"
    33  )
    34  
    35  // Build builds the project. Like go tool, it supports cross-platform build with env vars: GOOS, GOARCH.
    36  func Build() error {
    37  	logconfig.Bootstrap()
    38  	if err := buildBinary(path.Join("cmd", "mysterium_node", "mysterium_node.go"), "myst"); err != nil {
    39  		return err
    40  	}
    41  	if err := copyConfig("myst"); err != nil {
    42  		return err
    43  	}
    44  	if err := buildBinary(path.Join("cmd", "supervisor", "supervisor.go"), "myst_supervisor"); err != nil {
    45  		return err
    46  	}
    47  	return nil
    48  }
    49  
    50  func linkerFlags() (flags []string) {
    51  	if env.Str(env.BuildBranch) != "" {
    52  		flags = append(flags, "-X", fmt.Sprintf("'github.com/mysteriumnetwork/node/metadata.BuildBranch=%s'", env.Str(env.BuildBranch)))
    53  	}
    54  	if env.Str(env.BuildCommit) != "" {
    55  		flags = append(flags, "-X", fmt.Sprintf("'github.com/mysteriumnetwork/node/metadata.BuildCommit=%s'", env.Str(env.BuildCommit)))
    56  	}
    57  	if env.Str(env.BuildNumber) != "" {
    58  		flags = append(flags, "-X", fmt.Sprintf("'github.com/mysteriumnetwork/node/metadata.BuildNumber=%s'", env.Str(env.BuildNumber)))
    59  	}
    60  	if env.Str(env.BuildVersion) != "" {
    61  		flags = append(flags, "-X", fmt.Sprintf("'github.com/mysteriumnetwork/node/metadata.Version=%s'", env.Str(env.BuildVersion)))
    62  	}
    63  	return flags
    64  }
    65  
    66  func buildCrossBinary(os, arch string) error {
    67  	return sh.Run("bin/build_xgo", os+"/"+arch)
    68  }
    69  
    70  func buildBinary(source, target string) error {
    71  	targetOS, ok := os.LookupEnv("GOOS")
    72  	if !ok {
    73  		targetOS = runtime.GOOS
    74  	}
    75  	targetArch, ok := os.LookupEnv("GOARCH")
    76  	if !ok {
    77  		targetArch = runtime.GOARCH
    78  	}
    79  	return buildBinaryFor(source, target, targetOS, targetArch, nil, false)
    80  }
    81  
    82  func buildBinaryFor(source, target, targetOS, targetArch string, extraEnvs map[string]string, buildStatic bool) error {
    83  	log.Info().Msgf("Building %s -> %s %s/%s", source, target, targetOS, targetArch)
    84  
    85  	buildDir, err := filepath.Abs(path.Join("build", target))
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	var flags = []string{"build"}
    91  	if env.Bool("FLAG_RACE") {
    92  		flags = append(flags, "-race")
    93  	}
    94  
    95  	ldFlags := linkerFlags()
    96  	if buildStatic {
    97  		ldFlags = append(ldFlags, "-extldflags", `"-static"`)
    98  	}
    99  	flags = append(flags, fmt.Sprintf(`-ldflags=-w -s %s`, strings.Join(ldFlags, " ")))
   100  	if buildStatic {
   101  		flags = append(flags, "-a", "-tags", "netgo")
   102  	}
   103  
   104  	if targetOS == "windows" {
   105  		target += ".exe"
   106  	}
   107  	flags = append(flags, "-o", path.Join(buildDir, target), source)
   108  
   109  	envi := map[string]string{
   110  		"GOOS":   targetOS,
   111  		"GOARCH": targetArch,
   112  	}
   113  	for envKey, envValue := range extraEnvs {
   114  		envi[envKey] = envValue
   115  	}
   116  
   117  	if buildStatic {
   118  		envi["CGO_ENABLED"] = "0"
   119  	}
   120  	return sh.RunWith(envi, "go", flags...)
   121  }
   122  
   123  func copyConfig(target string) error {
   124  	dest, err := filepath.Abs(path.Join("build", target, "config"))
   125  	if err != nil {
   126  		return err
   127  	}
   128  
   129  	common, err := filepath.Abs(path.Join("bin", "package", "config", "common"))
   130  	if err != nil {
   131  		return err
   132  	}
   133  	if err := fileutil.CopyDirs(common, dest); err != nil {
   134  		return err
   135  	}
   136  
   137  	targetOS, ok := os.LookupEnv("GOOS")
   138  	if !ok {
   139  		targetOS = runtime.GOOS
   140  	}
   141  	osSpecific, err := filepath.Abs(path.Join("bin", "package", "config", targetOS))
   142  	if err != nil {
   143  		return err
   144  	}
   145  	if err := fileutil.CopyDirs(osSpecific, dest); err != nil {
   146  		return err
   147  	}
   148  
   149  	return nil
   150  }