xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-devtools/gcc/gcc-multilib-config.inc (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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