# 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']) # 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-21') 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.DARWIN: tc_arch = 'darwin-x86_64' elif 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' gcc_toolchain_root = f'{toolchain_prefix}/toolchains/{tools_dir}-4.9/prebuilt/{tc_arch}' spirv_toolchain_path = f'{toolchain_prefix}/shader-tools/{tc_arch}' gcc_toolchain_path = os.path.join (gcc_toolchain_root, 'bin') isysroot = f'{toolchain_prefix}/sysroot' sysroot = f'{toolchain_prefix}/platforms/android-{v}/arch-{_android_arch}' # Default compiler flags env['CFLAGS'] = '' env['CXXFLAGS'] = '' env['OBJCFLAGS'] = '' # Android NDK path env['ANDROID_NDK_HOME'] = toolchain_prefix # '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 -D__ANDROID_API__={v} ' # -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} -gcc-toolchain {gcc_toolchain_root} -isysroot {isysroot} -isystem {incl_dir} -isystem {isysroot}/usr/include -isystem {isysroot}/usr/include/{tools_prefix} -fno-integrated-as -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'-gcc-toolchain {gcc_toolchain_root} -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 ' if target_arch in [Architecture.X86_64]: ldflags += f' -L{sysroot}/usr/lib64 ' else: ldflags += f' -L{sysroot}/usr/lib ' ldvariant = 'gold' ldflags += f' -fuse-ld={ldvariant} ' # this C++ stl setup is closely tied to the gnustl recipe which sets up the # necessary environment and files for this stl_prefix = os.path.join(toolchain_prefix, 'sources', 'cxx-stl', 'llvm-libc++') stl_libdir = os.path.join(toolchain_prefix, 'libs', _cxx_arch) stl_cxxlinkargs = ['-nostdlib++', '-L' + stl_libdir, '-lc++_shared'] stl_cxxflags = '-nostdlib++ -isystem ' + os.path.join (stl_prefix, 'include') + ' -isystem ' + os.path.join (stl_prefix, '..', 'llvm-libc++abi', 'include') # Toolchain environment env['CPPFLAGS'] = defines env['CFLAGS'] += f'{cflags} {defines} -Wa,--noexecstack' env['CXXFLAGS'] = stl_cxxflags + ' ' + env['CFLAGS'] + ' -fno-rtti -fno-exceptions ' env['LDFLAGS'] = ldflags + ' -nostdlib++' def cmd(command): return f'{tools_prefix}-{command}' # clang requires the full path otherwise it does stupid things and can't # find it's own binary env['CC']= ccache + os.path.join(llvm_toolchain_path, 'clang') + f' -target {llvm_triple}' + f' --sysroot {sysroot}' env['CXX']= ccache + os.path.join(llvm_toolchain_path, 'clang++') + f' -target {llvm_triple}' + f' --sysroot {sysroot}' env['LD']= cmd(f'ld.{ldvariant}') env['CPP']= os.path.join(llvm_toolchain_path, 'clang') + ' -E' env['RANLIB']= cmd('ranlib') env['AR']= cmd('ar') env['AS']= cmd('as') env['NM']= cmd('nm') env['STRIP']= cmd('strip') env['OBJCOPY']= cmd('objcopy') env['PATH'] = f'{toolchain_prefix}:{llvm_toolchain_path}:{gcc_toolchain_path}:{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' meson_properties['cpp_link_args'] = stl_cxxlinkargs