You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
v2ray-core/tools/build/build.go

239 lines
5.8 KiB

package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"
)
var (
targetOS = flag.String("os", runtime.GOOS, "Target OS of this build.")
targetArch = flag.String("arch", runtime.GOARCH, "Target CPU arch of this build.")
archive = flag.Bool("zip", false, "Whether to make an archive of files or not.")
GOPATH string
repoRoot string
)
type OS string
const (
Windows = OS("windows")
MacOS = OS("darwin")
Linux = OS("linux")
)
type Architecture string
const (
X86 = Architecture("386")
Amd64 = Architecture("amd64")
Arm = Architecture("arm")
Arm64 = Architecture("arm64")
)
func getRepoVersion() (string, error) {
revHead, err := exec.Command("git", "rev-parse", "HEAD").Output()
if err != nil {
return "", err
}
version, err := exec.Command("git", "name-rev", "--tags", "--name-only", strings.TrimSpace(string(revHead))).Output()
if err != nil {
return "", err
}
verStr := strings.TrimSpace(string(version))
if strings.HasSuffix(verStr, "^0") {
verStr = verStr[:len(verStr)-2]
}
if verStr == "undefined" {
verStr = "custom"
}
return verStr, nil
}
func getOS() OS {
if targetOS == nil {
panic("OS is not specified.")
}
osStr := strings.ToLower(*targetOS)
if osStr == "windows" || osStr == "win" {
return Windows
}
if osStr == "darwin" || osStr == "mac" || osStr == "macos" || osStr == "osx" {
return MacOS
}
if osStr == "linux" || osStr == "debian" || osStr == "ubuntu" || osStr == "redhat" || osStr == "centos" {
return Linux
}
panic("Unknown OS " + *targetOS)
}
func getArch() Architecture {
if targetArch == nil {
panic("Arch is not specified.")
}
archStr := strings.ToLower(*targetArch)
if archStr == "x86" || archStr == "386" || archStr == "i386" {
return X86
}
if archStr == "amd64" || archStr == "x86-64" || archStr == "x64" {
return Amd64
}
if archStr == "arm" {
return Arm
}
if archStr == "arm64" {
return Arm64
}
panic("Unknown Arch " + *targetArch)
}
func getSuffix(vos OS, arch Architecture) string {
suffix := "-custom"
switch vos {
case Windows:
switch arch {
case X86:
suffix = "-windows-32"
case Amd64:
suffix = "-windows-64"
}
case MacOS:
suffix = "-macos"
case Linux:
switch arch {
case X86:
suffix = "-linux-32"
case Amd64:
suffix = "-linux-64"
case Arm:
suffix = "-linux-arm"
case Arm64:
suffix = "-linux-arm64"
}
}
return suffix
}
func createTargetDirectory(version string, vos OS, arch Architecture) (string, error) {
suffix := "-custom"
if version != "custom" {
suffix = getSuffix(vos, arch)
}
targetDir := filepath.Join(GOPATH, "bin", "v2ray"+suffix)
if version != "custom" {
os.RemoveAll(targetDir)
}
err := os.MkdirAll(targetDir, os.ModeDir|0777)
return targetDir, err
}
func getTargetFile(vos OS, arch Architecture) string {
suffix := getSuffix(vos, arch)
if vos == "Windows" {
suffix += ".exe"
}
return "v2ray" + suffix
}
func normalizedContent(content []byte, vos OS) []byte {
str := strings.Replace(string(content), "\r\n", "\n", -1)
if vos == Windows {
str = strings.Replace(str, "\n", "\r\n", -1)
}
return []byte(str)
}
func copyConfigFiles(dir string, version string, vos OS, arch Architecture) error {
clientConfig, err := ioutil.ReadFile(filepath.Join(repoRoot, "release", "config", "vpoint_socks_vmess.json"))
if err != nil {
return err
}
clientConfig = normalizedContent(clientConfig, vos)
clientConfigName := "vpoint_socks_vmess.json"
if vos == Windows || vos == MacOS {
clientConfigName = "config.json"
}
err = ioutil.WriteFile(filepath.Join(dir, clientConfigName), clientConfig, 0777)
if err != nil {
return err
}
if vos == Windows || vos == MacOS {
return nil
}
serverConfig, err := ioutil.ReadFile(filepath.Join(repoRoot, "release", "config", "vpoint_vmess_freedom.json"))
if err != nil {
return err
}
serverConfig = normalizedContent(serverConfig, vos)
err = ioutil.WriteFile(filepath.Join(dir, "vpoint_vmess_freedom.json"), serverConfig, 0777)
if err != nil {
return err
}
return nil
}
func buildV2Ray(targetDir, targetFile string, version string, vos OS, arch Architecture) error {
ldFlags := "-s"
if version != "custom" {
year, month, day := time.Now().UTC().Date()
today := fmt.Sprintf("%04d%02d%02d", year, int(month), day)
ldFlags = ldFlags + " -X github.com/v2ray/v2ray-core.version=" + version + " -X github.com/v2ray/v2ray-core.build=" + today
}
target := filepath.Join(targetDir, targetFile)
fmt.Println("Building to " + target)
cmd := exec.Command("go", "build", "-o", target, "-compiler", "gc", "-ldflags", "\""+ldFlags+"\"", "github.com/v2ray/v2ray-core/release/server")
cmd.Env = append(cmd.Env, "GOOS="+string(vos), "GOARCH="+string(arch))
cmd.Env = append(cmd.Env, os.Environ()...)
_, err := cmd.Output()
return err
}
func main() {
flag.Parse()
v2rayOS := getOS()
v2rayArch := getArch()
if err := os.Chdir(repoRoot); err != nil {
fmt.Println("Unable to switch to V2Ray repo: " + err.Error())
return
}
version, err := getRepoVersion()
if err != nil {
fmt.Println("Unable to detect V2Ray version: " + err.Error())
return
}
fmt.Printf("Building V2Ray (%s) for %s %s\n", version, v2rayOS, v2rayArch)
targetDir, err := createTargetDirectory(version, v2rayOS, v2rayArch)
if err != nil {
fmt.Println("Unable to create directory " + targetDir + ": " + err.Error())
}
targetFile := getTargetFile(v2rayOS, v2rayArch)
err = buildV2Ray(targetDir, targetFile, version, v2rayOS, v2rayArch)
if err != nil {
fmt.Println("Unable to build V2Ray: " + err.Error())
}
err = copyConfigFiles(targetDir, version, v2rayOS, v2rayArch)
if err != nil {
fmt.Println("Unable to copy config files: " + err.Error())
}
}
func init() {
GOPATH = os.Getenv("GOPATH")
repoRoot = filepath.Join(GOPATH, "src", "github.com", "v2ray", "v2ray-core")
}