1*4882a593Smuzhiyun# following code modifies these definitions in the gcc config 2*4882a593Smuzhiyun# MULTILIB_OPTIONS 3*4882a593Smuzhiyun# MULTILIB_DIRNAMES 4*4882a593Smuzhiyun# MULTILIB_OSDIRNAMES 5*4882a593Smuzhiyun# GLIBC_DYNAMIC_LINKER32 6*4882a593Smuzhiyun# GLIBC_DYNAMIC_LINKER64 7*4882a593Smuzhiyun# GLIBC_DYNAMIC_LINKERX32 8*4882a593Smuzhiyun# GLIBC_DYNAMIC_LINKERN32 9*4882a593Smuzhiyun# For more information on use of these variables look at these files in the gcc source code 10*4882a593Smuzhiyun# gcc/config/i386/t-linux64 11*4882a593Smuzhiyun# gcc/config/mips/t-linux64 12*4882a593Smuzhiyun# gcc/config/rs6000/t-linux64 13*4882a593Smuzhiyun# gcc/config/i386/linux64.h 14*4882a593Smuzhiyun# gcc/config/mips/linux64.h 15*4882a593Smuzhiyun# gcc/config/rs6000/linux64.h 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunMULTILIB_OPTION_WHITELIST ??= "-m32 -m64 -mx32 -mabi=n32 -mabi=32 -mabi=64" 18*4882a593Smuzhiyun 19*4882a593Smuzhiyunpython gcc_multilib_setup() { 20*4882a593Smuzhiyun import re 21*4882a593Smuzhiyun import shutil 22*4882a593Smuzhiyun import glob 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun srcdir = d.getVar('S') 25*4882a593Smuzhiyun builddir = d.getVar('B') 26*4882a593Smuzhiyun src_conf_dir = '%s/gcc/config' % srcdir 27*4882a593Smuzhiyun build_conf_dir = '%s/gcc/config' % builddir 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun bb.utils.remove(build_conf_dir, True) 30*4882a593Smuzhiyun ml_globs = ('%s/*/t-linux64' % src_conf_dir, 31*4882a593Smuzhiyun '%s/*/linux64.h' % src_conf_dir, 32*4882a593Smuzhiyun '%s/aarch64/t-aarch64' % src_conf_dir, 33*4882a593Smuzhiyun '%s/aarch64/aarch64.h' % src_conf_dir, 34*4882a593Smuzhiyun '%s/aarch64/aarch64-linux.h' % src_conf_dir, 35*4882a593Smuzhiyun '%s/aarch64/aarch64-cores.def' % src_conf_dir, 36*4882a593Smuzhiyun '%s/arm/linux-eabi.h' % src_conf_dir, 37*4882a593Smuzhiyun '%s/*/linux.h' % src_conf_dir, 38*4882a593Smuzhiyun '%s/linux.h' % src_conf_dir) 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun # copy the target multilib config files to ${B} 41*4882a593Smuzhiyun for ml_glob in ml_globs: 42*4882a593Smuzhiyun for fn in glob.glob(ml_glob): 43*4882a593Smuzhiyun rel_path = os.path.relpath(fn, src_conf_dir) 44*4882a593Smuzhiyun parent_dir = os.path.dirname(rel_path) 45*4882a593Smuzhiyun bb.utils.mkdirhier('%s/%s' % (build_conf_dir, parent_dir)) 46*4882a593Smuzhiyun bb.utils.copyfile(fn, '%s/%s' % (build_conf_dir, rel_path)) 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun pn = d.getVar('PN') 49*4882a593Smuzhiyun multilibs = (d.getVar('MULTILIB_VARIANTS') or '').split() 50*4882a593Smuzhiyun if not multilibs and pn != "nativesdk-gcc": 51*4882a593Smuzhiyun return 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun mlprefix = d.getVar('MLPREFIX') 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun if ('%sgcc' % mlprefix) != pn and (not pn.startswith('gcc-cross-canadian')) and pn != "nativesdk-gcc": 56*4882a593Smuzhiyun return 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun def write_config(root, files, options, dirnames, osdirnames): 60*4882a593Smuzhiyun for ml_conf_file in files: 61*4882a593Smuzhiyun with open(root + '/' + ml_conf_file, 'r') as f: 62*4882a593Smuzhiyun filelines = f.readlines() 63*4882a593Smuzhiyun # recreate multilib configuration variables 64*4882a593Smuzhiyun substs = [ 65*4882a593Smuzhiyun (r'^(\s*(MULTILIB_OPTIONS\s*=).*)$', r'\2 %s' % '/'.join(options)), 66*4882a593Smuzhiyun (r'^(\s*MULTILIB_OPTIONS\s*\+=.*)$', ''), 67*4882a593Smuzhiyun (r'^(\s*(MULTILIB_DIRNAMES\s*=).*)$', r'\2 %s' % ' '.join(dirnames)), 68*4882a593Smuzhiyun (r'^(\s*MULTILIB_DIRNAMES\s*\+=.*)$', ''), 69*4882a593Smuzhiyun (r'^(\s*(MULTILIB_OSDIRNAMES\s*=).*)$', r'\2 %s' % ' '.join(osdirnames)), 70*4882a593Smuzhiyun (r'^(\s*MULTILIB_OSDIRNAMES\s*\+=.*)$', ''), 71*4882a593Smuzhiyun ] 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun for (i, line) in enumerate(filelines): 74*4882a593Smuzhiyun for subst in substs: 75*4882a593Smuzhiyun line = re.sub(subst[0], subst[1], line) 76*4882a593Smuzhiyun filelines[i] = line 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun with open(root + '/' + ml_conf_file, 'w') as f: 79*4882a593Smuzhiyun f.write(''.join(filelines)) 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun def write_headers(root, files, libdir32, libdir64, libdirx32, libdirn32): 82*4882a593Smuzhiyun def wrap_libdir(libdir): 83*4882a593Smuzhiyun if libdir.find('SYSTEMLIBS_DIR') != -1: 84*4882a593Smuzhiyun return '"%r"' 85*4882a593Smuzhiyun else: 86*4882a593Smuzhiyun return '"/%s/"' % libdir 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun for ml_conf_file in files: 89*4882a593Smuzhiyun fn = root + '/' + ml_conf_file 90*4882a593Smuzhiyun if not os.path.exists(fn): 91*4882a593Smuzhiyun continue 92*4882a593Smuzhiyun with open(fn, 'r') as f: 93*4882a593Smuzhiyun filelines = f.readlines() 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun # replace lines like 96*4882a593Smuzhiyun # #define GLIBC_DYNAMIC_LINKER32 SYSTEMLIBS_DIR "ld-linux.so.2" 97*4882a593Smuzhiyun # by 98*4882a593Smuzhiyun # #define GLIBC_DYNAMIC_LINKER32 "/lib/" "ld-linux.so.2" 99*4882a593Smuzhiyun # this is needed to put the correct dynamic loader path in the generated binaries 100*4882a593Smuzhiyun substs = [ 101*4882a593Smuzhiyun (r'^(#define\s*GLIBC_DYNAMIC_LINKER32\s*)(\S+)(\s*\".*\")$', 102*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir32) + r'\3'), 103*4882a593Smuzhiyun (r'^(#define\s*GLIBC_DYNAMIC_LINKER64\s*)(\S+)(\s*\"\S+\")$', 104*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir64) + r'\3'), 105*4882a593Smuzhiyun (r'^(#define\s*GLIBC_DYNAMIC_LINKER64\s*\"\S+\"\s*)(\S+)(\s*\"\S+\"\s*)(\S+)(\s*\".*\")$', 106*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir64) + r'\3' + wrap_libdir(libdir64) + r'\5'), 107*4882a593Smuzhiyun (r'^(#define\s*GLIBC_DYNAMIC_LINKER\b\s*)(\S+)(\s*\".*\")$', 108*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir32) + r'\3'), 109*4882a593Smuzhiyun (r'^(#define\s*GLIBC_DYNAMIC_LINKERX32\s*)(\S+)(\s*\".*\")$', 110*4882a593Smuzhiyun r'\1' + wrap_libdir(libdirx32) + r'\3'), 111*4882a593Smuzhiyun (r'^(#define\s*GLIBC_DYNAMIC_LINKERN32\s*)(\S+)(\s*\".*\")$', 112*4882a593Smuzhiyun r'\1' + wrap_libdir(libdirn32) + r'\3'), 113*4882a593Smuzhiyun (r'^(#define\s*UCLIBC_DYNAMIC_LINKER32\s*)(\S+)(\s*\".*\")$', 114*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir32) + r'\3'), 115*4882a593Smuzhiyun (r'^(#define\s*UCLIBC_DYNAMIC_LINKER64\s*)(\S+)(\s*\".*\")$', 116*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir64) + r'\3'), 117*4882a593Smuzhiyun (r'^(#define\s*UCLIBC_DYNAMIC_LINKERN32\s*)(\S+)(\s*\".*\")$', 118*4882a593Smuzhiyun r'\1' + wrap_libdir(libdirn32) + r'\3'), 119*4882a593Smuzhiyun (r'^(#define\s*UCLIBC_DYNAMIC_LINKERX32\s*)(\S+)(\s*\".*\")$', 120*4882a593Smuzhiyun r'\1' + wrap_libdir(libdirx32) + r'\3'), 121*4882a593Smuzhiyun (r'^(#define\s*UCLIBC_DYNAMIC_LINKER\b\s*)(\S+)(\s*\".*\")$', 122*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir32) + r'\3'), 123*4882a593Smuzhiyun (r'^(#define\s*MUSL_DYNAMIC_LINKER32\s*)(\S+)(\s*\".*\")$', 124*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir32) + r'\3'), 125*4882a593Smuzhiyun (r'^(#define\s*MUSL_DYNAMIC_LINKER64\s*)(\S+)(\s*\".*\")$', 126*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir64) + r'\3'), 127*4882a593Smuzhiyun (r'^(#define\s*MUSL_DYNAMIC_LINKERX32\s*)(\S+)(\s*\".*\")$', 128*4882a593Smuzhiyun r'\1' + wrap_libdir(libdirx32) + r'\3'), 129*4882a593Smuzhiyun (r'^(#define\s*MUSL_DYNAMIC_LINKER\b\s*)(\S+)(\s*\".*\")$', 130*4882a593Smuzhiyun r'\1' + wrap_libdir(libdir32) + r'\3'), 131*4882a593Smuzhiyun ] 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun for (i, line) in enumerate(filelines): 134*4882a593Smuzhiyun for subst in substs: 135*4882a593Smuzhiyun line = re.sub(subst[0], subst[1], line) 136*4882a593Smuzhiyun filelines[i] = line 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun with open(root + '/' + ml_conf_file, 'w') as f: 139*4882a593Smuzhiyun f.write(''.join(filelines)) 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun gcc_target_config_files = { 143*4882a593Smuzhiyun 'x86_64' : ['gcc/config/i386/t-linux64'], 144*4882a593Smuzhiyun 'i586' : ['gcc/config/i386/t-linux64'], 145*4882a593Smuzhiyun 'i686' : ['gcc/config/i386/t-linux64'], 146*4882a593Smuzhiyun 'mips' : ['gcc/config/mips/t-linux64'], 147*4882a593Smuzhiyun 'mips64' : ['gcc/config/mips/t-linux64'], 148*4882a593Smuzhiyun 'powerpc' : ['gcc/config/rs6000/t-linux64'], 149*4882a593Smuzhiyun 'powerpc64' : ['gcc/config/rs6000/t-linux64'], 150*4882a593Smuzhiyun 'aarch64' : ['gcc/config/aarch64/t-aarch64'], 151*4882a593Smuzhiyun 'arm' : ['gcc/config/aarch64/t-aarch64'], 152*4882a593Smuzhiyun } 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun gcc_header_config_files = { 155*4882a593Smuzhiyun 'x86_64' : ['gcc/config/linux.h', 'gcc/config/i386/linux.h', 'gcc/config/i386/linux64.h'], 156*4882a593Smuzhiyun 'i586' : ['gcc/config/linux.h', 'gcc/config/i386/linux.h', 'gcc/config/i386/linux64.h'], 157*4882a593Smuzhiyun 'i686' : ['gcc/config/linux.h', 'gcc/config/i386/linux.h', 'gcc/config/i386/linux64.h'], 158*4882a593Smuzhiyun 'mips' : ['gcc/config/linux.h', 'gcc/config/mips/linux.h', 'gcc/config/mips/linux64.h'], 159*4882a593Smuzhiyun 'mips64' : ['gcc/config/linux.h', 'gcc/config/mips/linux.h', 'gcc/config/mips/linux64.h'], 160*4882a593Smuzhiyun 'powerpc' : ['gcc/config/linux.h', 'gcc/config/rs6000/linux64.h'], 161*4882a593Smuzhiyun 'powerpc64' : ['gcc/config/linux.h', 'gcc/config/rs6000/linux64.h'], 162*4882a593Smuzhiyun 'aarch64' : ['gcc/config/linux.h', 'gcc/config/aarch64/aarch64-linux.h', 'gcc/config/arm/linux-eabi.h'], 163*4882a593Smuzhiyun 'arm' : ['gcc/config/linux.h', 'gcc/config/aarch64/aarch64-linux.h', 'gcc/config/arm/linux-eabi.h'], 164*4882a593Smuzhiyun } 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun libdir32 = 'SYSTEMLIBS_DIR' 167*4882a593Smuzhiyun libdir64 = 'SYSTEMLIBS_DIR' 168*4882a593Smuzhiyun libdirx32 = 'SYSTEMLIBS_DIR' 169*4882a593Smuzhiyun libdirn32 = 'SYSTEMLIBS_DIR' 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun target_arch = (d.getVar('TARGET_ARCH_MULTILIB_ORIGINAL') if mlprefix 173*4882a593Smuzhiyun else d.getVar('TARGET_ARCH')) 174*4882a593Smuzhiyun if pn == "nativesdk-gcc": 175*4882a593Smuzhiyun header_config_files = gcc_header_config_files[d.getVar("SDK_ARCH")] 176*4882a593Smuzhiyun write_headers(builddir, header_config_files, libdir32, libdir64, libdirx32, libdirn32) 177*4882a593Smuzhiyun return 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun if target_arch not in gcc_target_config_files: 180*4882a593Smuzhiyun bb.warn('gcc multilib setup is not supported for TARGET_ARCH=' + target_arch) 181*4882a593Smuzhiyun return 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun target_config_files = gcc_target_config_files[target_arch] 184*4882a593Smuzhiyun header_config_files = gcc_header_config_files[target_arch] 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun ml_list = ['DEFAULTTUNE_MULTILIB_ORIGINAL' if mlprefix else 'DEFAULTTUNE'] 187*4882a593Smuzhiyun mltunes = [('DEFAULTTUNE:virtclass-multilib-%s' % ml) for ml in multilibs] 188*4882a593Smuzhiyun if mlprefix: 189*4882a593Smuzhiyun mlindex = 0 190*4882a593Smuzhiyun for ml in multilibs: 191*4882a593Smuzhiyun if mlprefix == ml + '-': 192*4882a593Smuzhiyun break 193*4882a593Smuzhiyun mlindex += 1 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun ml_list.extend(mltunes[:mlindex] + ['DEFAULTTUNE'] + mltunes[(mlindex + 1):]) 196*4882a593Smuzhiyun else: 197*4882a593Smuzhiyun ml_list.extend(mltunes) 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun options = [] 200*4882a593Smuzhiyun dirnames = [] 201*4882a593Smuzhiyun osdirnames = [] 202*4882a593Smuzhiyun optsets = [] 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun for ml in ml_list: 205*4882a593Smuzhiyun tune = d.getVar(ml) 206*4882a593Smuzhiyun if not tune: 207*4882a593Smuzhiyun bb.warn("%s doesn't have a corresponding tune. Skipping..." % ml) 208*4882a593Smuzhiyun continue 209*4882a593Smuzhiyun tune_parameters = get_tune_parameters(tune, d) 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun tune_baselib = tune_parameters['baselib'] 212*4882a593Smuzhiyun if not tune_baselib: 213*4882a593Smuzhiyun bb.warn("Tune %s doesn't have a baselib set. Skipping..." % tune) 214*4882a593Smuzhiyun continue 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun if tune_baselib == 'lib64': 217*4882a593Smuzhiyun libdir64 = tune_baselib 218*4882a593Smuzhiyun elif tune_baselib == 'libx32': 219*4882a593Smuzhiyun libdirx32 = tune_baselib 220*4882a593Smuzhiyun elif tune_baselib == 'lib32': 221*4882a593Smuzhiyun libdirn32 = tune_baselib 222*4882a593Smuzhiyun elif tune_baselib == 'lib': 223*4882a593Smuzhiyun libdir32 = tune_baselib 224*4882a593Smuzhiyun else: 225*4882a593Smuzhiyun bb.error('Unknown libdir (%s) of the tune : %s' % (tune_baselib, tune)) 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun # take out '-' mcpu='s and march='s from parameters 228*4882a593Smuzhiyun opts = [] 229*4882a593Smuzhiyun whitelist = (d.getVar("MULTILIB_OPTION_WHITELIST") or "").split() 230*4882a593Smuzhiyun for i in d.expand(tune_parameters['ccargs']).split(): 231*4882a593Smuzhiyun if i in whitelist: 232*4882a593Smuzhiyun # Need to strip '-' from option 233*4882a593Smuzhiyun opts.append(i[1:]) 234*4882a593Smuzhiyun options.append(" ".join(opts)) 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun if tune_baselib == 'lib': 237*4882a593Smuzhiyun dirnames.append('32') # /lib => 32bit lib 238*4882a593Smuzhiyun else: 239*4882a593Smuzhiyun dirnames.append(tune_baselib.replace('lib', '')) 240*4882a593Smuzhiyun osdirnames.append('../' + tune_baselib) 241*4882a593Smuzhiyun 242*4882a593Smuzhiyun write_config(builddir, target_config_files, options, dirnames, osdirnames) 243*4882a593Smuzhiyun write_headers(builddir, header_config_files, libdir32, libdir64, libdirx32, libdirn32) 244*4882a593Smuzhiyun} 245*4882a593Smuzhiyun 246*4882a593Smuzhiyungcc_multilib_setup[cleandirs] = "${B}/gcc/config" 247*4882a593Smuzhiyungcc_multilib_setup[vardepsexclude] = "SDK_ARCH" 248*4882a593Smuzhiyun 249*4882a593SmuzhiyunEXTRACONFFUNCS += "gcc_multilib_setup" 250