cutego/internal/utils/env.go

331 lines
8.2 KiB
Go
Raw Normal View History

2016-10-28 05:00:58 +03:00
package utils
import (
"os"
"os/exec"
2016-10-28 05:00:58 +03:00
"path/filepath"
"runtime"
"strconv"
2016-10-28 05:00:58 +03:00
"strings"
2018-12-17 20:56:35 +03:00
"sync"
2016-10-28 05:00:58 +03:00
)
var qT_VERSION_CACHE string
2016-12-30 23:40:48 +03:00
func QT_VERSION() string {
if version, ok := os.LookupEnv("QT_VERSION"); ok {
2016-12-30 23:40:48 +03:00
return version
}
if QT_PKG_CONFIG() {
if qT_VERSION_CACHE == "" {
qT_VERSION_CACHE = strings.TrimSpace(RunCmd(exec.Command("pkg-config", "--modversion", "Qt5Core"), "cgo.LinuxPkgConfig_modVersion"))
}
return qT_VERSION_CACHE
}
return "5.12.0"
2016-12-30 23:40:48 +03:00
}
func QT_VERSION_NUM() int {
version := QT_VERSION()
vmaj, _ := strconv.Atoi(string(version[0]))
vmin, _ := strconv.Atoi(strings.Replace(version[1:], ".", "", -1))
return vmaj*1e3 + vmin
}
func QT_VERSION_MAJOR() string {
if version, ok := os.LookupEnv("QT_VERSION_MAJOR"); ok {
return version
}
if QT_VERSION_NUM() >= 5091 {
return QT_VERSION()
}
return strings.Join(strings.Split(QT_VERSION(), ".")[:2], ".")
}
2018-07-16 19:50:11 +03:00
func QT_API(def string) string {
if api, ok := os.LookupEnv("QT_API"); ok {
return api
}
return def
}
func QT_API_NUM(def string) int {
version := QT_API(def)
vmaj, _ := strconv.Atoi(string(version[0]))
vmin, _ := strconv.Atoi(strings.Replace(version[1:], ".", "", -1))
return vmaj*1e3 + vmin
}
2016-10-28 05:00:58 +03:00
func QT_DIR() string {
path := qT_DIR()
if ExistsDir(path) {
return path
}
return strings.Replace(path, QT_VERSION_MAJOR(), QT_VERSION(), -1)
}
func qT_DIR() string {
if dir, ok := os.LookupEnv("QT_DIR"); ok {
2016-10-28 05:00:58 +03:00
return filepath.Clean(dir)
}
2018-10-14 19:50:54 +03:00
prefix := os.Getenv("HOME")
2016-10-28 05:00:58 +03:00
if runtime.GOOS == "windows" {
prefix = windowsSystemDrive() + "\\"
2017-08-31 00:04:28 +03:00
}
2018-10-14 19:50:54 +03:00
if dir := filepath.Join(prefix, "Qt", "Qt"+QT_VERSION()); ExistsDir(dir) {
2017-08-31 00:04:28 +03:00
return dir
2016-10-28 05:00:58 +03:00
}
2018-10-14 19:50:54 +03:00
if dir := filepath.Join(prefix, "Qt"+QT_VERSION()); ExistsDir(dir) {
return dir
}
return filepath.Join(prefix, "Qt")
2016-10-28 05:00:58 +03:00
}
func QT_FAT() bool {
return os.Getenv("QT_FAT") == "true"
}
2016-10-28 05:00:58 +03:00
func QT_STUB() bool {
return os.Getenv("QT_STUB") == "true" && !QT_FAT()
2016-10-28 05:00:58 +03:00
}
func QT_DEBUG() bool {
return os.Getenv("QT_DEBUG") == "true"
}
func QT_DEBUG_QML() bool {
return os.Getenv("QT_DEBUG_QML") == "true"
}
func QT_DEBUG_CONSOLE() bool {
return os.Getenv("QT_DEBUG_CONSOLE") == "true"
}
func CheckBuildTarget(buildTarget string, docker bool) {
switch buildTarget {
case "android", "android-emulator",
2017-03-17 23:36:32 +03:00
"ios", "ios-simulator",
"sailfish", "sailfish-emulator", "asteroid",
"rpi1", "rpi2", "rpi3",
"windows", "darwin", "linux",
2018-06-09 03:31:50 +03:00
"homebrew", "ubports",
"js", "wasm": //TODO: pkg_config ?
default:
if !strings.Contains(buildTarget, "_") {
Log.Panicf("failed to recognize build target %v", buildTarget)
}
}
if !docker && buildTarget != runtime.GOOS && !strings.Contains(buildTarget, "_") {
switch {
case QT_MSYS2():
2017-03-17 23:36:32 +03:00
Log.Fatalf("%v is not supported as a deploy target on %v with MSYS2 -> install the official Qt version instead and try again", buildTarget, runtime.GOOS)
2018-10-09 19:38:22 +03:00
case QT_HOMEBREW(), QT_MACPORTS(), QT_NIX():
Log.Fatalf("%v is not supported as a deploy target on %v with HomeBrew/MacPorts/Nix -> install the official Qt version instead and try again", buildTarget, runtime.GOOS)
case QT_PKG_CONFIG() && !QT_UBPORTS():
2017-03-17 23:36:32 +03:00
Log.Fatalf("%v is not supported as a deploy target on %v with PkgConfig -> install the official Qt version instead and try again", buildTarget, runtime.GOOS)
}
}
}
2017-02-01 18:38:51 +03:00
func CI() bool {
return os.Getenv("CI") == "true"
2017-02-01 18:38:51 +03:00
}
func QT_QMAKE_DIR() string {
if dir, ok := os.LookupEnv("QT_QMAKE_DIR"); ok {
2017-02-27 03:23:27 +03:00
return filepath.Clean(dir)
}
return ""
}
2017-02-28 21:27:55 +03:00
func QT_DOCKER() bool {
return os.Getenv("QT_DOCKER") == "true"
2017-02-28 21:27:55 +03:00
}
func QT_VAGRANT() bool {
return os.Getenv("QT_VAGRANT") == "true"
}
2017-03-17 23:36:32 +03:00
//TODO: use qmake props
func ToolPath(tool, target string) string {
2017-03-17 23:36:32 +03:00
if dir := QT_QMAKE_DIR(); dir != "" {
return filepath.Join(dir, tool)
}
if strings.HasPrefix(target, "sailfish") && !QT_SAILFISH() {
target = runtime.GOOS
}
switch target {
case "darwin":
2018-10-09 19:38:22 +03:00
if QT_NIX() {
path, _ := exec.LookPath(tool)
path, _ = filepath.Abs(path)
return path
}
return filepath.Join(QT_DARWIN_DIR(), "bin", tool)
case "windows":
if runtime.GOOS == target {
if QT_MSYS2() {
if QT_MSYS2_STATIC() {
return filepath.Join(QT_MSYS2_DIR(), "qt5-static", "bin", tool)
}
return filepath.Join(QT_MSYS2_DIR(), "bin", tool)
}
2019-03-30 19:41:02 +03:00
path := filepath.Join(QT_DIR(), QT_VERSION_MAJOR(), MINGWDIR(), "bin", tool)
2018-10-15 01:43:19 +03:00
if !ExistsDir(filepath.Join(QT_DIR(), QT_VERSION_MAJOR())) {
2019-03-30 19:41:02 +03:00
path = filepath.Join(QT_DIR(), QT_VERSION(), MINGWDIR(), "bin", tool)
}
if !ExistsFile(path + ".exe") {
2019-03-30 19:41:02 +03:00
path = strings.Replace(path, MINGWDIR(), "mingw53_32", -1)
2018-10-15 01:43:19 +03:00
}
2018-10-15 05:26:30 +03:00
if !ExistsFile(path + ".exe") {
2018-10-15 01:43:19 +03:00
path = strings.Replace(path, "mingw53_32", "mingw49_32", -1)
}
return path
}
return filepath.Join(QT_MXE_DIR(), "usr", QT_MXE_TRIPLET(), "qt5", "bin", tool)
case "linux", "ubports":
if QT_PKG_CONFIG() {
return filepath.Join(strings.TrimSpace(RunCmd(exec.Command("pkg-config", "--variable=host_bins", "Qt5Core"), "cgo.LinuxPkgConfig_hostBins")), tool)
}
2018-10-15 01:43:19 +03:00
path := filepath.Join(QT_DIR(), QT_VERSION_MAJOR(), "gcc_64", "bin", tool)
if !ExistsDir(filepath.Join(QT_DIR(), QT_VERSION_MAJOR())) {
path = filepath.Join(QT_DIR(), QT_VERSION(), "gcc_64", "bin", tool)
2018-10-15 01:43:19 +03:00
}
return path
case "ios", "ios-simulator":
return filepath.Join(QT_DIR(), QT_VERSION_MAJOR(), "ios", "bin", tool)
case "android":
return filepath.Join(QT_DIR(), QT_VERSION_MAJOR(), "android_armv7", "bin", tool)
case "android-emulator":
return filepath.Join(QT_DIR(), QT_VERSION_MAJOR(), "android_x86", "bin", tool)
case "sailfish", "sailfish-emulator":
return filepath.Join("/srv/mer/targets/SailfishOS-"+QT_SAILFISH_VERSION()+"-i486/usr/lib/qt5/bin/", tool)
//TODO support indirect access on desktop: return filepath.Join(os.Getenv("HOME"), ".config", "SailfishOS-SDK", "mer-sdk-tools", "MerSDK", "SailfishOS-i486", tool)
case "asteroid":
//TODO:
case "rp1", "rpi2", "rpi3":
return filepath.Join(QT_DIR(), QT_VERSION_MAJOR(), target, "bin", tool)
}
return ""
}
2017-04-11 00:38:26 +03:00
2018-10-14 19:50:54 +03:00
//TODO: detect webkit support automatically
2017-04-11 00:38:26 +03:00
func QT_WEBKIT() bool {
return os.Getenv("QT_WEBKIT") == "true"
2017-04-11 00:38:26 +03:00
}
func CGO_CFLAGS_ALLOW() string {
if allowed, ok := os.LookupEnv("CGO_CFLAGS_ALLOW"); ok {
return allowed
}
return ".*"
}
func CGO_CXXFLAGS_ALLOW() string {
if allowed, ok := os.LookupEnv("CGO_CXXFLAGS_ALLOW"); ok {
return allowed
}
return ".*"
}
func CGO_LDFLAGS_ALLOW() string {
if allowed, ok := os.LookupEnv("CGO_LDFLAGS_ALLOW"); ok {
return allowed
}
return ".*"
}
func GOARCH() string {
if arch, ok := os.LookupEnv("GOARCH"); ok {
return arch
}
return runtime.GOARCH
}
func QT_DYNAMIC_SETUP() bool {
return os.Getenv("QT_DYNAMIC_SETUP") == "true"
}
2018-12-17 20:56:35 +03:00
func GOFLAGS() string {
if flags, ok := os.LookupEnv("GOFLAGS"); ok {
return flags
}
if UseGOMOD("") {
2018-12-17 20:56:35 +03:00
return "-mod=vendor"
}
return ""
}
func GOMOD(path string) string {
if mod, ok := os.LookupEnv("GOMOD"); ok {
return mod
}
cmd := exec.Command("go", "env", "GOMOD")
cmd.Dir = path
return strings.TrimSpace(RunCmd(cmd, "GOMOD"))
}
var (
useGOMOD int
2018-12-17 20:56:35 +03:00
useGOMODMutex = new(sync.Mutex)
)
func UseGOMOD(path string) (r bool) {
useGOMODMutex.Lock()
if useGOMOD == 0 {
if len(GOMOD(path)) != 0 {
useGOMOD = 1
} else {
useGOMOD = -1
}
2018-12-17 20:56:35 +03:00
}
r = useGOMOD == 1
2018-12-17 20:56:35 +03:00
useGOMODMutex.Unlock()
return
}
func QT_GEN_OPENGL() bool {
return os.Getenv("QT_GEN_OPENGL") == "true"
}
func GoList(args ...string) *exec.Cmd {
cmd := exec.Command("go", "list")
if UseGOMOD("") {
2019-01-21 21:28:43 +03:00
if /*strings.Contains(strings.Join(args, "|"), "github.com/therecipe/env_"+runtime.GOOS+"_amd64") ||*/ strings.Contains(strings.Join(args, "|"), "github.com/therecipe/qt/internal") {
//TODO: make env readonly if it can't be found inside ./vendor ...
cmd.Args = append(cmd.Args, "-mod=readonly")
} else {
cmd.Args = append(cmd.Args, GOFLAGS())
}
}
cmd.Args = append(cmd.Args, "-e", "-f")
cmd.Args = append(cmd.Args, args...)
2019-01-22 00:14:26 +03:00
cmd.Env = append(os.Environ(), []string{"CGO_ENABLED=0"}...)
return cmd
}
var (
goListCache = make(map[string]string)
goListCacheMutex = new(sync.Mutex)
)
func GoListOptional(args ...string) (r string) {
goListCacheMutex.Lock()
if _, ok := goListCache[strings.Join(args, "|")]; !ok {
goListCache[strings.Join(args, "|")] = RunCmdOptional(GoList(args[:2]...), args[2])
}
r = goListCache[strings.Join(args, "|")]
goListCacheMutex.Unlock()
return r
}
func QT_STATIC() bool {
return os.Getenv("QT_STATIC") == "true"
}