github.com/sagernet/sing-box@v1.2.7/cmd/internal/build_shared/sdk.go (about)

     1  package build_shared
     2  
     3  import (
     4  	"go/build"
     5  	"os"
     6  	"path/filepath"
     7  	"runtime"
     8  	"sort"
     9  	"strconv"
    10  	"strings"
    11  
    12  	"github.com/sagernet/sing-box/log"
    13  	"github.com/sagernet/sing/common"
    14  	"github.com/sagernet/sing/common/rw"
    15  )
    16  
    17  var (
    18  	androidSDKPath string
    19  	androidNDKPath string
    20  )
    21  
    22  func FindSDK() {
    23  	searchPath := []string{
    24  		"$ANDROID_HOME",
    25  		"$HOME/Android/Sdk",
    26  		"$HOME/.local/lib/android/sdk",
    27  		"$HOME/Library/Android/sdk",
    28  	}
    29  	for _, path := range searchPath {
    30  		path = os.ExpandEnv(path)
    31  		if rw.FileExists(path + "/licenses/android-sdk-license") {
    32  			androidSDKPath = path
    33  			break
    34  		}
    35  	}
    36  	if androidSDKPath == "" {
    37  		log.Fatal("android SDK not found")
    38  	}
    39  	if !findNDK() {
    40  		log.Fatal("android NDK not found")
    41  	}
    42  
    43  	os.Setenv("ANDROID_HOME", androidSDKPath)
    44  	os.Setenv("ANDROID_SDK_HOME", androidSDKPath)
    45  	os.Setenv("ANDROID_NDK_HOME", androidNDKPath)
    46  	os.Setenv("NDK", androidNDKPath)
    47  	os.Setenv("PATH", os.Getenv("PATH")+":"+filepath.Join(androidNDKPath, "toolchains", "llvm", "prebuilt", runtime.GOOS+"-x86_64", "bin"))
    48  }
    49  
    50  func findNDK() bool {
    51  	if rw.FileExists(androidSDKPath + "/ndk/25.1.8937393") {
    52  		androidNDKPath = androidSDKPath + "/ndk/25.1.8937393"
    53  		return true
    54  	}
    55  	ndkVersions, err := os.ReadDir(androidSDKPath + "/ndk")
    56  	if err != nil {
    57  		return false
    58  	}
    59  	versionNames := common.Map(ndkVersions, os.DirEntry.Name)
    60  	if len(versionNames) == 0 {
    61  		return false
    62  	}
    63  	sort.Slice(versionNames, func(i, j int) bool {
    64  		iVersions := strings.Split(versionNames[i], ".")
    65  		jVersions := strings.Split(versionNames[j], ".")
    66  		for k := 0; k < len(iVersions) && k < len(jVersions); k++ {
    67  			iVersion, _ := strconv.Atoi(iVersions[k])
    68  			jVersion, _ := strconv.Atoi(jVersions[k])
    69  			if iVersion != jVersion {
    70  				return iVersion > jVersion
    71  			}
    72  		}
    73  		return true
    74  	})
    75  	for _, versionName := range versionNames {
    76  		if rw.FileExists(androidSDKPath + "/ndk/" + versionName) {
    77  			androidNDKPath = androidSDKPath + "/ndk/" + versionName
    78  			return true
    79  		}
    80  	}
    81  	return false
    82  }
    83  
    84  var GoBinPath string
    85  
    86  func FindMobile() {
    87  	goBin := filepath.Join(build.Default.GOPATH, "bin")
    88  	if !rw.FileExists(goBin + "/" + "gobind") {
    89  		log.Fatal("missing gomobile installation")
    90  	}
    91  	GoBinPath = goBin
    92  }