import argparse import os import platform import subprocess from utils import pushd, removeall, shellish def attach_build_runtime(subparsers): build = subparsers.add_parser("build-runtime", help="TODO") build.add_argument("--release", action="store_true", help="compile Orca in release mode (default is debug)") build.set_defaults(func=shellish(build_runtime)) def build_runtime(args): try: subprocess.run(["clang", "-v"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) except FileNotFoundError: print("ERROR: clang was not found on your system.") if platform.system() == "Windows": print("We recommend installing clang via the Visual Studio installer.") # TODO(ben): Link to the Visual Studio download page (I have no internet right now) elif platform.system() == "Darwin": print("Run the following to install it:") print() print(" brew install llvm") print() exit(1) # TODO(ben): Check for xcode command line tools build_milepost("lib", args.release) def build_milepost(target, release): print("Building milepost...") with pushd("milepost"): os.makedirs("bin", exist_ok=True) os.makedirs("lib", exist_ok=True) os.makedirs("resources", exist_ok=True) if target == "lib": if platform.system() == "Darwin": build_milepost_lib_mac(release) else: print(f"ERROR: can't build milepost for unknown platform '{platform.system()}'") elif target == "test": with pushd("examples/test_app"): # TODO? subprocess.run(["./build.sh"]) elif target == "clean": removeall("bin") else: print(f"ERROR: unrecognized milepost target '{target}'") exit(1) def build_milepost_lib_mac(release): sdk_dir = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk" flags = ["-mmacos-version-min=10.15.4", "-maes"] cflags = ["-std=c11"] debug_flags = ["-O3"] if release else ["-g", "-DDEBUG", "-DLOG_COMPILE_DEBUG"] ldflags = [f"-L{sdk_dir}/usr/lib", f"-F{sdk_dir}/System/Library/Frameworks/"] includes = ["-Isrc", "-Isrc/util", "-Isrc/platform", "-Iext", "-Iext/angle_headers"] # compile metal shader subprocess.run([ "xcrun", "-sdk", "macosx", "metal", # TODO: shaderFlagParam "-fno-fast-math", "-c", "-o", "lib/mtl_renderer.air", "src/mtl_renderer.metal", ], check=True) subprocess.run([ "xcrun", "-sdk", "macosx", "metallib", "-o", "lib/mtl_renderer.metallib", "lib/mtl_renderer.air", ], check=True) # compile milepost. We use one compilation unit for all C code, and one # compilation unit for all Objective-C code subprocess.run([ "clang", *debug_flags, "-c", "-o", "bin/milepost_c.o", *cflags, *flags, *includes, "src/milepost.c" ], check=True) subprocess.run([ "clang", *debug_flags, "-c", "-o", "bin/milepost_objc.o", *flags, *includes, "src/milepost.m" ], check=True) # build dynamic library subprocess.run([ "ld", *ldflags, "-dylib", "-o", "bin/libmilepost.dylib", "bin/milepost_c.o", "bin/milepost_objc.o", "-Llib", "-lc", "-framework", "Carbon", "-framework", "Cocoa", "-framework", "Metal", "-framework", "QuartzCore", "-weak-lEGL", "-weak-lGLESv2", ], check=True) # change dependent libs path to @rpath subprocess.run([ "install_name_tool", "-change", "./libEGL.dylib", "@rpath/libEGL.dylib", "bin/libmilepost.dylib", ], check=True) subprocess.run([ "install_name_tool", "-change", "./libGLESv2.dylib", "@rpath/libGLESv2.dylib", "bin/libmilepost.dylib", ], check=True) # add executable path to rpath. Client executable can still add its own # rpaths if needed, e.g. @executable_path/libs/ etc. subprocess.run([ "install_name_tool", "-id", "@rpath/libmilepost.dylib", "bin/libmilepost.dylib", ], check=True)