Convert build scripts to Python #31
|
@ -22,4 +22,7 @@ sdk/io_stubs.c
|
|||
sdk/orca_surface.c
|
||||
*bind_gen.c
|
||||
|
||||
.vscode/launch.json
|
||||
.vscode/settings.json
|
||||
|
||||
__pycache__
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
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)
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
|
||||
from build_runtime import attach_build_runtime
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
subparsers = parser.add_subparsers(required=True, title='commands')
|
||||
attach_build_runtime(subparsers)
|
||||
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
|
@ -0,0 +1,32 @@
|
|||
import glob
|
||||
import os
|
||||
import subprocess
|
||||
import traceback
|
||||
|
||||
from contextlib import contextmanager
|
||||
|
||||
@contextmanager
|
||||
def pushd(new_dir):
|
||||
previous_dir = os.getcwd()
|
||||
os.chdir(new_dir)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
os.chdir(previous_dir)
|
||||
|
||||
|
||||
def removeall(dir):
|
||||
[os.remove(f) for f in glob.iglob("{}/*".format(dir), recursive=True)]
|
||||
os.removedirs(dir)
|
||||
|
||||
|
||||
def shellish(func):
|
||||
def shellfunc(*args, **kwargs):
|
||||
try:
|
||||
func(*args, **kwargs)
|
||||
except subprocess.CalledProcessError as err:
|
||||
print()
|
||||
print(f"ERROR (code {err.returncode}): The following command failed:")
|
||||
print(" ".join(err.cmd))
|
||||
exit(err.returncode)
|
||||
return shellfunc
|
Loading…
Reference in New Issue