build.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. ##############################################################################
  2. # build.py script
  3. ##############################################################################
  4. import os
  5. import argparse
  6. import glob
  7. import subprocess
  8. import shutil
  9. import sys
  10. from pathlib import Path
  11. # build.py arguments
  12. ##############################################################################
  13. parser = argparse.ArgumentParser()
  14. parser.add_argument("-c", "--clean", help="Clean only", action="store_true")
  15. parser.add_argument("-g", "--generate", help="Generates only", action="store_true")
  16. parser.add_argument("-b", "--build", help="Builds only", action="store_true")
  17. parser.add_argument("--configuration", help="Specify the configuration. (all,debug,release)", default="all")
  18. parser.add_argument("--toolchain", help="Toolchain override.", default="")
  19. args = parser.parse_args()
  20. # constants
  21. ##############################################################################
  22. BUILD_FOLDER = "_build"
  23. COMPILER_FOLDER = "_compiler"
  24. DEPS_FOLDER = "_deps"
  25. # utility functions
  26. ##############################################################################
  27. def clear_dir(dir_path):
  28. if os.path.exists(dir_path):
  29. shutil.rmtree(dir_path, ignore_errors=True)
  30. path = Path(dir_path)
  31. path.mkdir(parents=True)
  32. if os.path.exists(dir_path):
  33. os.rmdir(dir_path)
  34. def copy_files(src_dir, dst_dir, match_exp):
  35. clear_dir(dst_dir)
  36. for filename in glob.glob(os.path.join(src_dir, match_exp)):
  37. shutil.copy(filename, dst_dir)
  38. def remove_files(src_dir, match_exp):
  39. for filename in glob.glob(os.path.join(src_dir, match_exp)):
  40. os.remove(filename)
  41. def init_vsvars():
  42. vswhere_path = r"%ProgramFiles(x86)%/Microsoft Visual Studio/Installer/vswhere.exe"
  43. vswhere_path = os.path.expandvars(vswhere_path)
  44. if not os.path.exists(vswhere_path):
  45. raise EnvironmentError("vswhere.exe not found at: %s", vswhere_path)
  46. vs_path = os.popen('"{}" -latest -property installationPath'.format(vswhere_path)).read().rstrip()
  47. vsvars_path = os.path.join(vs_path, "VC\\Auxiliary\\Build\\vcvars64.bat")
  48. output = os.popen('"{}" && set'.format(vsvars_path)).read()
  49. for line in output.splitlines():
  50. pair = line.split("=", 1)
  51. if(len(pair) >= 2):
  52. os.environ[pair[0]] = pair[1]
  53. # building
  54. ##############################################################################
  55. current_dir = os.getcwd()
  56. # generate premake for toolchain (specified or host detected)
  57. if args.toolchain:
  58. toolchain = args.toolchain
  59. else:
  60. if sys.platform == "win32":
  61. toolchain = "vs2019"
  62. elif sys.platform == "linux":
  63. toolchain = "gmake"
  64. elif sys.platform == "darwin":
  65. toolchain = "xcode4"
  66. # premake
  67. compiler_dir = os.path.join(current_dir, COMPILER_FOLDER)
  68. if not args.build and not args.clean:
  69. deps_dir = os.path.join(current_dir, DEPS_FOLDER)
  70. premake_proc = subprocess.Popen(f"{deps_dir}/premake/premake5 --file=premake5.lua {toolchain}", cwd=current_dir, shell=True)
  71. premake_proc.wait()
  72. # clean build check
  73. clean_build = False
  74. if args.clean:
  75. clean_build = True
  76. if clean_build and not os.path.exists(compiler_dir):
  77. quit()
  78. # build configurations
  79. config_debug = False
  80. config_release = False
  81. if args.configuration == "all":
  82. config_debug = True
  83. config_release = True
  84. elif args.configuration == "debug":
  85. config_debug = True
  86. elif args.configuration == "release":
  87. config_release = True
  88. # build compiler/toolchain (skip if generate_only is specified)
  89. build_dir = os.path.join(current_dir, BUILD_FOLDER)
  90. if not args.generate:
  91. if toolchain == "vs2019":
  92. compiler_dir = os.path.join(compiler_dir, "vs2019")
  93. init_vsvars()
  94. os.chdir(compiler_dir)
  95. if clean_build:
  96. subprocess.run("msbuild gameplay.sln -t:Clean")
  97. clear_dir(build_dir)
  98. else:
  99. if config_debug:
  100. subprocess.run("msbuild gameplay.sln /property:Configuration=Debug")
  101. if config_release:
  102. subprocess.run("msbuild gameplay.sln /property:Configuration=Release")
  103. elif toolchain == "gmake":
  104. compiler_dir = os.path.join(compiler_dir, "gmake")
  105. os.chdir(compiler_dir)
  106. if clean_build:
  107. subprocess.run("make clean", shell=True)
  108. clear_dir(build_dir)
  109. else:
  110. if config_debug:
  111. subprocess.run("make config=debug_x86_64", shell=True)
  112. if config_release:
  113. subprocess.run("make config=release_x86_64", shell=True)
  114. elif toolchain == "xcode4":
  115. compiler_dir = os.path.join(compiler_dir, "xcode4")
  116. os.chdir(compiler_dir)
  117. if clean_build:
  118. subprocess.run("xcodebuild clean -workspace gameplay.xcworkspace", shell=True)
  119. clear_dir(build_dir)
  120. else:
  121. if config_debug:
  122. subprocess.run("xcodebuild -workspace gameplay.xcworkspace -configuration Debug build", shell=True)
  123. if config_release:
  124. subprocess.run("xcodebuild -workspace gameplay.xcworkspace -configuration Release build", shell=True)
  125. else:
  126. print("Error: Compiler toolchain not supported.")