1535dbc13SAlexander von Gluck IV#!/bin/env python3 2535dbc13SAlexander von Gluck IV# 3535dbc13SAlexander von Gluck IV# Haiku build configuration tool 4535dbc13SAlexander von Gluck IV# Copyright 2002-2018, Haiku, Inc. All rights reserved. 5535dbc13SAlexander von Gluck IV# 6535dbc13SAlexander von Gluck IV 7535dbc13SAlexander von Gluck IVimport argparse 8535dbc13SAlexander von Gluck IVimport os 9535dbc13SAlexander von Gluck IVimport subprocess 10535dbc13SAlexander von Gluck IVimport sys 11cf62f22aSAlexander von Gluck IVimport errno 12535dbc13SAlexander von Gluck IVfrom pprint import pprint 13535dbc13SAlexander von Gluck IV 14535dbc13SAlexander von Gluck IVparser = argparse.ArgumentParser(description='Configure a build of Haiku') 154d182b9bSAlexander von Gluck IVparser.add_argument('--target-arch', nargs=1, 164d182b9bSAlexander von Gluck IV help='Target architectures. First provided is primary.', type=str, action='append', 17*c59cde3dSAlexander von Gluck IV choices=('x86_gcc2', 'x86', 'x86_64', 'ppc', 'm68k', 'arm', 'arm64', 'riscv64')) 18535dbc13SAlexander von Gluck IVparser.add_argument('--bootstrap', nargs=3, 19535dbc13SAlexander von Gluck IV help='Prepare for a bootstrap build. No pre-built packages will be used, instead they will be built from the sources (in several phases).', 20535dbc13SAlexander von Gluck IV metavar=('<haikuporter>','<haikuports.cross>', '<haikuports>')) 21535dbc13SAlexander von Gluck IVparser.add_argument('--build-gcc-toolchain', nargs=1, 22535dbc13SAlexander von Gluck IV help='Assume cross compilation. Build a gcc-based toolchain.', 23535dbc13SAlexander von Gluck IV metavar=('<buildtools dir>')) 244d182b9bSAlexander von Gluck IVparser.add_argument('--use-gcc-toolchain', nargs=1, 254d182b9bSAlexander von Gluck IV help='Assume cross compilation. Build using an existing gcc-based toolchain.', 26535dbc13SAlexander von Gluck IV metavar=('<prefix>')) 274d182b9bSAlexander von Gluck IVparser.add_argument('--use-clang', default=False, action='store_true', help='Assume native clang build') 28535dbc13SAlexander von Gluck IVparser.add_argument('--distro-compatibility', nargs=1, 29535dbc13SAlexander von Gluck IV help='The distribution\'s level of compatibility with the official Haiku distribution. The generated files will contain the respective trademarks accordingly.', 30535dbc13SAlexander von Gluck IV choices=('official', 'compatible', 'default'), default='default') 31535dbc13SAlexander von Gluck IVargs = vars(parser.parse_args()) 32535dbc13SAlexander von Gluck IV 33cf62f22aSAlexander von Gluck IV### Global functions 34535dbc13SAlexander von Gluck IV 35cf62f22aSAlexander von Gluck IVdef mkdir_p(path): 36cf62f22aSAlexander von Gluck IV try: 37cf62f22aSAlexander von Gluck IV os.makedirs(path) 38cf62f22aSAlexander von Gluck IV except OSError as exc: 39cf62f22aSAlexander von Gluck IV if exc.errno == errno.EEXIST and os.path.isdir(path): 40cf62f22aSAlexander von Gluck IV pass 41cf62f22aSAlexander von Gluck IV else: 42cf62f22aSAlexander von Gluck IV raise 43535dbc13SAlexander von Gluck IV 44535dbc13SAlexander von Gluck IVdef bok(message): 45535dbc13SAlexander von Gluck IV start_color = "" 46535dbc13SAlexander von Gluck IV end_color = "" 47535dbc13SAlexander von Gluck IV if sys.stdout.isatty(): 48535dbc13SAlexander von Gluck IV start_color = "\033[92m" 49535dbc13SAlexander von Gluck IV end_color = "\033[0m" 50535dbc13SAlexander von Gluck IV print(start_color + message + end_color) 51535dbc13SAlexander von Gluck IV 52535dbc13SAlexander von Gluck IVdef berror(message): 53535dbc13SAlexander von Gluck IV start_color = "" 54535dbc13SAlexander von Gluck IV end_color = "" 55535dbc13SAlexander von Gluck IV if sys.stdout.isatty(): 56535dbc13SAlexander von Gluck IV start_color = "\033[91m" 57535dbc13SAlexander von Gluck IV end_color = "\033[0m" 58535dbc13SAlexander von Gluck IV print(start_color + message + end_color) 59535dbc13SAlexander von Gluck IV 60535dbc13SAlexander von Gluck IVdef binfo(message): 61535dbc13SAlexander von Gluck IV start_color = "" 62535dbc13SAlexander von Gluck IV end_color = "" 63535dbc13SAlexander von Gluck IV if sys.stdout.isatty(): 64535dbc13SAlexander von Gluck IV start_color = "\033[94m" 65535dbc13SAlexander von Gluck IV end_color = "\033[0m" 66535dbc13SAlexander von Gluck IV print(start_color + message + end_color) 67535dbc13SAlexander von Gluck IV 68cf62f22aSAlexander von Gluck IV### Global Varables 69cf62f22aSAlexander von Gluck IV 70cf62f22aSAlexander von Gluck IV(host_sysname, host_nodename, host_release, host_version, host_machine) = os.uname() 71cf62f22aSAlexander von Gluck IVbuildConfig = [] 72cf62f22aSAlexander von Gluck IV 73cf62f22aSAlexander von Gluck IV# TODO: Remove "../.." if this ever moves to the source root 74cf62f22aSAlexander von Gluck IVsourceDir = os.path.realpath(os.path.dirname(os.path.realpath(__file__)) + "/../..") 75cf62f22aSAlexander von Gluck IVoutputDir = os.getcwd() 76cf62f22aSAlexander von Gluck IV 77cf62f22aSAlexander von Gluck IV# If run in our source dir, assume generated 78cf62f22aSAlexander von Gluck IVif outputDir == sourceDir: 79cf62f22aSAlexander von Gluck IV outputDir = sourceDir + "/generated" 80cf62f22aSAlexander von Gluck IV mkdir_p(outputDir) 81cf62f22aSAlexander von Gluck IV 82cf62f22aSAlexander von Gluck IV### Helper Functions 83cf62f22aSAlexander von Gluck IV 84535dbc13SAlexander von Gluck IV# Run a command, collect stdout into a string 85535dbc13SAlexander von Gluck IVdef cmdrun(cmd): 86535dbc13SAlexander von Gluck IV return subprocess.check_output(cmd).decode(sys.stdout.encoding) 87535dbc13SAlexander von Gluck IV 88535dbc13SAlexander von Gluck IV# Get a config key 89535dbc13SAlexander von Gluck IVdef get_build_config(key): 90535dbc13SAlexander von Gluck IV global buildConfig 91535dbc13SAlexander von Gluck IV for i in buildConfig: 92535dbc13SAlexander von Gluck IV if i["key"] == key: 93535dbc13SAlexander von Gluck IV return i["value"] 94535dbc13SAlexander von Gluck IV return None 95535dbc13SAlexander von Gluck IV 96535dbc13SAlexander von Gluck IV# Delete a config key 97535dbc13SAlexander von Gluck IVdef drop_build_config(key): 98535dbc13SAlexander von Gluck IV global buildConfig 99535dbc13SAlexander von Gluck IV value = get_build_config(key) 100535dbc13SAlexander von Gluck IV if value != None: 101535dbc13SAlexander von Gluck IV buildConfig.remove({"key": key, "value": value}) 102535dbc13SAlexander von Gluck IV 103535dbc13SAlexander von Gluck IV# Set a config key 104535dbc13SAlexander von Gluck IVdef set_build_config(key, value): 105535dbc13SAlexander von Gluck IV global buildConfig 106535dbc13SAlexander von Gluck IV if get_build_config(key) != None: 107535dbc13SAlexander von Gluck IV drop_build_config(key) 108535dbc13SAlexander von Gluck IV buildConfig.append({"key": key, "value": value}) 109535dbc13SAlexander von Gluck IV 110cf62f22aSAlexander von Gluck IVdef write_build_config(filename): 111cf62f22aSAlexander von Gluck IV global buildConfig 112cf62f22aSAlexander von Gluck IV with open(filename, "w") as fh: 11376392ecaSAlexander von Gluck IV fh.write("# -- WARNING --\n") 11476392ecaSAlexander von Gluck IV fh.write("# This file was AUTOMATICALLY GENERATED by configure, and will be completely\n") 11576392ecaSAlexander von Gluck IV fh.write("# overwritten the next time configure is run.\n\n") 116cf62f22aSAlexander von Gluck IV for i in buildConfig: 117cf62f22aSAlexander von Gluck IV fh.write(i["key"] + " ?= " + str(i["value"]) + " ;\n") 118cf62f22aSAlexander von Gluck IV 119535dbc13SAlexander von Gluck IVdef triplet_lookup(arch): 120535dbc13SAlexander von Gluck IV if arch == "x86_gcc2": 121535dbc13SAlexander von Gluck IV return "i586-pc-haiku" 122535dbc13SAlexander von Gluck IV elif arch == "x86": 123535dbc13SAlexander von Gluck IV return "i586-pc-haiku" 124535dbc13SAlexander von Gluck IV elif arch == "x86_64": 125535dbc13SAlexander von Gluck IV return "x86_64-unknown-haiku" 126535dbc13SAlexander von Gluck IV elif arch == "ppc": 127535dbc13SAlexander von Gluck IV return "powerpc-apple-haiku" 128535dbc13SAlexander von Gluck IV elif arch == "m68k": 129535dbc13SAlexander von Gluck IV return "m68k-unknown-haiku" 130535dbc13SAlexander von Gluck IV elif arch == "arm": 131535dbc13SAlexander von Gluck IV return "arm-unknown-haiku" 132535dbc13SAlexander von Gluck IV elif arch == "riscv64": 133535dbc13SAlexander von Gluck IV return "riscv64-unknown-haiku" 134535dbc13SAlexander von Gluck IV else: 135535dbc13SAlexander von Gluck IV berror("Unsupported target architecture: " + arch) 136535dbc13SAlexander von Gluck IV exit(1) 137535dbc13SAlexander von Gluck IV 138cf62f22aSAlexander von Gluck IVdef platform_lookup(sysname): 139cf62f22aSAlexander von Gluck IV if sysname == "Darwin": 140cf62f22aSAlexander von Gluck IV return "darwin" 141cf62f22aSAlexander von Gluck IV elif sysname == "FreeBSD": 142cf62f22aSAlexander von Gluck IV return "freebsd" 143cf62f22aSAlexander von Gluck IV elif sysname == "Haiku": 144cf62f22aSAlexander von Gluck IV return "haiku_host" 145cf62f22aSAlexander von Gluck IV elif sysname == "Linux": 146cf62f22aSAlexander von Gluck IV return "linux" 147cf62f22aSAlexander von Gluck IV elif sysname == "OpenBSD": 148cf62f22aSAlexander von Gluck IV return "openbsd" 149cf62f22aSAlexander von Gluck IV elif sysname == "SunOS": 150cf62f22aSAlexander von Gluck IV return "sunos" 151cf62f22aSAlexander von Gluck IV else: 152cf62f22aSAlexander von Gluck IV berror("Unknown platform: " + sysname) 153cf62f22aSAlexander von Gluck IV exit(1) 154cf62f22aSAlexander von Gluck IV 155535dbc13SAlexander von Gluck IVdef setup_bootstrap(): 156535dbc13SAlexander von Gluck IV if args["bootstrap"] == None: 157535dbc13SAlexander von Gluck IV return 158535dbc13SAlexander von Gluck IV set_build_config("HOST_HAIKU_PORTER", os.path.abspath(args["bootstrap"][0])) 159535dbc13SAlexander von Gluck IV set_build_config("HAIKU_PORTS", os.path.abspath(args["bootstrap"][1])) 160535dbc13SAlexander von Gluck IV set_build_config("HAIKU_PORTS_CROSS", os.path.abspath(args["bootstrap"][2])) 161535dbc13SAlexander von Gluck IV 162535dbc13SAlexander von Gluck IVdef setup_host_tools(): 163535dbc13SAlexander von Gluck IV set_build_config("HOST_SHA256", "sha256sum") 164535dbc13SAlexander von Gluck IV set_build_config("HOST_EXTENDED_REGEX_SED", "sed -r") 165535dbc13SAlexander von Gluck IV 166535dbc13SAlexander von Gluck IVdef setup_host_compiler(): 167535dbc13SAlexander von Gluck IV cc = os.environ.get("CC") 168535dbc13SAlexander von Gluck IV if cc == None: 169535dbc13SAlexander von Gluck IV # We might want to step through each potential compiler here 170535dbc13SAlexander von Gluck IV cc = "gcc" 171cf62f22aSAlexander von Gluck IV set_build_config("HOST_PLATFORM", platform_lookup(host_sysname)) 172535dbc13SAlexander von Gluck IV set_build_config("HOST_CC", cc) 173535dbc13SAlexander von Gluck IV set_build_config("HOST_CC_LD", cmdrun([cc, "-print-prog-name=ld"]).strip()) 174535dbc13SAlexander von Gluck IV set_build_config("HOST_CC_OBJCOPY", cmdrun([cc, "-print-prog-name=objcopy"]).strip()) 175cf62f22aSAlexander von Gluck IV set_build_config("HOST_GCC_MACHINE", cmdrun([cc, "-dumpmachine"]).strip()) 176cf62f22aSAlexander von Gluck IV set_build_config("HOST_GCC_RAW_VERSION", cmdrun([cc, "-dumpversion"]).strip()) 177535dbc13SAlexander von Gluck IV 178535dbc13SAlexander von Gluck IVdef setup_target_compiler(arch): 179535dbc13SAlexander von Gluck IV cc = get_build_config("HOST_CC") 180cf62f22aSAlexander von Gluck IV triplet = triplet_lookup(arch) 181535dbc13SAlexander von Gluck IV set_build_config("HAIKU_GCC_RAW_VERSION_" + arch, cmdrun([cc, "-dumpversion"]).strip()) 182cf62f22aSAlexander von Gluck IV set_build_config("HAIKU_GCC_MACHINE_" + arch, triplet) 183535dbc13SAlexander von Gluck IV set_build_config("HAIKU_CPU_" + arch, arch) 184535dbc13SAlexander von Gluck IV if args["use_clang"]: 185cf62f22aSAlexander von Gluck IV set_build_config("HAIKU_CC_" + arch, "clang -target " + triplet + " -B llvm-") 186535dbc13SAlexander von Gluck IV 1874d182b9bSAlexander von Gluck IVdef build_gcc_toolchain(buildtools_dir, arch): 1884d182b9bSAlexander von Gluck IV bok(arch + " toolchain build complete!") 1894d182b9bSAlexander von Gluck IV 190535dbc13SAlexander von Gluck IV### Workflow 191535dbc13SAlexander von Gluck IV 192535dbc13SAlexander von Gluck IVumask = os.umask(0) 193535dbc13SAlexander von Gluck IVos.umask(umask) 194535dbc13SAlexander von Gluck IVif umask > 22: 195535dbc13SAlexander von Gluck IV berror("Your umask is too restrictive (should be <= 0022; is actually " + str(umask) + ")") 196535dbc13SAlexander von Gluck IV print() 197535dbc13SAlexander von Gluck IV berror("Additionally, if the source tree was cloned with a too-restrictive umask,") 198535dbc13SAlexander von Gluck IV berror("you will need to run \"git checkout\" again to fix this.") 199535dbc13SAlexander von Gluck IV exit(1) 200535dbc13SAlexander von Gluck IV 201535dbc13SAlexander von Gluck IVif args["target_arch"] == None: 2024d182b9bSAlexander von Gluck IV berror("You need to specify at least one target architecture via --target-arch") 203535dbc13SAlexander von Gluck IV exit(1) 204535dbc13SAlexander von Gluck IV 2054d182b9bSAlexander von Gluck IVif args["use_clang"] == False and args["build_gcc_toolchain"] == None and args["use_gcc_toolchain"] == None: 2064d182b9bSAlexander von Gluck IV berror("You need to pick a toolchain via --build-gcc-toolchain, --use-gcc-toolchain, or --use-clang") 207535dbc13SAlexander von Gluck IV exit(1) 2084d182b9bSAlexander von Gluck IVelif args["use_clang"] == True: 2094d182b9bSAlexander von Gluck IV bok("Using the host's clang toolchain with a haiku target.") 2104d182b9bSAlexander von Gluck IVelif args["build_gcc_toolchain"] != None: 2114d182b9bSAlexander von Gluck IV bok("Building a gcc cross-compiler.") 2124d182b9bSAlexander von Gluck IVelif args["use_gcc_toolchain"] != None: 2134d182b9bSAlexander von Gluck IV bok("Using the existing gcc toolchain at " + args["use_gcc_toolchain"][0]) 2144d182b9bSAlexander von Gluck IV 2154d182b9bSAlexander von Gluck IVmkdir_p(outputDir + "/build") 216535dbc13SAlexander von Gluck IV 217535dbc13SAlexander von Gluck IV# Some Defaults 218535dbc13SAlexander von Gluck IVset_build_config("TARGET_PLATFORM", "haiku") 219535dbc13SAlexander von Gluck IVset_build_config("HAIKU_INCLUDE_SOURCES", 0) 220535dbc13SAlexander von Gluck IVset_build_config("HAIKU_USE_GCC_PIPE", 0) 221535dbc13SAlexander von Gluck IVset_build_config("HAIKU_HOST_USE_32BIT", 0) 222535dbc13SAlexander von Gluck IVset_build_config("HAIKU_HOST_USE_XATTR", "") 223535dbc13SAlexander von Gluck IVset_build_config("HAIKU_HOST_USE_XATTR_REF", "") 224535dbc13SAlexander von Gluck IVset_build_config("HAIKU_DISTRO_COMPATIBILITY", args["distro_compatibility"]) 225535dbc13SAlexander von Gluck IV 226535dbc13SAlexander von Gluck IVsetup_bootstrap() 227535dbc13SAlexander von Gluck IVsetup_host_tools() 228535dbc13SAlexander von Gluck IVsetup_host_compiler() 229535dbc13SAlexander von Gluck IV 230535dbc13SAlexander von Gluck IVbinfo("Configuring a Haiku build at " + outputDir) 231535dbc13SAlexander von Gluck IV 2324d182b9bSAlexander von Gluck IVfor arch in args["target_arch"]: 2334d182b9bSAlexander von Gluck IV binfo("Configuring " + arch[0] + " architecture...") 2344d182b9bSAlexander von Gluck IV setup_target_compiler(arch[0]) 2354d182b9bSAlexander von Gluck IV 2364d182b9bSAlexander von Gluck IV if args["build_gcc_toolchain"] != None: 2374d182b9bSAlexander von Gluck IV build_gcc_toolchain(args["build_gcc_toolchain"][0], arch[0]) 2384d182b9bSAlexander von Gluck IV 239cf62f22aSAlexander von Gluck IVwrite_build_config(outputDir + "/build/BuildConfig") 240cf62f22aSAlexander von Gluck IV 241cf62f22aSAlexander von Gluck IV# Write out an entry Jamfile in our build directory 242cf62f22aSAlexander von Gluck IVwith open(outputDir + "/Jamfile", "w") as fh: 243cf62f22aSAlexander von Gluck IV fh.write("# -- WARNING --\n") 244cf62f22aSAlexander von Gluck IV fh.write("# This file was AUTOMATICALLY GENERATED by configure, and will be completely\n") 245cf62f22aSAlexander von Gluck IV fh.write("# overwritten the next time configure is run.\n\n") 246cf62f22aSAlexander von Gluck IV fh.write("HAIKU_TOP = " + os.path.relpath(sourceDir, outputDir) + " ;\n") 247cf62f22aSAlexander von Gluck IV fh.write("HAIKU_OUTPUT_DIR = " + os.path.relpath(outputDir, os.getcwd()) + " ;\n\n") 248cf62f22aSAlexander von Gluck IV fh.write("include [ FDirName $(HAIKU_TOP) Jamfile ] ;\n") 249cf62f22aSAlexander von Gluck IV 250cf62f22aSAlexander von Gluck IVbok("Configuration complete!") 251