ios.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import codecs
  2. import os
  3. import subprocess
  4. import sys
  5. import common_compiler_flags
  6. from SCons.Variables import BoolVariable
  7. def has_ios_osxcross():
  8. return "OSXCROSS_IOS" in os.environ
  9. def options(opts):
  10. opts.Add(BoolVariable("ios_simulator", "Target iOS Simulator", False))
  11. opts.Add("ios_min_version", "Target minimum iphoneos/iphonesimulator version", "12.0")
  12. opts.Add(
  13. "IOS_TOOLCHAIN_PATH",
  14. "Path to iOS toolchain",
  15. "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
  16. )
  17. opts.Add("IOS_SDK_PATH", "Path to the iOS SDK", "")
  18. if has_ios_osxcross():
  19. opts.Add("ios_triple", "Triple for ios toolchain", "")
  20. def exists(env):
  21. return sys.platform == "darwin" or has_ios_osxcross()
  22. def generate(env):
  23. if env["arch"] not in ("universal", "arm64", "x86_64"):
  24. raise ValueError("Only universal, arm64, and x86_64 are supported on iOS. Exiting.")
  25. if env["ios_simulator"]:
  26. sdk_name = "iphonesimulator"
  27. env.Append(CCFLAGS=["-mios-simulator-version-min=" + env["ios_min_version"]])
  28. env.Append(LINKFLAGS=["-mios-simulator-version-min=" + env["ios_min_version"]])
  29. else:
  30. sdk_name = "iphoneos"
  31. env.Append(CCFLAGS=["-miphoneos-version-min=" + env["ios_min_version"]])
  32. env.Append(LINKFLAGS=["-miphoneos-version-min=" + env["ios_min_version"]])
  33. if sys.platform == "darwin":
  34. if env["IOS_SDK_PATH"] == "":
  35. try:
  36. env["IOS_SDK_PATH"] = codecs.utf_8_decode(
  37. subprocess.check_output(["xcrun", "--sdk", sdk_name, "--show-sdk-path"]).strip()
  38. )[0]
  39. except (subprocess.CalledProcessError, OSError):
  40. raise ValueError(
  41. "Failed to find SDK path while running xcrun --sdk {} --show-sdk-path.".format(sdk_name)
  42. )
  43. compiler_path = env["IOS_TOOLCHAIN_PATH"] + "/usr/bin/"
  44. env["CC"] = compiler_path + "clang"
  45. env["CXX"] = compiler_path + "clang++"
  46. env["AR"] = compiler_path + "ar"
  47. env["RANLIB"] = compiler_path + "ranlib"
  48. env["SHLIBSUFFIX"] = ".dylib"
  49. env["ENV"]["PATH"] = env["IOS_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
  50. else:
  51. # OSXCross
  52. compiler_path = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}"
  53. env["CC"] = compiler_path + "clang"
  54. env["CXX"] = compiler_path + "clang++"
  55. env["AR"] = compiler_path + "ar"
  56. env["RANLIB"] = compiler_path + "ranlib"
  57. env["SHLIBSUFFIX"] = ".dylib"
  58. env.Prepend(
  59. CPPPATH=[
  60. "$IOS_SDK_PATH/usr/include",
  61. "$IOS_SDK_PATH/System/Library/Frameworks/AudioUnit.framework/Headers",
  62. ]
  63. )
  64. env.Append(CCFLAGS=["-stdlib=libc++"])
  65. binpath = os.path.join(env["IOS_TOOLCHAIN_PATH"], "usr", "bin")
  66. if binpath not in env["ENV"]["PATH"]:
  67. env.PrependENVPath("PATH", binpath)
  68. if env["arch"] == "universal":
  69. if env["ios_simulator"]:
  70. env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
  71. env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
  72. else:
  73. env.Append(LINKFLAGS=["-arch", "arm64"])
  74. env.Append(CCFLAGS=["-arch", "arm64"])
  75. else:
  76. env.Append(LINKFLAGS=["-arch", env["arch"]])
  77. env.Append(CCFLAGS=["-arch", env["arch"]])
  78. env.Append(CCFLAGS=["-isysroot", env["IOS_SDK_PATH"]])
  79. env.Append(LINKFLAGS=["-isysroot", env["IOS_SDK_PATH"], "-F" + env["IOS_SDK_PATH"]])
  80. env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED"])
  81. # Refer to https://github.com/godotengine/godot/blob/master/platform/ios/detect.py:
  82. # Disable by default as it makes linking in Xcode very slow.
  83. if env["lto"] == "auto":
  84. env["lto"] = "none"
  85. common_compiler_flags.generate(env)