mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-27 18:51:41 +02:00
Get universal builds working again
Now we use lipo and build individually so we can pass the correct compiler flags per arch
This commit is contained in:
@@ -46,7 +46,7 @@ def run(*args, **extra_env):
|
|||||||
return subprocess.call(list(args), env=env, cwd=cwd)
|
return subprocess.call(list(args), env=env, cwd=cwd)
|
||||||
|
|
||||||
|
|
||||||
SETUP_CMD = [PYTHON, 'setup.py', '--build-universal-binary']
|
SETUP_CMD = [PYTHON, 'setup.py']
|
||||||
|
|
||||||
|
|
||||||
def build_frozen_launcher(extra_include_dirs):
|
def build_frozen_launcher(extra_include_dirs):
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ class Env:
|
|||||||
ldpaths: List[str] = []
|
ldpaths: List[str] = []
|
||||||
ccver: Tuple[int, int]
|
ccver: Tuple[int, int]
|
||||||
vcs_rev: str = ''
|
vcs_rev: str = ''
|
||||||
build_universal_binary: bool = False
|
|
||||||
binary_arch: BinaryArch = BinaryArch()
|
binary_arch: BinaryArch = BinaryArch()
|
||||||
native_optimizations: bool = False
|
native_optimizations: bool = False
|
||||||
|
|
||||||
@@ -71,14 +70,13 @@ class Env:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self, cc: List[str] = [], cppflags: List[str] = [], cflags: List[str] = [], ldflags: List[str] = [],
|
self, cc: List[str] = [], cppflags: List[str] = [], cflags: List[str] = [], ldflags: List[str] = [],
|
||||||
library_paths: Dict[str, List[str]] = {}, ldpaths: Optional[List[str]] = None, ccver: Tuple[int, int] = (0, 0),
|
library_paths: Dict[str, List[str]] = {}, ldpaths: Optional[List[str]] = None, ccver: Tuple[int, int] = (0, 0),
|
||||||
vcs_rev: str = '', build_universal_binary: bool = False, binary_arch: BinaryArch = BinaryArch(),
|
vcs_rev: str = '', binary_arch: BinaryArch = BinaryArch(),
|
||||||
native_optimizations: bool = False,
|
native_optimizations: bool = False,
|
||||||
):
|
):
|
||||||
self.cc, self.cppflags, self.cflags, self.ldflags, self.library_paths = cc, cppflags, cflags, ldflags, library_paths
|
self.cc, self.cppflags, self.cflags, self.ldflags, self.library_paths = cc, cppflags, cflags, ldflags, library_paths
|
||||||
self.ldpaths = ldpaths or []
|
self.ldpaths = ldpaths or []
|
||||||
self.ccver = ccver
|
self.ccver = ccver
|
||||||
self.vcs_rev = vcs_rev
|
self.vcs_rev = vcs_rev
|
||||||
self.build_universal_binary = build_universal_binary
|
|
||||||
self.binary_arch = binary_arch
|
self.binary_arch = binary_arch
|
||||||
self.native_optimizations = native_optimizations
|
self.native_optimizations = native_optimizations
|
||||||
|
|
||||||
@@ -91,7 +89,6 @@ class Env:
|
|||||||
ans.wayland_scanner_code = self.wayland_scanner_code
|
ans.wayland_scanner_code = self.wayland_scanner_code
|
||||||
ans.wayland_protocols = self.wayland_protocols
|
ans.wayland_protocols = self.wayland_protocols
|
||||||
ans.vcs_rev = self.vcs_rev
|
ans.vcs_rev = self.vcs_rev
|
||||||
ans.build_universal_binary = self.build_universal_binary
|
|
||||||
ans.binary_arch = self.binary_arch
|
ans.binary_arch = self.binary_arch
|
||||||
ans.native_optimizations = self.native_optimizations
|
ans.native_optimizations = self.native_optimizations
|
||||||
return ans
|
return ans
|
||||||
|
|||||||
@@ -12,11 +12,12 @@
|
|||||||
#include "charsets.h"
|
#include "charsets.h"
|
||||||
|
|
||||||
// Boilerplate {{{
|
// Boilerplate {{{
|
||||||
#ifdef __clang__
|
#if defined(__clang__) && __clang_major__ > 12
|
||||||
_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wbitwise-instead-of-logical\"")
|
_Pragma("clang diagnostic push")
|
||||||
|
_Pragma("clang diagnostic ignored \"-Wbitwise-instead-of-logical\"")
|
||||||
#endif
|
#endif
|
||||||
#include <simde/x86/avx2.h>
|
#include <simde/x86/avx2.h>
|
||||||
#ifdef __clang__
|
#if defined(__clang__) && __clang_major__ > 12
|
||||||
_Pragma("clang diagnostic pop")
|
_Pragma("clang diagnostic pop")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
173
setup.py
173
setup.py
@@ -54,6 +54,8 @@ is_arm = platform.processor() == 'arm' or platform.machine() in ('arm64', 'aarch
|
|||||||
Env = glfw.Env
|
Env = glfw.Env
|
||||||
env = Env()
|
env = Env()
|
||||||
PKGCONFIG = os.environ.get('PKGCONFIG_EXE', 'pkg-config')
|
PKGCONFIG = os.environ.get('PKGCONFIG_EXE', 'pkg-config')
|
||||||
|
link_targets: List[str] = []
|
||||||
|
macos_universal_arches = ('arm64', 'x86_64') if is_arm else ('x86_64', 'arm64')
|
||||||
|
|
||||||
|
|
||||||
def LinkKey(output: str) -> CompileKey:
|
def LinkKey(output: str) -> CompileKey:
|
||||||
@@ -119,7 +121,7 @@ class CompilationDatabase:
|
|||||||
|
|
||||||
def __enter__(self) -> 'CompilationDatabase':
|
def __enter__(self) -> 'CompilationDatabase':
|
||||||
self.all_keys: Set[CompileKey] = set()
|
self.all_keys: Set[CompileKey] = set()
|
||||||
self.dbpath = os.path.abspath(os.path.join('build', 'compile_commands.json'))
|
self.dbpath = os.path.abspath(os.path.join(build_dir, 'compile_commands.json'))
|
||||||
self.linkdbpath = os.path.join(os.path.dirname(self.dbpath), 'link_commands.json')
|
self.linkdbpath = os.path.join(os.path.dirname(self.dbpath), 'link_commands.json')
|
||||||
try:
|
try:
|
||||||
with open(self.dbpath) as f:
|
with open(self.dbpath) as f:
|
||||||
@@ -166,7 +168,6 @@ class Options:
|
|||||||
python_compiler_flags: str = ''
|
python_compiler_flags: str = ''
|
||||||
python_linker_flags: str = ''
|
python_linker_flags: str = ''
|
||||||
incremental: bool = True
|
incremental: bool = True
|
||||||
build_universal_binary: bool = False
|
|
||||||
build_dsym: bool = False
|
build_dsym: bool = False
|
||||||
ignore_compiler_warnings: bool = False
|
ignore_compiler_warnings: bool = False
|
||||||
profile: bool = False
|
profile: bool = False
|
||||||
@@ -181,6 +182,7 @@ class Options:
|
|||||||
startup_notification_library: Optional[str] = os.getenv('KITTY_STARTUP_NOTIFICATION_LIBRARY')
|
startup_notification_library: Optional[str] = os.getenv('KITTY_STARTUP_NOTIFICATION_LIBRARY')
|
||||||
canberra_library: Optional[str] = os.getenv('KITTY_CANBERRA_LIBRARY')
|
canberra_library: Optional[str] = os.getenv('KITTY_CANBERRA_LIBRARY')
|
||||||
fontconfig_library: Optional[str] = os.getenv('KITTY_FONTCONFIG_LIBRARY')
|
fontconfig_library: Optional[str] = os.getenv('KITTY_FONTCONFIG_LIBRARY')
|
||||||
|
building_arch: str = ''
|
||||||
|
|
||||||
# Extras
|
# Extras
|
||||||
compilation_database: CompilationDatabase = CompilationDatabase()
|
compilation_database: CompilationDatabase = CompilationDatabase()
|
||||||
@@ -417,7 +419,7 @@ def first_successful_compile(cc: List[str], *cflags: str, src: str = '', source_
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
def set_arches(flags: List[str], arches: Iterable[str] = ('x86_64', 'arm64')) -> None:
|
def set_arches(flags: List[str], *arches: str) -> None:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
idx = flags.index('-arch')
|
idx = flags.index('-arch')
|
||||||
@@ -452,13 +454,12 @@ def init_env(
|
|||||||
extra_logging: Iterable[str] = (),
|
extra_logging: Iterable[str] = (),
|
||||||
extra_include_dirs: Iterable[str] = (),
|
extra_include_dirs: Iterable[str] = (),
|
||||||
ignore_compiler_warnings: bool = False,
|
ignore_compiler_warnings: bool = False,
|
||||||
build_universal_binary: bool = False,
|
building_arch: str = '',
|
||||||
extra_library_dirs: Iterable[str] = (),
|
extra_library_dirs: Iterable[str] = (),
|
||||||
verbose: bool = True,
|
verbose: bool = True,
|
||||||
vcs_rev: str = '',
|
vcs_rev: str = '',
|
||||||
) -> Env:
|
) -> Env:
|
||||||
native_optimizations = native_optimizations and not sanitize
|
native_optimizations = native_optimizations and not sanitize
|
||||||
build_universal_binary = build_universal_binary and is_macos
|
|
||||||
cc, ccver = cc_version()
|
cc, ccver = cc_version()
|
||||||
if verbose:
|
if verbose:
|
||||||
print('CC:', cc, ccver)
|
print('CC:', cc, ccver)
|
||||||
@@ -486,27 +487,15 @@ def init_env(
|
|||||||
werror = '' if ignore_compiler_warnings else '-pedantic-errors -Werror'
|
werror = '' if ignore_compiler_warnings else '-pedantic-errors -Werror'
|
||||||
std = '' if is_openbsd else '-std=c11'
|
std = '' if is_openbsd else '-std=c11'
|
||||||
sanitize_flag = ' '.join(sanitize_args)
|
sanitize_flag = ' '.join(sanitize_args)
|
||||||
# Using -mbranch-protection=standard causes crashes on Linux ARM, reported
|
|
||||||
# in https://github.com/kovidgoyal/kitty/issues/6845#issuecomment-1835886938
|
|
||||||
arm_control_flow_protection = '-mbranch-protection=standard' if is_macos else ''
|
|
||||||
# Universal build fails with -fcf-protection clang is not smart enough to filter it out for the ARM part
|
|
||||||
intel_control_flow_protection = '-fcf-protection=full' if ccver >= (9, 0) else ''
|
|
||||||
control_flow_protection = arm_control_flow_protection if is_arm else intel_control_flow_protection
|
|
||||||
env_cflags = shlex.split(os.environ.get('CFLAGS', ''))
|
env_cflags = shlex.split(os.environ.get('CFLAGS', ''))
|
||||||
env_cppflags = shlex.split(os.environ.get('CPPFLAGS', ''))
|
env_cppflags = shlex.split(os.environ.get('CPPFLAGS', ''))
|
||||||
env_ldflags = shlex.split(os.environ.get('LDFLAGS', ''))
|
env_ldflags = shlex.split(os.environ.get('LDFLAGS', ''))
|
||||||
if control_flow_protection and not test_compile(cc, control_flow_protection, *env_cppflags, *env_cflags, ldflags=env_ldflags):
|
|
||||||
control_flow_protection = ''
|
|
||||||
march = ''
|
|
||||||
if native_optimizations and not build_universal_binary and not (is_macos and is_arm):
|
|
||||||
# see https://github.com/kovidgoyal/kitty/issues/3126
|
|
||||||
# -march=native is not supported when targeting Apple Silicon
|
|
||||||
march = '-march=native -mtune=native'
|
|
||||||
cflags_ = os.environ.get(
|
cflags_ = os.environ.get(
|
||||||
'OVERRIDE_CFLAGS', (
|
'OVERRIDE_CFLAGS', (
|
||||||
f'-Wextra {float_conversion} -Wno-missing-field-initializers -Wall -Wstrict-prototypes {std}'
|
f'-Wextra {float_conversion} -Wno-missing-field-initializers -Wall -Wstrict-prototypes {std}'
|
||||||
f' {werror} {optimize} {sanitize_flag} -fwrapv {stack_protector} {missing_braces}'
|
f' {werror} {optimize} {sanitize_flag} -fwrapv {stack_protector} {missing_braces}'
|
||||||
f' -pipe {march} -fvisibility=hidden {fortify_source} {control_flow_protection} -fno-plt'
|
f' -pipe -fvisibility=hidden {fortify_source} -fno-plt'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
cflags = shlex.split(cflags_) + shlex.split(
|
cflags = shlex.split(cflags_) + shlex.split(
|
||||||
@@ -558,12 +547,30 @@ def init_env(
|
|||||||
cflags.insert(0, f'-I{os.environ["DEVELOP_ROOT"]}/include')
|
cflags.insert(0, f'-I{os.environ["DEVELOP_ROOT"]}/include')
|
||||||
ldpaths.insert(0, f'-L{os.environ["DEVELOP_ROOT"]}/lib')
|
ldpaths.insert(0, f'-L{os.environ["DEVELOP_ROOT"]}/lib')
|
||||||
|
|
||||||
|
if building_arch:
|
||||||
|
set_arches(cflags, building_arch)
|
||||||
|
set_arches(ldflags, building_arch)
|
||||||
ba = test_compile(cc, *(cppflags + cflags), ldflags=ldflags, get_output_arch=True)
|
ba = test_compile(cc, *(cppflags + cflags), ldflags=ldflags, get_output_arch=True)
|
||||||
assert isinstance(ba, BinaryArch)
|
assert isinstance(ba, BinaryArch)
|
||||||
|
|
||||||
|
control_flow_protection = ''
|
||||||
|
if ba.isa == ISA.AMD64:
|
||||||
|
control_flow_protection = '-fcf-protection=full' if ccver >= (9, 0) else ''
|
||||||
|
elif ba.isa == ISA.ARM64:
|
||||||
|
# Using -mbranch-protection=standard causes crashes on Linux ARM, reported
|
||||||
|
# in https://github.com/kovidgoyal/kitty/issues/6845#issuecomment-1835886938
|
||||||
|
if is_macos:
|
||||||
|
control_flow_protection = '-mbranch-protection=standard'
|
||||||
|
|
||||||
|
if control_flow_protection:
|
||||||
|
cflags.append(control_flow_protection)
|
||||||
|
|
||||||
|
if native_optimizations and ba.isa in (ISA.AMD64, ISA.X86):
|
||||||
|
cflags.extend('-march=native -mtune=native'.split())
|
||||||
|
|
||||||
return Env(
|
return Env(
|
||||||
cc, cppflags, cflags, ldflags, library_paths, binary_arch=ba, native_optimizations=native_optimizations,
|
cc, cppflags, cflags, ldflags, library_paths, binary_arch=ba, native_optimizations=native_optimizations,
|
||||||
ccver=ccver, ldpaths=ldpaths, vcs_rev=vcs_rev, build_universal_binary=build_universal_binary
|
ccver=ccver, ldpaths=ldpaths, vcs_rev=vcs_rev,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -616,7 +623,6 @@ def kitty_env(args: Options) -> Env:
|
|||||||
if '-lz' not in ans.ldpaths:
|
if '-lz' not in ans.ldpaths:
|
||||||
ans.ldpaths.append('-lz')
|
ans.ldpaths.append('-lz')
|
||||||
|
|
||||||
os.makedirs(build_dir, exist_ok=True)
|
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
@@ -705,14 +711,12 @@ def get_source_specific_cflags(env: Env, src: str) -> List[str]:
|
|||||||
# SIMD specific flags, ignored for native optimizations as they give slightly better performance
|
# SIMD specific flags, ignored for native optimizations as they give slightly better performance
|
||||||
if src == 'kitty/simd-string-128.c':
|
if src == 'kitty/simd-string-128.c':
|
||||||
if env.binary_arch.isa in (ISA.AMD64, ISA.X86):
|
if env.binary_arch.isa in (ISA.AMD64, ISA.X86):
|
||||||
if not env.native_optimizations:
|
ans.append('-msse4.2')
|
||||||
ans.append('-msse4.2')
|
|
||||||
elif src == 'kitty/simd-string-256.c':
|
elif src == 'kitty/simd-string-256.c':
|
||||||
if env.binary_arch.isa in (ISA.AMD64, ISA.X86):
|
if env.binary_arch.isa in (ISA.AMD64, ISA.X86):
|
||||||
if not env.native_optimizations:
|
ans.append('-mavx2')
|
||||||
ans.append('-mavx2')
|
|
||||||
elif src.startswith('3rdparty/base64/lib/arch/'):
|
elif src.startswith('3rdparty/base64/lib/arch/'):
|
||||||
if not env.native_optimizations:
|
if env.binary_arch.isa in (ISA.AMD64, ISA.X86):
|
||||||
q = src.split(os.path.sep)
|
q = src.split(os.path.sep)
|
||||||
if 'sse3' in q:
|
if 'sse3' in q:
|
||||||
ans.append('-msse3')
|
ans.append('-msse3')
|
||||||
@@ -842,6 +846,7 @@ def compile_c_extension(
|
|||||||
compilation_database.add_command(desc, cmd, partial(newer, dest, *dependecies_for(src, dest, headers)), key=key, keyfile=src)
|
compilation_database.add_command(desc, cmd, partial(newer, dest, *dependecies_for(src, dest, headers)), key=key, keyfile=src)
|
||||||
dest = os.path.join(build_dir, f'{module}.so')
|
dest = os.path.join(build_dir, f'{module}.so')
|
||||||
real_dest = f'{module}.so'
|
real_dest = f'{module}.so'
|
||||||
|
link_targets.append(os.path.abspath(real_dest))
|
||||||
os.makedirs(os.path.dirname(dest), exist_ok=True)
|
os.makedirs(os.path.dirname(dest), exist_ok=True)
|
||||||
desc = f'Linking {emphasis(desc_prefix + module)} ...'
|
desc = f'Linking {emphasis(desc_prefix + module)} ...'
|
||||||
# Old versions of clang don't like -pthread being passed to the linker
|
# Old versions of clang don't like -pthread being passed to the linker
|
||||||
@@ -957,7 +962,7 @@ def init_env_from_args(args: Options, native_optimizations: bool = False) -> Non
|
|||||||
args.debug, args.sanitize, native_optimizations, args.link_time_optimization, args.profile,
|
args.debug, args.sanitize, native_optimizations, args.link_time_optimization, args.profile,
|
||||||
args.egl_library, args.startup_notification_library, args.canberra_library, args.fontconfig_library,
|
args.egl_library, args.startup_notification_library, args.canberra_library, args.fontconfig_library,
|
||||||
args.extra_logging, args.extra_include_dirs, args.ignore_compiler_warnings,
|
args.extra_logging, args.extra_include_dirs, args.ignore_compiler_warnings,
|
||||||
args.build_universal_binary, args.extra_library_dirs, verbose=args.verbose > 0, vcs_rev=args.vcs_rev,
|
args.building_arch, args.extra_library_dirs, verbose=args.verbose > 0, vcs_rev=args.vcs_rev,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1119,31 +1124,31 @@ def build_static_kittens(
|
|||||||
dest += f'-{for_platform[0]}-{for_platform[1]}'
|
dest += f'-{for_platform[0]}-{for_platform[1]}'
|
||||||
src = os.path.abspath('tools/cmd')
|
src = os.path.abspath('tools/cmd')
|
||||||
|
|
||||||
def run_one(dest: str, **env: str) -> None:
|
def run_one(dest: str) -> None:
|
||||||
c = cmd + ['-o', dest, src]
|
c = cmd + ['-o', dest, src]
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
print(shlex.join(c))
|
print(shlex.join(c))
|
||||||
e = os.environ.copy()
|
e = os.environ.copy()
|
||||||
e.update(env)
|
|
||||||
# https://github.com/kovidgoyal/kitty/issues/6051#issuecomment-1441369828
|
# https://github.com/kovidgoyal/kitty/issues/6051#issuecomment-1441369828
|
||||||
e.pop('PWD', None)
|
e.pop('PWD', None)
|
||||||
if for_platform:
|
if for_platform:
|
||||||
e['CGO_ENABLED'] = '0'
|
e['CGO_ENABLED'] = '0'
|
||||||
e['GOOS'] = for_platform[0]
|
e['GOOS'] = for_platform[0]
|
||||||
e['GOARCH'] = for_platform[1]
|
e['GOARCH'] = for_platform[1]
|
||||||
|
elif args.building_arch:
|
||||||
|
e['GOARCH'] = {'x86_64': 'amd64', 'arm64': 'arm64'}[args.building_arch]
|
||||||
cp = subprocess.run(c, env=e)
|
cp = subprocess.run(c, env=e)
|
||||||
if cp.returncode != 0:
|
if cp.returncode != 0:
|
||||||
raise SystemExit(cp.returncode)
|
raise SystemExit(cp.returncode)
|
||||||
|
|
||||||
if args.build_universal_binary and not for_platform:
|
if is_macos and for_freeze and not for_platform:
|
||||||
outs = []
|
adests = []
|
||||||
for arch in ('amd64', 'arm64'):
|
for arch in macos_universal_arches:
|
||||||
d = dest + f'-{arch}'
|
args.building_arch = arch
|
||||||
run_one(d, GOOS='darwin', GOARCH=arch)
|
adest = dest + '-' + arch
|
||||||
outs.append(d)
|
adests.append(adest)
|
||||||
subprocess.check_call(['lipo', '-create', '-output', dest] + outs)
|
run_one(adest)
|
||||||
for x in outs:
|
lipo({dest: adests})
|
||||||
os.remove(x)
|
|
||||||
else:
|
else:
|
||||||
run_one(dest)
|
run_one(dest)
|
||||||
return dest
|
return dest
|
||||||
@@ -1208,9 +1213,9 @@ def build_launcher(args: Options, launcher_dir: str = '.', bundle_type: str = 's
|
|||||||
cflags += shlex.split(os.environ.get('CFLAGS', ''))
|
cflags += shlex.split(os.environ.get('CFLAGS', ''))
|
||||||
for path in args.extra_include_dirs:
|
for path in args.extra_include_dirs:
|
||||||
cflags.append(f'-I{path}')
|
cflags.append(f'-I{path}')
|
||||||
if args.build_universal_binary:
|
if args.building_arch:
|
||||||
set_arches(cflags)
|
set_arches(cflags, args.building_arch)
|
||||||
set_arches(ldflags)
|
set_arches(ldflags, args.building_arch)
|
||||||
if bundle_type == 'linux-freeze':
|
if bundle_type == 'linux-freeze':
|
||||||
# --disable-new-dtags prevents -rpath from generating RUNPATH instead of
|
# --disable-new-dtags prevents -rpath from generating RUNPATH instead of
|
||||||
# RPATH entries in the launcher. The ld dynamic linker does not search
|
# RPATH entries in the launcher. The ld dynamic linker does not search
|
||||||
@@ -1226,6 +1231,7 @@ def build_launcher(args: Options, launcher_dir: str = '.', bundle_type: str = 's
|
|||||||
key = CompileKey(src, os.path.basename(obj))
|
key = CompileKey(src, os.path.basename(obj))
|
||||||
args.compilation_database.add_command(f'Compiling {emphasis(src)} ...', cmd, partial(newer, obj, src), key=key, keyfile=src)
|
args.compilation_database.add_command(f'Compiling {emphasis(src)} ...', cmd, partial(newer, obj, src), key=key, keyfile=src)
|
||||||
dest = os.path.join(launcher_dir, 'kitty')
|
dest = os.path.join(launcher_dir, 'kitty')
|
||||||
|
link_targets.append(os.path.abspath(dest))
|
||||||
desc = f'Linking {emphasis("launcher")} ...'
|
desc = f'Linking {emphasis("launcher")} ...'
|
||||||
cmd = env.cc + ldflags + objects + libs + pylib + ['-o', dest]
|
cmd = env.cc + ldflags + objects + libs + pylib + ['-o', dest]
|
||||||
args.compilation_database.add_command(desc, cmd, partial(newer, dest, *objects), key=LinkKey('kitty'))
|
args.compilation_database.add_command(desc, cmd, partial(newer, dest, *objects), key=LinkKey('kitty'))
|
||||||
@@ -1612,7 +1618,7 @@ def create_macos_bundle_gunk(dest: str, for_freeze: bool, args: Options) -> str:
|
|||||||
return str(kitty_exe)
|
return str(kitty_exe)
|
||||||
|
|
||||||
|
|
||||||
def package(args: Options, bundle_type: str) -> None:
|
def package(args: Options, bundle_type: str, do_build_all: bool = True) -> None:
|
||||||
ddir = args.prefix
|
ddir = args.prefix
|
||||||
for_freeze = bundle_type.endswith('-freeze')
|
for_freeze = bundle_type.endswith('-freeze')
|
||||||
if bundle_type == 'linux-freeze':
|
if bundle_type == 'linux-freeze':
|
||||||
@@ -1623,7 +1629,8 @@ def package(args: Options, bundle_type: str) -> None:
|
|||||||
launcher_dir = os.path.join(ddir, 'bin')
|
launcher_dir = os.path.join(ddir, 'bin')
|
||||||
safe_makedirs(launcher_dir)
|
safe_makedirs(launcher_dir)
|
||||||
if for_freeze: # freeze launcher is built separately
|
if for_freeze: # freeze launcher is built separately
|
||||||
args.compilation_database.build_all()
|
if do_build_all:
|
||||||
|
args.compilation_database.build_all()
|
||||||
else:
|
else:
|
||||||
build_launcher(args, launcher_dir, bundle_type)
|
build_launcher(args, launcher_dir, bundle_type)
|
||||||
os.makedirs(os.path.join(libdir, 'logo'))
|
os.makedirs(os.path.join(libdir, 'logo'))
|
||||||
@@ -1923,11 +1930,6 @@ def option_parser() -> argparse.ArgumentParser: # {{{
|
|||||||
default=Options.ignore_compiler_warnings, action='store_true',
|
default=Options.ignore_compiler_warnings, action='store_true',
|
||||||
help='Ignore any warnings from the compiler while building'
|
help='Ignore any warnings from the compiler while building'
|
||||||
)
|
)
|
||||||
p.add_argument(
|
|
||||||
'--build-universal-binary',
|
|
||||||
default=Options.build_universal_binary, action='store_true',
|
|
||||||
help='Build a universal binary (ARM + Intel on macOS, ignored on other platforms)'
|
|
||||||
)
|
|
||||||
p.add_argument(
|
p.add_argument(
|
||||||
'--build-dSYM', dest='build_dsym',
|
'--build-dSYM', dest='build_dsym',
|
||||||
default=Options.build_dsym, action='store_true',
|
default=Options.build_dsym, action='store_true',
|
||||||
@@ -1978,16 +1980,49 @@ def build_dep() -> None:
|
|||||||
run_tool(cmd)
|
run_tool(cmd)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def lipo(target_map: Dict[str, List[str]]) -> None:
|
||||||
global verbose
|
print(f'Using lipo to generate {len(target_map)} universal binaries...')
|
||||||
if len(sys.argv) > 1 and sys.argv[1] == 'build-dep':
|
for dest, inputs in target_map.items():
|
||||||
return build_dep()
|
cmd = ['lipo', '-create', '-output', dest] + inputs
|
||||||
args = option_parser().parse_args(namespace=Options())
|
subprocess.check_call(cmd)
|
||||||
if not is_macos:
|
for x in inputs:
|
||||||
args.build_universal_binary = False
|
os.remove(x)
|
||||||
verbose = args.verbose > 0
|
|
||||||
args.prefix = os.path.abspath(args.prefix)
|
|
||||||
os.chdir(src_base)
|
def macos_freeze(args: Options, launcher_dir: str, only_frozen_launcher: bool = False) -> None:
|
||||||
|
global build_dir
|
||||||
|
# Need to build a universal binary in two stages
|
||||||
|
orig_build_dir = build_dir
|
||||||
|
link_target_map: Dict[str, List[str]] = {}
|
||||||
|
bundle_type = 'macos-freeze'
|
||||||
|
for arch in macos_universal_arches:
|
||||||
|
args.building_arch = arch
|
||||||
|
build_dir = os.path.join(orig_build_dir, arch)
|
||||||
|
os.makedirs(build_dir, exist_ok=True)
|
||||||
|
print('Building for arch:', arch, 'in', build_dir)
|
||||||
|
if arch is not macos_universal_arches[0]:
|
||||||
|
args.skip_code_generation = True # cant run kitty as its not a native arch
|
||||||
|
link_targets.clear()
|
||||||
|
with CompilationDatabase() as cdb:
|
||||||
|
args.compilation_database = cdb
|
||||||
|
init_env_from_args(args, native_optimizations=False)
|
||||||
|
if only_frozen_launcher:
|
||||||
|
build_launcher(args, launcher_dir=launcher_dir, bundle_type=bundle_type)
|
||||||
|
else:
|
||||||
|
build_launcher(args, launcher_dir=launcher_dir)
|
||||||
|
build(args, native_optimizations=False, call_init=False)
|
||||||
|
cdb.build_all()
|
||||||
|
for x in link_targets:
|
||||||
|
arch_specific = x + '-' + arch
|
||||||
|
link_target_map.setdefault(x, []).append(arch_specific)
|
||||||
|
os.rename(x, arch_specific)
|
||||||
|
build_dir = orig_build_dir
|
||||||
|
lipo(link_target_map)
|
||||||
|
if not only_frozen_launcher:
|
||||||
|
package(args, bundle_type=bundle_type, do_build_all=False)
|
||||||
|
|
||||||
|
|
||||||
|
def do_build(args: Options) -> None:
|
||||||
launcher_dir = 'kitty/launcher'
|
launcher_dir = 'kitty/launcher'
|
||||||
|
|
||||||
if args.action == 'test':
|
if args.action == 'test':
|
||||||
@@ -1996,6 +2031,11 @@ def main() -> None:
|
|||||||
if args.action == 'clean':
|
if args.action == 'clean':
|
||||||
clean(for_cross_compile=args.clean_for_cross_compile)
|
clean(for_cross_compile=args.clean_for_cross_compile)
|
||||||
return
|
return
|
||||||
|
if args.action == 'macos-freeze':
|
||||||
|
return macos_freeze(args, launcher_dir)
|
||||||
|
if args.action == 'build-frozen-launcher' and is_macos:
|
||||||
|
launcher_dir=os.path.join(args.prefix, 'bin')
|
||||||
|
return macos_freeze(args, launcher_dir, only_frozen_launcher=True)
|
||||||
|
|
||||||
with CompilationDatabase(args.incremental) as cdb:
|
with CompilationDatabase(args.incremental) as cdb:
|
||||||
args.compilation_database = cdb
|
args.compilation_database = cdb
|
||||||
@@ -2028,11 +2068,6 @@ def main() -> None:
|
|||||||
elif args.action == 'linux-freeze':
|
elif args.action == 'linux-freeze':
|
||||||
build(args, native_optimizations=False)
|
build(args, native_optimizations=False)
|
||||||
package(args, bundle_type='linux-freeze')
|
package(args, bundle_type='linux-freeze')
|
||||||
elif args.action == 'macos-freeze':
|
|
||||||
init_env_from_args(args, native_optimizations=False)
|
|
||||||
build_launcher(args, launcher_dir=launcher_dir)
|
|
||||||
build(args, native_optimizations=False, call_init=False)
|
|
||||||
package(args, bundle_type='macos-freeze')
|
|
||||||
elif args.action == 'kitty.app':
|
elif args.action == 'kitty.app':
|
||||||
args.prefix = 'kitty.app'
|
args.prefix = 'kitty.app'
|
||||||
if os.path.exists(args.prefix):
|
if os.path.exists(args.prefix):
|
||||||
@@ -2048,5 +2083,17 @@ def main() -> None:
|
|||||||
build_static_binaries(args, launcher_dir)
|
build_static_binaries(args, launcher_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
global verbose, build_dir
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1] == 'build-dep':
|
||||||
|
return build_dep()
|
||||||
|
args = option_parser().parse_args(namespace=Options())
|
||||||
|
verbose = args.verbose > 0
|
||||||
|
args.prefix = os.path.abspath(args.prefix)
|
||||||
|
os.chdir(src_base)
|
||||||
|
os.makedirs(build_dir, exist_ok=True)
|
||||||
|
do_build(args)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user