# This file contains the default configuration to compile for Android # platforms. It contains sensitive enviroment configuration that # shouldn't be modified unless you know what you are doing. # PLEASE, DO NOT EDIT THIS FILE import os from cerbero.enums import Architecture, DistroVersion, Platform from cerbero.errors import FatalError import cerbero.utils.messages as m # So, paths: # # With NDK r16, 'Unified Headers' is the only way to build against the NDK and # the API-level specific headers are not shipped anymore. A migration guide is # available from https://android.googlesource.com/platform/ndk/+/ndk-release-r16/docs/UnifiedHeaders.md # and we follow that when setting up these paths. One thing to note however # is that the 'Unified Headers' ship headers that contain API-level guarded # functions so we may need to replace or override headers. One such example # is iconv.h which at the time of writing, has a header in the NDK # with no usable functions. This simply means that we have to construct # cflags/cppflags/ldflags/etc to look in our directories before looking into # the sysroot. # # toolchain_prefix: NDK location # toolchain_path: location of the compiler binaries # sysroot: location of the API-level libraries (no headers) # isysroot: location of the headers variants.override(['nopython', 'notestspackage', 'rust']) # We don't want anything from linux system to be used on android :) allow_system_libs=False if not toolchain_prefix: toolchain_prefix = os.path.join(home_dir, 'android-ndk-25') toolchain_path = None toolchain_version = None v = DistroVersion.get_android_api_version(target_distro_version) tools_prefix = None tools_dir = None host = None llvm_triple = None if target_arch == Architecture.ARMv7: tools_prefix = 'arm-linux-androideabi' tools_dir = tools_prefix arch_include = tools_prefix host = 'arm-linux-androideabi' llvm_triple = f'armv7a-linux-androideabi{v}' _android_arch = 'arm' _cerbero_arch = 'armv7' _cxx_arch = 'armeabi-v7a' elif target_arch == Architecture.ARM64: tools_prefix = 'aarch64-linux-android' tools_dir = tools_prefix arch_include = tools_prefix host = 'aarch64-linux-android' llvm_triple = f'aarch64-linux-android{v}' _android_arch = 'arm64' _cerbero_arch = 'arm64' _cxx_arch = 'arm64-v8a' elif target_arch == Architecture.X86: tools_prefix = 'i686-linux-android' tools_dir = 'x86' arch_include = tools_prefix host = 'i686-linux-android' llvm_triple = f'i686-linux-android{v}' _android_arch = 'x86' _cerbero_arch = 'x86' _cxx_arch = 'x86' elif target_arch == Architecture.X86_64: tools_prefix = 'x86_64-linux-android' tools_dir = 'x86_64' host = 'x86_64-linux-android' llvm_triple = f'x86_64-linux-android{v}' _android_arch = 'x86_64' _cerbero_arch = 'x86_64' _cxx_arch = 'x86_64' elif target_arch == Architecture.UNIVERSAL: tools_prefix = '' host = '' llvm_triple = '' _android_arch = 'x86_64' _cerbero_arch = 'x86_64' _cxx_arch = 'x86_64' else: raise FatalError(f'Arch {target_arch} not supported') if platform == Platform.LINUX: tc_arch = 'linux-x86_64' else: raise FatalError(f'Platform {platform} is not supported') llvm_toolchain_path = f'{toolchain_prefix}/toolchains/llvm/prebuilt/{tc_arch}/bin' spirv_toolchain_path = f'{toolchain_prefix}/shader-tools/{tc_arch}' isysroot = f'{toolchain_prefix}/toolchains/llvm/prebuilt/linux-x86_64/sysroot' sysroot = f'{toolchain_prefix}/toolchains/llvm/prebuilt/linux-x86_64/sysroot' # Default compiler flags env['CFLAGS'] = '' env['CXXFLAGS'] = '' env['OBJCFLAGS'] = '' # Make sure user's env doesn't mess up with our build. env.pop('RUSTFLAGS', None) # Android NDK path env['ANDROID_NDK_HOME'] = toolchain_prefix env['ANDROID_NDK_TOOLCHAIN_BIN'] = llvm_toolchain_path # 'universal' is set by cerbero itself when building under a universal regime # so that we can construct different paths to include/lib directories to where # they actually are. Without this we don't know where the headers/libs will # actually end up if universal_archs: incl_dir = os.path.join(prefix, _cerbero_arch, 'include') lib_dir = os.path.join(prefix, _cerbero_arch, 'lib') else: incl_dir = os.path.join(prefix, 'include') lib_dir = os.path.join(prefix, 'lib') if target_arch != Architecture.UNIVERSAL and not os.path.exists(incl_dir): os.makedirs(incl_dir) if target_arch != Architecture.UNIVERSAL and not os.path.exists(lib_dir): os.makedirs(lib_dir) # Most of the compiler/linker specific flags are taken from # from android-ndk-r16/build/core/toolchains/$NAME-$VERSION/setup.mk ccache = use_ccache and 'ccache ' or '' defines = f'-DANDROID -DPIC ' # -fno-integrated-as cause some libraries (e.g. pixman) fail to build with # clang's assembler # -target is being duplicated here and in CC variable to workaround cmake # ignoring arguments in CC while other build systems may ignore CFLAGS for # certain checks. cflags = f'-target {llvm_triple} --sysroot {sysroot} -isysroot {isysroot} -isystem {incl_dir} -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fPIC -Wno-invalid-command-line-argument -Wno-unused-command-line-argument ' # http://b.android.com/220159 http://b.android.com/222239 if target_arch == Architecture.X86: if v < 24: cflags += ' -mstackrealign' ldflags = f'-fPIC -no-canonical-prefixes -Wl,-no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--gc-sections -Wl,--warn-shared-textrel ' if target_arch == Architecture.ARMv7: defines += ' -D__ARM_ARCH_7A__ ' cflags += ' -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16' ldflags += ' -Wl,--fix-cortex-a8 ' elif target_arch == Architecture.X86: cflags += ' -march=i686 ' ldflags += ' -L' + lib_dir if not target_arch in [Architecture.ARM64, Architecture.X86_64]: # nocopyreloc causes broken linking on arm64 ldflags += ' -Wl,-z,nocopyreloc ' # Initialize both the linker and the sysroot ldflags += f' -L{sysroot}/usr/lib/{host}/{v} -Wl,--sysroot={sysroot}' ldvariant = 'lld' ldflags += f' -fuse-ld={ldvariant} ' # Toolchain environment env['CPPFLAGS'] = defines env['CFLAGS'] += f'{cflags} {defines} -Wa,--noexecstack' env['CXXFLAGS'] = env['CFLAGS'] + ' -fno-rtti -fno-exceptions ' env['LDFLAGS'] = ldflags def llvm_cmd(command): return os.path.join(llvm_toolchain_path, command) # clang requires the full path otherwise it does stupid things and can't # find it's own binary env['CC']= ccache + llvm_cmd('clang') + f' -target {llvm_triple}' + f' --sysroot {sysroot}' env['CC_FOR_BUILD']= ccache + llvm_cmd('clang') env['CXX']= ccache + llvm_cmd('clang++') + f' -target {llvm_triple}' + f' --sysroot {sysroot}' # linker is needed for Autotools env['LD']= llvm_cmd(f'ld.lld') # Supply the linker separately to pick up the dependency on -lunwind # See https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html env['RUSTC_LINKER']= llvm_cmd(f'{llvm_triple}-clang') env['CPP']= llvm_cmd('clang') + ' -E' env['RANLIB']= llvm_cmd('llvm-ranlib') env['AR']= llvm_cmd('llvm-ar') env['AS']= llvm_cmd('llvm-as') env['NM']= llvm_cmd('llvm-nm') env['STRIP']= llvm_cmd('llvm-strip') env['OBJCOPY']= llvm_cmd('llvm-objcopy') env['PATH'] = f'{spirv_toolchain_path}:{env["PATH"]}' # For the libc.so dependency in i686-linux-android-as if target_arch == Architecture.X86: extra_lib_path = f'{sysroot}/usr/lib' elif target_arch == Architecture.X86_64: extra_lib_path = f'{sysroot}/usr/lib64' # For GLib meson_properties['growing_stack'] = 'true' # For cairo # FIXME : IF WE ADD BIG-ENDIAN PLATFORMS, FIX THIS ! env['ax_cv_c_float_words_bigendian'] = 'no' #No, really, it doesn't have uselocale env['ac_cv_func_uselocale'] = 'no' # fixup meson detecting wrong functions as __builtin's # https://github.com/mesonbuild/meson/issues/3672 if v < 18: meson_properties['has_function_log2'] = 'false' if v < 21: meson_properties['has_function_stpcpy'] = 'false' if v < 24: meson_properties['has_function_fseeko'] = 'false' meson_properties['has_function_ftello'] = 'false' meson_properties['has_function_fsetpos'] = 'false' meson_properties['has_function_fgetpos'] = 'false' meson_properties['has_function_fseeko64'] = 'false' meson_properties['has_function_ftello64'] = 'false' meson_properties['has_function_fsetpos64'] = 'false' meson_properties['has_function_fgetpos64'] = 'false'