1# GN host architecture helpers. 2# 3# BUILD_ARCH's value corresponds to what uname returns as the machine name. 4# The mapping in gn_host_arch_name() tries to match several possible values 5# returned by the Linux kernel in uname(2) into the corresponding values GN 6# understands. 7def gn_host_arch_name(d): 8 """Returns a GN architecture name corresponding to the build host's machine 9 architecture.""" 10 import re 11 arch_translations = { 12 r'aarch64.*': 'arm64', 13 r'arm.*': 'arm', 14 r'i[3456]86$': 'x86', 15 r'x86_64$': 'x64', 16 } 17 build_arch = d.getVar("BUILD_ARCH") 18 for arch_regexp, gn_arch_name in arch_translations.items(): 19 if re.match(arch_regexp, build_arch): 20 return gn_arch_name 21 bb.fatal('Unsuported BUILD_ARCH value: "%s"' % build_arch) 22 23# GN target architecture helpers. 24# 25# Determining the target architecture is more difficult, as there are many 26# different values we can use on the Yocto side (e.g. TUNE_ARCH, TARGET_ARCH, 27# MACHINEOVERRIDES etc). What we do is define the mapping with regular, 28# non-Python variables with overrides that are generic enough (i.e. "x86" 29# instead of "i586") and then use gn_target_arch_name() to return the right 30# value with some validation. 31GN_TARGET_ARCH_NAME:aarch64 = "arm64" 32GN_TARGET_ARCH_NAME:arm = "arm" 33GN_TARGET_ARCH_NAME:x86 = "x86" 34GN_TARGET_ARCH_NAME:x86-64 = "x64" 35 36def clang_install_path(d): 37 """Return clang compiler install path.""" 38 return d.getVar("STAGING_BINDIR_NATIVE") 39 40def gn_target_arch_name(d): 41 """Returns a GN architecture name corresponding to the target machine's 42 architecture.""" 43 name = d.getVar("GN_TARGET_ARCH_NAME") 44 if name is None: 45 bb.fatal('Unsupported target architecture. A valid override for the ' 46 'GN_TARGET_ARCH_NAME variable could not be found.') 47 return name 48 49def write_toolchain_file(d, file_path): 50 """Creates a complete GN toolchain file in |file_path|.""" 51 import string 52 # Even though we always use clang, the "clang_toolchain" GN template is too 53 # restrictive in the way it sets variables such as |cxx|. Since it is just 54 # a wrapper on top of the "gcc_toolchain" template, we keep using the 55 # latter directly to accommodate our cross-compilation needs. 56 toolchain_tmpl = string.Template( 57 'gcc_toolchain("${toolchain_name}") {\n' 58 ' cc = "${cc}"\n' 59 ' cxx = "${cxx}"\n' 60 ' ar = "${ar}"\n' 61 ' ld = cxx # GN expects a compiler, not a linker.\n' 62 ' nm = "${nm}"\n' 63 ' readelf = "${readelf}"\n' 64 ' extra_cflags = "${extra_cflags}"\n' 65 ' extra_cppflags = "${extra_cppflags}"\n' 66 ' extra_cxxflags = "${extra_cxxflags}"\n' 67 ' extra_ldflags = "${extra_ldflags}"\n' 68 ' toolchain_args = {\n' 69 ' current_cpu = "${current_cpu}"\n' 70 ' current_os = "linux"\n' 71 ' is_clang = true\n' 72 ' }\n' 73 '}\n' 74 ) 75 76 native_toolchain = { 77 'toolchain_name': 'yocto_native', 78 'current_cpu': gn_host_arch_name(d), 79 'cc': d.expand('${BUILD_CC}'), 80 'cxx': d.expand('${BUILD_CXX}'), 81 'ar': d.expand('${BUILD_AR}'), 82 'nm': d.expand('${BUILD_NM}'), 83 'readelf': d.expand('${BUILD_PREFIX}readelf'), 84 'extra_cflags': d.expand('${BUILD_CFLAGS}'), 85 'extra_cppflags': d.expand('${BUILD_CPPFLAGS}'), 86 'extra_cxxflags': d.expand('${BUILD_CXXFLAGS}'), 87 'extra_ldflags': d.expand('${BUILD_LDFLAGS}'), 88 } 89 target_toolchain = { 90 'toolchain_name': 'yocto_target', 91 'current_cpu': gn_target_arch_name(d), 92 'cc': d.expand('${CC}'), 93 'cxx': d.expand('${CXX}'), 94 'ar': d.expand('${AR}'), 95 'nm': d.expand('${NM}'), 96 'readelf': d.expand('${READELF}'), 97 'extra_cflags': d.expand('${CFLAGS}'), 98 'extra_cppflags': d.expand('${CPPFLAGS}'), 99 'extra_cxxflags': d.expand('${CXXFLAGS}'), 100 'extra_ldflags': d.expand('${LDFLAGS}'), 101 } 102 103 with open(file_path, 'w') as toolchain_file: 104 toolchain_file.write( 105 '# This file has been generated automatically.\n' 106 '\n' 107 'import("//build/toolchain/gcc_toolchain.gni")\n' 108 '\n' 109 ) 110 toolchain_file.write(toolchain_tmpl.substitute(native_toolchain)) 111 toolchain_file.write(toolchain_tmpl.substitute(target_toolchain)) 112