summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-multilib-config.inc
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-multilib-config.inc')
-rw-r--r--meta/recipes-devtools/gcc/gcc-multilib-config.inc211
1 files changed, 211 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-multilib-config.inc b/meta/recipes-devtools/gcc/gcc-multilib-config.inc
new file mode 100644
index 0000000000..61340979ba
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-multilib-config.inc
@@ -0,0 +1,211 @@
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', True)
25 builddir = d.getVar('B', True)
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/linux.h' % src_conf_dir)
33
34 # copy the target multilib config files to ${B}
35 for ml_glob in ml_globs:
36 for fn in glob.glob(ml_glob):
37 rel_path = os.path.relpath(fn, src_conf_dir)
38 parent_dir = os.path.dirname(rel_path)
39 bb.utils.mkdirhier('%s/%s' % (build_conf_dir, parent_dir))
40 bb.utils.copyfile(fn, '%s/%s' % (build_conf_dir, rel_path))
41
42 multilibs = (d.getVar('MULTILIB_VARIANTS', True) or '').split()
43 if not multilibs:
44 return
45
46 mlprefix = d.getVar('MLPREFIX', True)
47 pn = d.getVar('PN', True)
48 if ('%sgcc' % mlprefix) != pn and (not pn.startswith('gcc-cross-canadian')):
49 return
50
51
52 def write_config(root, files, options, dirnames, osdirnames):
53 for ml_conf_file in files:
54 with open(root + '/' + ml_conf_file, 'r') as f:
55 filelines = f.readlines()
56 # recreate multilib configuration variables
57 substs = [
58 (r'^(\s*(MULTILIB_OPTIONS\s*=).*)$', r'\2 %s' % '/'.join(options)),
59 (r'^(\s*MULTILIB_OPTIONS\s*\+=.*)$', ''),
60 (r'^(\s*(MULTILIB_DIRNAMES\s*=).*)$', r'\2 %s' % ' '.join(dirnames)),
61 (r'^(\s*MULTILIB_DIRNAMES\s*\+=.*)$', ''),
62 (r'^(\s*(MULTILIB_OSDIRNAMES\s*=).*)$', r'\2 %s' % ' '.join(osdirnames)),
63 (r'^(\s*MULTILIB_OSDIRNAMES\s*\+=.*)$', ''),
64 ]
65
66 for (i, line) in enumerate(filelines):
67 for subst in substs:
68 line = re.sub(subst[0], subst[1], line)
69 filelines[i] = line
70
71 with open(root + '/' + ml_conf_file, 'w') as f:
72 f.write(''.join(filelines))
73
74 def write_headers(root, files, libdir32, libdir64, libdirx32, libdirn32):
75 def wrap_libdir(libdir):
76 if libdir.find('SYSTEMLIBS_DIR') != -1:
77 return libdir
78 else:
79 return '"/%s/"' % libdir
80
81 for ml_conf_file in files:
82 with open(root + '/' + ml_conf_file, 'r') as f:
83 filelines = f.readlines()
84
85 # replace lines like
86 # #define GLIBC_DYNAMIC_LINKER32 SYSTEMLIBS_DIR "ld-linux.so.2"
87 # by
88 # #define GLIBC_DYNAMIC_LINKER32 "/lib/" "ld-linux.so.2"
89 # this is needed to put the correct dynamic loader path in the generated binaries
90 substs = [
91 (r'^(#define\s*GLIBC_DYNAMIC_LINKER32\s*)(\S+)(\s*\".*\")$',
92 r'\1' + wrap_libdir(libdir32) + r'\3'),
93 (r'^(#define\s*GLIBC_DYNAMIC_LINKER64\s*)(\S+)(\s*\"\S+\")$',
94 r'\1' + wrap_libdir(libdir64) + r'\3'),
95 (r'^(#define\s*GLIBC_DYNAMIC_LINKER64\s*\"\S+\"\s*)(\S+)(\s*\"\S+\"\s*)(\S+)(\s*\".*\")$',
96 r'\1' + wrap_libdir(libdir64) + r'\3' + wrap_libdir(libdir64) + r'\5'),
97 (r'^(#define\s*GLIBC_DYNAMIC_LINKERX32\s*)(\S+)(\s*\".*\")$',
98 r'\1' + wrap_libdir(libdirx32) + r'\3'),
99 (r'^(#define\s*GLIBC_DYNAMIC_LINKERN32\s*)(\S+)(\s*\".*\")$',
100 r'\1' + wrap_libdir(libdirn32) + r'\3'),
101 (r'^(#define\s*UCLIBC_DYNAMIC_LINKER32\s*)(\S+)(\s*\".*\")$',
102 r'\1' + wrap_libdir(libdir32) + r'\3'),
103 (r'^(#define\s*UCLIBC_DYNAMIC_LINKER64\s*)(\S+)(\s*\".*\")$',
104 r'\1' + wrap_libdir(libdir64) + r'\3'),
105 (r'^(#define\s*UCLIBC_DYNAMIC_LINKERN32\s*)(\S+)(\s*\".*\")$',
106 r'\1' + wrap_libdir(libdirn32) + r'\3'),
107 (r'^(#define\s*UCLIBC_DYNAMIC_LINKER\b\s*)(\S+)(\s*\".*\")$',
108 r'\1' + wrap_libdir(libdir32) + r'\3'),
109 ]
110
111 for (i, line) in enumerate(filelines):
112 for subst in substs:
113 line = re.sub(subst[0], subst[1], line)
114 filelines[i] = line
115
116 with open(root + '/' + ml_conf_file, 'w') as f:
117 f.write(''.join(filelines))
118
119
120 gcc_target_config_files = {
121 'x86_64' : ['gcc/config/i386/t-linux64'],
122 'i586' : ['gcc/config/i386/t-linux64'],
123 'mips' : ['gcc/config/mips/t-linux64'],
124 'powerpc' : ['gcc/config/rs6000/t-linux64'],
125 'powerpc64' : ['gcc/config/rs6000/t-linux64'],
126 }
127
128 gcc_header_config_files = {
129 'x86_64' : ['gcc/config/i386/linux64.h'],
130 'i586' : ['gcc/config/i386/linux64.h'],
131 'mips' : ['gcc/config/mips/linux64.h'],
132 'powerpc' : ['gcc/config/rs6000/linux64.h'],
133 'powerpc64' : ['gcc/config/rs6000/linux64.h'],
134 }
135
136 target_arch = (d.getVar('TARGET_ARCH_MULTILIB_ORIGINAL', True) if mlprefix
137 else d.getVar('TARGET_ARCH', True))
138 if target_arch not in gcc_target_config_files:
139 bb.warn('gcc multilib setup is not supported for TARGET_ARCH=' + target_arch)
140 return
141
142 libdir32 = 'SYSTEMLIBS_DIR'
143 libdir64 = 'SYSTEMLIBS_DIR'
144 libdirx32 = 'SYSTEMLIBS_DIR'
145 libdirn32 = 'SYSTEMLIBS_DIR'
146
147 target_config_files = gcc_target_config_files[target_arch]
148 header_config_files = gcc_header_config_files[target_arch]
149
150 ml_list = ['DEFAULTTUNE_MULTILIB_ORIGINAL' if mlprefix else 'DEFAULTTUNE']
151 mltunes = [('DEFAULTTUNE_virtclass-multilib-%s' % ml) for ml in multilibs]
152 if mlprefix:
153 mlindex = 0
154 for ml in multilibs:
155 if mlprefix == ml + '-':
156 break
157 mlindex += 1
158
159 ml_list.extend(mltunes[:mlindex] + ['DEFAULTTUNE'] + mltunes[(mlindex + 1):])
160 else:
161 ml_list.extend(mltunes)
162
163 options = []
164 dirnames = []
165 osdirnames = []
166 optsets = []
167
168 for ml in ml_list:
169 tune = d.getVar(ml, True)
170 if not tune:
171 bb.warn("%s doesn't have a corresponding tune. Skipping..." % ml)
172 continue
173 tune_parameters = get_tune_parameters(tune, d)
174
175 tune_baselib = tune_parameters['baselib']
176 if not tune_baselib:
177 bb.warn("Tune %s doesn't have a baselib set. Skipping..." % tune)
178 continue
179
180 if tune_baselib == 'lib64':
181 libdir64 = tune_baselib
182 elif tune_baselib == 'libx32':
183 libdirx32 = tune_baselib
184 elif tune_baselib == 'lib32':
185 libdirn32 = tune_baselib
186 elif tune_baselib == 'lib':
187 libdir32 = tune_baselib
188 else:
189 bb.error('Unknown libdir (%s) of the tune : %s' % (tune_baselib, tune))
190
191 # take out '-' mcpu='s and march='s from parameters
192 opts = []
193 whitelist = (d.getVar("MULTILIB_OPTION_WHITELIST", True) or "").split()
194 for i in tune_parameters['ccargs'].split():
195 if i in whitelist:
196 opts.append(i)
197 options.append(" ".join(opts))
198
199 if tune_baselib == 'lib':
200 dirnames.append('32') # /lib => 32bit lib
201 else:
202 dirnames.append(tune_baselib.replace('lib', ''))
203 osdirnames.append('../' + tune_baselib)
204
205 write_config(builddir, target_config_files, options, dirnames, osdirnames)
206 write_headers(builddir, header_config_files, libdir32, libdir64, libdirx32, libdirn32)
207}
208
209gcc_multilib_setup[cleandirs] = "${B}/gcc/config"
210
211EXTRACONFFUNCS += "gcc_multilib_setup"