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