sdk.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package build_shared
  2. import (
  3. "go/build"
  4. "os"
  5. "path/filepath"
  6. "runtime"
  7. "sort"
  8. "strconv"
  9. "strings"
  10. "github.com/sagernet/sing-box/log"
  11. "github.com/sagernet/sing/common"
  12. "github.com/sagernet/sing/common/rw"
  13. )
  14. var (
  15. androidSDKPath string
  16. androidNDKPath string
  17. )
  18. func FindSDK() {
  19. searchPath := []string{
  20. "$ANDROID_HOME",
  21. "$HOME/Android/Sdk",
  22. "$HOME/.local/lib/android/sdk",
  23. "$HOME/Library/Android/sdk",
  24. }
  25. for _, path := range searchPath {
  26. path = os.ExpandEnv(path)
  27. if rw.IsFile(filepath.Join(path, "licenses", "android-sdk-license")) {
  28. androidSDKPath = path
  29. break
  30. }
  31. }
  32. if androidSDKPath == "" {
  33. log.Fatal("android SDK not found")
  34. }
  35. if !findNDK() {
  36. log.Fatal("android NDK not found")
  37. }
  38. os.Setenv("ANDROID_HOME", androidSDKPath)
  39. os.Setenv("ANDROID_SDK_HOME", androidSDKPath)
  40. os.Setenv("ANDROID_NDK_HOME", androidNDKPath)
  41. os.Setenv("NDK", androidNDKPath)
  42. os.Setenv("PATH", os.Getenv("PATH")+":"+filepath.Join(androidNDKPath, "toolchains", "llvm", "prebuilt", runtime.GOOS+"-x86_64", "bin"))
  43. }
  44. func findNDK() bool {
  45. const fixedVersion = "28.0.12916984"
  46. const versionFile = "source.properties"
  47. if fixedPath := filepath.Join(androidSDKPath, "ndk", fixedVersion); rw.IsFile(filepath.Join(fixedPath, versionFile)) {
  48. androidNDKPath = fixedPath
  49. return true
  50. }
  51. if ndkHomeEnv := os.Getenv("ANDROID_NDK_HOME"); rw.IsFile(filepath.Join(ndkHomeEnv, versionFile)) {
  52. androidNDKPath = ndkHomeEnv
  53. return true
  54. }
  55. ndkVersions, err := os.ReadDir(filepath.Join(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. currentNDKPath := filepath.Join(androidSDKPath, "ndk", versionName)
  77. if rw.IsFile(filepath.Join(currentNDKPath, versionFile)) {
  78. androidNDKPath = currentNDKPath
  79. log.Warn("reproducibility warning: using NDK version " + versionName + " instead of " + fixedVersion)
  80. return true
  81. }
  82. }
  83. return false
  84. }
  85. var GoBinPath string
  86. func FindMobile() {
  87. goBin := filepath.Join(build.Default.GOPATH, "bin")
  88. if runtime.GOOS == "windows" {
  89. if !rw.IsFile(filepath.Join(goBin, "gobind.exe")) {
  90. log.Fatal("missing gomobile installation")
  91. }
  92. } else {
  93. if !rw.IsFile(filepath.Join(goBin, "gobind")) {
  94. log.Fatal("missing gomobile installation")
  95. }
  96. }
  97. GoBinPath = goBin
  98. }