]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/tools/gcc.py
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / tools / build / src / tools / gcc.py
1 # Status: being ported by Steven Watanabe
2 # Base revision: 47077
3 # TODO: common.jam needs to be ported
4 # TODO: generators.jam needs to have register_c_compiler.
5 #
6 # Copyright 2001 David Abrahams.
7 # Copyright 2002-2006 Rene Rivera.
8 # Copyright 2002-2003 Vladimir Prus.
9 # Copyright (c) 2005 Reece H. Dunn.
10 # Copyright 2006 Ilya Sokolov.
11 # Copyright 2007 Roland Schwarz
12 # Copyright 2007 Boris Gubenko.
13 # Copyright 2008 Steven Watanabe
14 #
15 # Distributed under the Boost Software License, Version 1.0.
16 # (See accompanying file LICENSE_1_0.txt or copy at
17 # http://www.boost.org/LICENSE_1_0.txt)
18
19 import os
20 import subprocess
21 import re
22
23 import bjam
24
25 from b2.tools import unix, common, rc, pch, builtin
26 from b2.build import feature, type, toolset, generators, property_set
27 from b2.build.property import Property
28 from b2.util.utility import os_name, on_windows
29 from b2.manager import get_manager
30 from b2.build.generators import Generator
31 from b2.build.toolset import flags
32 from b2.util.utility import to_seq
33
34
35
36 __debug = None
37
38 def debug():
39 global __debug
40 if __debug is None:
41 __debug = "--debug-configuration" in bjam.variable("ARGV")
42 return __debug
43
44 feature.extend('toolset', ['gcc'])
45
46
47 toolset.inherit_generators('gcc', [], 'unix', ['unix.link', 'unix.link.dll'])
48 toolset.inherit_flags('gcc', 'unix')
49 toolset.inherit_rules('gcc', 'unix')
50
51 generators.override('gcc.prebuilt', 'builtin.prebuilt')
52 generators.override('gcc.searched-lib-generator', 'searched-lib-generator')
53
54 # Target naming is determined by types/lib.jam and the settings below this
55 # comment.
56 #
57 # On *nix:
58 # libxxx.a static library
59 # libxxx.so shared library
60 #
61 # On windows (mingw):
62 # libxxx.lib static library
63 # xxx.dll DLL
64 # xxx.lib import library
65 #
66 # On windows (cygwin) i.e. <target-os>cygwin
67 # libxxx.a static library
68 # xxx.dll DLL
69 # libxxx.dll.a import library
70 #
71 # Note: user can always override by using the <tag>@rule
72 # This settings have been chosen, so that mingw
73 # is in line with msvc naming conventions. For
74 # cygwin the cygwin naming convention has been chosen.
75
76 # Make the "o" suffix used for gcc toolset on all
77 # platforms
78 type.set_generated_target_suffix('OBJ', ['<toolset>gcc'], 'o')
79 type.set_generated_target_suffix('STATIC_LIB', ['<toolset>gcc', '<target-os>cygwin'], 'a')
80
81 type.set_generated_target_suffix('IMPORT_LIB', ['<toolset>gcc', '<target-os>cygwin'], 'dll.a')
82 type.set_generated_target_prefix('IMPORT_LIB', ['<toolset>gcc', '<target-os>cygwin'], 'lib')
83
84 __machine_match = re.compile('^([^ ]+)')
85 __version_match = re.compile('^([0-9.]+)')
86
87 def init(version = None, command = None, options = None):
88 """
89 Initializes the gcc toolset for the given version. If necessary, command may
90 be used to specify where the compiler is located. The parameter 'options' is a
91 space-delimited list of options, each one specified as
92 <option-name>option-value. Valid option names are: cxxflags, linkflags and
93 linker-type. Accepted linker-type values are gnu, darwin, osf, hpux or sun
94 and the default value will be selected based on the current OS.
95 Example:
96 using gcc : 3.4 : : <cxxflags>foo <linkflags>bar <linker-type>sun ;
97 """
98
99 options = to_seq(options)
100 command = to_seq(command)
101
102 # Information about the gcc command...
103 # The command.
104 command = to_seq(common.get_invocation_command('gcc', 'g++', command))
105 # The root directory of the tool install.
106 root = feature.get_values('<root>', options)
107 root = root[0] if root else ''
108 # The bin directory where to find the command to execute.
109 bin = None
110 # The flavor of compiler.
111 flavor = feature.get_values('<flavor>', options)
112 flavor = flavor[0] if flavor else ''
113 # Autodetect the root and bin dir if not given.
114 if command:
115 if not bin:
116 bin = common.get_absolute_tool_path(command[-1])
117 if not root:
118 root = os.path.dirname(bin)
119 # Autodetect the version and flavor if not given.
120 if command:
121 machine_info = subprocess.Popen(command + ['-dumpmachine'], stdout=subprocess.PIPE).communicate()[0]
122 machine = __machine_match.search(machine_info).group(1)
123
124 version_info = subprocess.Popen(command + ['-dumpversion'], stdout=subprocess.PIPE).communicate()[0]
125 version = __version_match.search(version_info).group(1)
126 if not flavor and machine.find('mingw') != -1:
127 flavor = 'mingw'
128
129 condition = None
130 if flavor:
131 condition = common.check_init_parameters('gcc', None,
132 ('version', version),
133 ('flavor', flavor))
134 else:
135 condition = common.check_init_parameters('gcc', None,
136 ('version', version))
137
138 if command:
139 command = command[0]
140
141 common.handle_options('gcc', condition, command, options)
142
143 linker = feature.get_values('<linker-type>', options)
144 if not linker:
145 if os_name() == 'OSF':
146 linker = 'osf'
147 elif os_name() == 'HPUX':
148 linker = 'hpux' ;
149 else:
150 linker = 'gnu'
151
152 init_link_flags('gcc', linker, condition)
153
154 # If gcc is installed in non-standard location, we'd need to add
155 # LD_LIBRARY_PATH when running programs created with it (for unit-test/run
156 # rules).
157 if command:
158 # On multilib 64-bit boxes, there are both 32-bit and 64-bit libraries
159 # and all must be added to LD_LIBRARY_PATH. The linker will pick the
160 # right ones. Note that we don't provide a clean way to build 32-bit
161 # binary with 64-bit compiler, but user can always pass -m32 manually.
162 lib_path = [os.path.join(root, 'bin'),
163 os.path.join(root, 'lib'),
164 os.path.join(root, 'lib32'),
165 os.path.join(root, 'lib64')]
166 if debug():
167 print 'notice: using gcc libraries ::', condition, '::', lib_path
168 toolset.flags('gcc.link', 'RUN_PATH', condition, lib_path)
169
170 # If it's not a system gcc install we should adjust the various programs as
171 # needed to prefer using the install specific versions. This is essential
172 # for correct use of MinGW and for cross-compiling.
173
174 # - The archive builder.
175 archiver = common.get_invocation_command('gcc',
176 'ar', feature.get_values('<archiver>', options), [bin], path_last=True)
177 toolset.flags('gcc.archive', '.AR', condition, [archiver])
178 if debug():
179 print 'notice: using gcc archiver ::', condition, '::', archiver
180
181 # - Ranlib
182 ranlib = common.get_invocation_command('gcc',
183 'ranlib', feature.get_values('<ranlib>', options), [bin], path_last=True)
184 toolset.flags('gcc.archive', '.RANLIB', condition, [ranlib])
185 if debug():
186 print 'notice: using gcc archiver ::', condition, '::', ranlib
187
188 # - The resource compiler.
189 rc_command = common.get_invocation_command_nodefault('gcc',
190 'windres', feature.get_values('<rc>', options), [bin], path_last=True)
191 rc_type = feature.get_values('<rc-type>', options)
192
193 if not rc_type:
194 rc_type = 'windres'
195
196 if not rc_command:
197 # If we can't find an RC compiler we fallback to a null RC compiler that
198 # creates empty object files. This allows the same Jamfiles to work
199 # across the board. The null RC uses the assembler to create the empty
200 # objects, so configure that.
201 rc_command = common.get_invocation_command('gcc', 'as', [], [bin], path_last=True)
202 rc_type = 'null'
203 rc.configure([rc_command], condition, ['<rc-type>' + rc_type])
204
205 ###if [ os.name ] = NT
206 ###{
207 ### # This causes single-line command invocation to not go through .bat files,
208 ### # thus avoiding command-line length limitations.
209 ### JAMSHELL = % ;
210 ###}
211
212 #FIXME: when register_c_compiler is moved to
213 # generators, these should be updated
214 builtin.register_c_compiler('gcc.compile.c++.preprocess', ['CPP'], ['PREPROCESSED_CPP'], ['<toolset>gcc'])
215 builtin.register_c_compiler('gcc.compile.c.preprocess', ['C'], ['PREPROCESSED_C'], ['<toolset>gcc'])
216 builtin.register_c_compiler('gcc.compile.c++', ['CPP'], ['OBJ'], ['<toolset>gcc'])
217 builtin.register_c_compiler('gcc.compile.c', ['C'], ['OBJ'], ['<toolset>gcc'])
218 builtin.register_c_compiler('gcc.compile.asm', ['ASM'], ['OBJ'], ['<toolset>gcc'])
219
220 # pch support
221
222 # The compiler looks for a precompiled header in each directory just before it
223 # looks for the include file in that directory. The name searched for is the
224 # name specified in the #include directive with ".gch" suffix appended. The
225 # logic in gcc-pch-generator will make sure that BASE_PCH suffix is appended to
226 # full name of the header.
227
228 type.set_generated_target_suffix('PCH', ['<toolset>gcc'], 'gch')
229
230 # GCC-specific pch generator.
231 class GccPchGenerator(pch.PchGenerator):
232
233 # Inherit the __init__ method
234
235 def run_pch(self, project, name, prop_set, sources):
236 # Find the header in sources. Ignore any CPP sources.
237 header = None
238 for s in sources:
239 if type.is_derived(s.type(), 'H'):
240 header = s
241
242 # Error handling: Base header file name should be the same as the base
243 # precompiled header name.
244 header_name = header.name()
245 header_basename = os.path.basename(header_name).rsplit('.', 1)[0]
246 if header_basename != name:
247 location = project.project_module
248 ###FIXME:
249 raise Exception()
250 ### errors.user-error "in" $(location)": pch target name `"$(name)"' should be the same as the base name of header file `"$(header-name)"'" ;
251
252 pch_file = Generator.run(self, project, name, prop_set, [header])
253
254 # return result of base class and pch-file property as usage-requirements
255 # FIXME: what about multiple results from generator.run?
256 return (property_set.create([Property('pch-file', pch_file[0]),
257 Property('cflags', '-Winvalid-pch')]),
258 pch_file)
259
260 # Calls the base version specifying source's name as the name of the created
261 # target. As result, the PCH will be named whatever.hpp.gch, and not
262 # whatever.gch.
263 def generated_targets(self, sources, prop_set, project, name = None):
264 name = sources[0].name()
265 return Generator.generated_targets(self, sources,
266 prop_set, project, name)
267
268 # Note: the 'H' source type will catch both '.h' header and '.hpp' header. The
269 # latter have HPP type, but HPP type is derived from H. The type of compilation
270 # is determined entirely by the destination type.
271 generators.register(GccPchGenerator('gcc.compile.c.pch', False, ['H'], ['C_PCH'], ['<pch>on', '<toolset>gcc' ]))
272 generators.register(GccPchGenerator('gcc.compile.c++.pch', False, ['H'], ['CPP_PCH'], ['<pch>on', '<toolset>gcc' ]))
273
274 # Override default do-nothing generators.
275 generators.override('gcc.compile.c.pch', 'pch.default-c-pch-generator')
276 generators.override('gcc.compile.c++.pch', 'pch.default-cpp-pch-generator')
277
278 flags('gcc.compile', 'PCH_FILE', ['<pch>on'], ['<pch-file>'])
279
280 # Declare flags and action for compilation
281 flags('gcc.compile', 'OPTIONS', ['<optimization>off'], ['-O0'])
282 flags('gcc.compile', 'OPTIONS', ['<optimization>speed'], ['-O3'])
283 flags('gcc.compile', 'OPTIONS', ['<optimization>space'], ['-Os'])
284
285 flags('gcc.compile', 'OPTIONS', ['<inlining>off'], ['-fno-inline'])
286 flags('gcc.compile', 'OPTIONS', ['<inlining>on'], ['-Wno-inline'])
287 flags('gcc.compile', 'OPTIONS', ['<inlining>full'], ['-finline-functions', '-Wno-inline'])
288
289 flags('gcc.compile', 'OPTIONS', ['<warnings>off'], ['-w'])
290 flags('gcc.compile', 'OPTIONS', ['<warnings>on'], ['-Wall'])
291 flags('gcc.compile', 'OPTIONS', ['<warnings>all'], ['-Wall', '-pedantic'])
292 flags('gcc.compile', 'OPTIONS', ['<warnings-as-errors>on'], ['-Werror'])
293
294 flags('gcc.compile', 'OPTIONS', ['<debug-symbols>on'], ['-g'])
295 flags('gcc.compile', 'OPTIONS', ['<profiling>on'], ['-pg'])
296
297 flags('gcc.compile.c++', 'OPTIONS', ['<rtti>off'], ['-fno-rtti'])
298 flags('gcc.compile.c++', 'OPTIONS', ['<exception-handling>off'], ['-fno-exceptions'])
299
300 # On cygwin and mingw, gcc generates position independent code by default, and
301 # warns if -fPIC is specified. This might not be the right way of checking if
302 # we're using cygwin. For example, it's possible to run cygwin gcc from NT
303 # shell, or using crosscompiling. But we'll solve that problem when it's time.
304 # In that case we'll just add another parameter to 'init' and move this login
305 # inside 'init'.
306 if not os_name () in ['CYGWIN', 'NT']:
307 # This logic will add -fPIC for all compilations:
308 #
309 # lib a : a.cpp b ;
310 # obj b : b.cpp ;
311 # exe c : c.cpp a d ;
312 # obj d : d.cpp ;
313 #
314 # This all is fine, except that 'd' will be compiled with -fPIC even though
315 # it's not needed, as 'd' is used only in exe. However, it's hard to detect
316 # where a target is going to be used. Alternative, we can set -fPIC only
317 # when main target type is LIB but than 'b' will be compiled without -fPIC.
318 # In x86-64 that will lead to link errors. So, compile everything with
319 # -fPIC.
320 #
321 # Yet another alternative would be to create propagated <sharedable>
322 # feature, and set it when building shared libraries, but that's hard to
323 # implement and will increase target path length even more.
324 flags('gcc.compile', 'OPTIONS', ['<link>shared'], ['-fPIC'])
325
326 if os_name() != 'NT' and os_name() != 'OSF' and os_name() != 'HPUX':
327 # OSF does have an option called -soname but it doesn't seem to work as
328 # expected, therefore it has been disabled.
329 HAVE_SONAME = ''
330 SONAME_OPTION = '-h'
331
332
333 flags('gcc.compile', 'USER_OPTIONS', [], ['<cflags>'])
334 flags('gcc.compile.c++', 'USER_OPTIONS',[], ['<cxxflags>'])
335 flags('gcc.compile', 'DEFINES', [], ['<define>'])
336 flags('gcc.compile', 'INCLUDES', [], ['<include>'])
337
338 engine = get_manager().engine()
339
340 engine.register_action('gcc.compile.c++.pch',
341 '"$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"')
342
343 engine.register_action('gcc.compile.c.pch',
344 '"$(CONFIG_COMMAND)" -x c-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"')
345
346
347 def gcc_compile_cpp(targets, sources, properties):
348 # Some extensions are compiled as C++ by default. For others, we need to
349 # pass -x c++. We could always pass -x c++ but distcc does not work with it.
350 extension = os.path.splitext (sources [0]) [1]
351 lang = ''
352 if not extension in ['.cc', '.cp', '.cxx', '.cpp', '.c++', '.C']:
353 lang = '-x c++'
354 get_manager().engine().set_target_variable (targets, 'LANG', lang)
355 engine.add_dependency(targets, bjam.call('get-target-variable', targets, 'PCH_FILE'))
356
357 def gcc_compile_c(targets, sources, properties):
358 engine = get_manager().engine()
359 # If we use the name g++ then default file suffix -> language mapping does
360 # not work. So have to pass -x option. Maybe, we can work around this by
361 # allowing the user to specify both C and C++ compiler names.
362 #if $(>:S) != .c
363 #{
364 engine.set_target_variable (targets, 'LANG', '-x c')
365 #}
366 engine.add_dependency(targets, bjam.call('get-target-variable', targets, 'PCH_FILE'))
367
368 engine.register_action(
369 'gcc.compile.c++',
370 '"$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-128 $(OPTIONS) ' +
371 '$(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" ' +
372 '-c -o "$(<:W)" "$(>:W)"',
373 function=gcc_compile_cpp,
374 bound_list=['PCH_FILE'])
375
376 engine.register_action(
377 'gcc.compile.c',
378 '"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) ' +
379 '-I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)"',
380 function=gcc_compile_c,
381 bound_list=['PCH_FILE'])
382
383 engine.register_action(
384 'gcc.compile.c++.preprocess',
385 function=gcc_compile_cpp,
386 bound_list=['PCH_FILE'],
387 command="""
388 $(CONFIG_COMMAND) $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>:W)" -E >"$(<:W)"
389 """
390 )
391
392 engine.register_action(
393 'gcc.compile.c.preprocess',
394 function=gcc_compile_c,
395 bound_list=['PCH_FILE'],
396 command="""
397 $(CONFIG_COMMAND) $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>)" -E >$(<)
398 """
399 )
400
401 def gcc_compile_asm(targets, sources, properties):
402 get_manager().engine().set_target_variable(targets, 'LANG', '-x assembler-with-cpp')
403
404 engine.register_action(
405 'gcc.compile.asm',
406 '"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"',
407 function=gcc_compile_asm)
408
409
410 class GccLinkingGenerator(unix.UnixLinkingGenerator):
411 """
412 The class which check that we don't try to use the <runtime-link>static
413 property while creating or using shared library, since it's not supported by
414 gcc/libc.
415 """
416 def run(self, project, name, ps, sources):
417 # TODO: Replace this with the use of a target-os property.
418
419 no_static_link = False
420 if bjam.variable('UNIX'):
421 no_static_link = True;
422 ##FIXME: what does this mean?
423 ## {
424 ## switch [ modules.peek : JAMUNAME ]
425 ## {
426 ## case * : no-static-link = true ;
427 ## }
428 ## }
429
430 reason = None
431 if no_static_link and ps.get('runtime-link') == 'static':
432 if ps.get('link') == 'shared':
433 reason = "On gcc, DLL can't be build with '<runtime-link>static'."
434 elif type.is_derived(self.target_types[0], 'EXE'):
435 for s in sources:
436 source_type = s.type()
437 if source_type and type.is_derived(source_type, 'SHARED_LIB'):
438 reason = "On gcc, using DLLS together with the " +\
439 "<runtime-link>static options is not possible "
440 if reason:
441 print 'warning:', reason
442 print 'warning:',\
443 "It is suggested to use '<runtime-link>static' together",\
444 "with '<link>static'." ;
445 return
446 else:
447 generated_targets = unix.UnixLinkingGenerator.run(self, project,
448 name, ps, sources)
449 return generated_targets
450
451 if on_windows():
452 flags('gcc.link.dll', '.IMPLIB-COMMAND', [], ['-Wl,--out-implib,'])
453 generators.register(
454 GccLinkingGenerator('gcc.link', True,
455 ['OBJ', 'SEARCHED_LIB', 'STATIC_LIB', 'IMPORT_LIB'],
456 [ 'EXE' ],
457 [ '<toolset>gcc' ]))
458 generators.register(
459 GccLinkingGenerator('gcc.link.dll', True,
460 ['OBJ', 'SEARCHED_LIB', 'STATIC_LIB', 'IMPORT_LIB'],
461 ['IMPORT_LIB', 'SHARED_LIB'],
462 ['<toolset>gcc']))
463 else:
464 generators.register(
465 GccLinkingGenerator('gcc.link', True,
466 ['LIB', 'OBJ'],
467 ['EXE'],
468 ['<toolset>gcc']))
469 generators.register(
470 GccLinkingGenerator('gcc.link.dll', True,
471 ['LIB', 'OBJ'],
472 ['SHARED_LIB'],
473 ['<toolset>gcc']))
474
475 # Declare flags for linking.
476 # First, the common flags.
477 flags('gcc.link', 'OPTIONS', ['<debug-symbols>on'], ['-g'])
478 flags('gcc.link', 'OPTIONS', ['<profiling>on'], ['-pg'])
479 flags('gcc.link', 'USER_OPTIONS', [], ['<linkflags>'])
480 flags('gcc.link', 'LINKPATH', [], ['<library-path>'])
481 flags('gcc.link', 'FINDLIBS-ST', [], ['<find-static-library>'])
482 flags('gcc.link', 'FINDLIBS-SA', [], ['<find-shared-library>'])
483 flags('gcc.link', 'LIBRARIES', [], ['<library-file>'])
484
485 # For <runtime-link>static we made sure there are no dynamic libraries in the
486 # link. On HP-UX not all system libraries exist as archived libraries (for
487 # example, there is no libunwind.a), so, on this platform, the -static option
488 # cannot be specified.
489 if os_name() != 'HPUX':
490 flags('gcc.link', 'OPTIONS', ['<runtime-link>static'], ['-static'])
491
492 # Now, the vendor specific flags.
493 # The parameter linker can be either gnu, darwin, osf, hpux or sun.
494 def init_link_flags(toolset, linker, condition):
495 """
496 Now, the vendor specific flags.
497 The parameter linker can be either gnu, darwin, osf, hpux or sun.
498 """
499 toolset_link = toolset + '.link'
500 if linker == 'gnu':
501 # Strip the binary when no debugging is needed. We use --strip-all flag
502 # as opposed to -s since icc (intel's compiler) is generally
503 # option-compatible with and inherits from the gcc toolset, but does not
504 # support -s.
505
506 # FIXME: what does unchecked translate to?
507 flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,--strip-all']) # : unchecked ;
508 flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ;
509 flags(toolset_link, 'RPATH_LINK', condition, ['<xdll-path>']) # : unchecked ;
510 flags(toolset_link, 'START-GROUP', condition, ['-Wl,--start-group'])# : unchecked ;
511 flags(toolset_link, 'END-GROUP', condition, ['-Wl,--end-group']) # : unchecked ;
512
513 # gnu ld has the ability to change the search behaviour for libraries
514 # referenced by -l switch. These modifiers are -Bstatic and -Bdynamic
515 # and change search for -l switches that follow them. The following list
516 # shows the tried variants.
517 # The search stops at the first variant that has a match.
518 # *nix: -Bstatic -lxxx
519 # libxxx.a
520 #
521 # *nix: -Bdynamic -lxxx
522 # libxxx.so
523 # libxxx.a
524 #
525 # windows (mingw,cygwin) -Bstatic -lxxx
526 # libxxx.a
527 # xxx.lib
528 #
529 # windows (mingw,cygwin) -Bdynamic -lxxx
530 # libxxx.dll.a
531 # xxx.dll.a
532 # libxxx.a
533 # xxx.lib
534 # cygxxx.dll (*)
535 # libxxx.dll
536 # xxx.dll
537 # libxxx.a
538 #
539 # (*) This is for cygwin
540 # Please note that -Bstatic and -Bdynamic are not a guarantee that a
541 # static or dynamic lib indeed gets linked in. The switches only change
542 # search patterns!
543
544 # On *nix mixing shared libs with static runtime is not a good idea.
545 flags(toolset_link, 'FINDLIBS-ST-PFX',
546 map(lambda x: x + '/<runtime-link>shared', condition),
547 ['-Wl,-Bstatic']) # : unchecked ;
548 flags(toolset_link, 'FINDLIBS-SA-PFX',
549 map(lambda x: x + '/<runtime-link>shared', condition),
550 ['-Wl,-Bdynamic']) # : unchecked ;
551
552 # On windows allow mixing of static and dynamic libs with static
553 # runtime.
554 flags(toolset_link, 'FINDLIBS-ST-PFX',
555 map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition),
556 ['-Wl,-Bstatic']) # : unchecked ;
557 flags(toolset_link, 'FINDLIBS-SA-PFX',
558 map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition),
559 ['-Wl,-Bdynamic']) # : unchecked ;
560 flags(toolset_link, 'OPTIONS',
561 map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition),
562 ['-Wl,-Bstatic']) # : unchecked ;
563
564 elif linker == 'darwin':
565 # On Darwin, the -s option to ld does not work unless we pass -static,
566 # and passing -static unconditionally is a bad idea. So, don't pass -s.
567 # at all, darwin.jam will use separate 'strip' invocation.
568 flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ;
569 flags(toolset_link, 'RPATH_LINK', condition, ['<xdll-path>']) # : unchecked ;
570
571 elif linker == 'osf':
572 # No --strip-all, just -s.
573 flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s'])
574 # : unchecked ;
575 flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ;
576 # This does not supports -R.
577 flags(toolset_link, 'RPATH_OPTION', condition, ['-rpath']) # : unchecked ;
578 # -rpath-link is not supported at all.
579
580 elif linker == 'sun':
581 flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s'])
582 # : unchecked ;
583 flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ;
584 # Solaris linker does not have a separate -rpath-link, but allows to use
585 # -L for the same purpose.
586 flags(toolset_link, 'LINKPATH', condition, ['<xdll-path>']) # : unchecked ;
587
588 # This permits shared libraries with non-PIC code on Solaris.
589 # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the
590 # following is not needed. Whether -fPIC should be hardcoded, is a
591 # separate question.
592 # AH, 2004/10/16: it is still necessary because some tests link against
593 # static libraries that were compiled without PIC.
594 flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<link>shared', condition), ['-mimpure-text'])
595 # : unchecked ;
596
597 elif linker == 'hpux':
598 flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition),
599 ['-Wl,-s']) # : unchecked ;
600 flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<link>shared', condition),
601 ['-fPIC']) # : unchecked ;
602
603 else:
604 # FIXME:
605 errors.user_error(
606 "$(toolset) initialization: invalid linker '$(linker)' " +
607 "The value '$(linker)' specified for <linker> is not recognized. " +
608 "Possible values are 'gnu', 'darwin', 'osf', 'hpux' or 'sun'")
609
610 # Declare actions for linking.
611 def gcc_link(targets, sources, properties):
612 engine = get_manager().engine()
613 engine.set_target_variable(targets, 'SPACE', ' ')
614 # Serialize execution of the 'link' action, since running N links in
615 # parallel is just slower. For now, serialize only gcc links, it might be a
616 # good idea to serialize all links.
617 engine.set_target_variable(targets, 'JAM_SEMAPHORE', '<s>gcc-link-semaphore')
618
619 engine.register_action(
620 'gcc.link',
621 '"$(CONFIG_COMMAND)" -L"$(LINKPATH)" ' +
622 '-Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" ' +
623 '-Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" ' +
624 '$(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) ' +
625 '-l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) ' +
626 '$(OPTIONS) $(USER_OPTIONS)',
627 function=gcc_link,
628 bound_list=['LIBRARIES'])
629
630 # Default value. Mostly for the sake of intel-linux that inherits from gcc, but
631 # does not have the same logic to set the .AR variable. We can put the same
632 # logic in intel-linux, but that's hardly worth the trouble as on Linux, 'ar' is
633 # always available.
634 __AR = 'ar'
635
636 flags('gcc.archive', 'AROPTIONS', [], ['<archiveflags>'])
637
638 def gcc_archive(targets, sources, properties):
639 # Always remove archive and start again. Here's rationale from
640 #
641 # Andre Hentz:
642 #
643 # I had a file, say a1.c, that was included into liba.a. I moved a1.c to
644 # a2.c, updated my Jamfiles and rebuilt. My program was crashing with absurd
645 # errors. After some debugging I traced it back to the fact that a1.o was
646 # *still* in liba.a
647 #
648 # Rene Rivera:
649 #
650 # Originally removing the archive was done by splicing an RM onto the
651 # archive action. That makes archives fail to build on NT when they have
652 # many files because it will no longer execute the action directly and blow
653 # the line length limit. Instead we remove the file in a different action,
654 # just before building the archive.
655 clean = targets[0] + '(clean)'
656 bjam.call('TEMPORARY', clean)
657 bjam.call('NOCARE', clean)
658 engine = get_manager().engine()
659 engine.set_target_variable('LOCATE', clean, bjam.call('get-target-variable', targets, 'LOCATE'))
660 engine.add_dependency(clean, sources)
661 engine.add_dependency(targets, clean)
662 engine.set_update_action('common.RmTemps', clean, targets)
663
664 # Declare action for creating static libraries.
665 # The letter 'r' means to add files to the archive with replacement. Since we
666 # remove archive, we don't care about replacement, but there's no option "add
667 # without replacement".
668 # The letter 'c' suppresses the warning in case the archive does not exists yet.
669 # That warning is produced only on some platforms, for whatever reasons.
670 engine.register_action('gcc.archive',
671 '''"$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)"
672 "$(.RANLIB)" "$(<)"
673 ''',
674 function=gcc_archive,
675 flags=['piecemeal'])
676
677 def gcc_link_dll(targets, sources, properties):
678 engine = get_manager().engine()
679 engine.set_target_variable(targets, 'SPACE', ' ')
680 engine.set_target_variable(targets, 'JAM_SEMAPHORE', '<s>gcc-link-semaphore')
681 engine.set_target_variable(targets, "HAVE_SONAME", HAVE_SONAME)
682 engine.set_target_variable(targets, "SONAME_OPTION", SONAME_OPTION)
683
684 engine.register_action(
685 'gcc.link.dll',
686 # Differ from 'link' above only by -shared.
687 '"$(CONFIG_COMMAND)" -L"$(LINKPATH)" ' +
688 '-Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" ' +
689 '"$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" ' +
690 '$(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) ' +
691 '-shared $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) ' +
692 '-l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) ' +
693 '$(OPTIONS) $(USER_OPTIONS)',
694 function = gcc_link_dll,
695 bound_list=['LIBRARIES'])
696
697 # Set up threading support. It's somewhat contrived, so perform it at the end,
698 # to avoid cluttering other code.
699
700 if on_windows():
701 flags('gcc', 'OPTIONS', ['<threading>multi'], ['-mthreads'])
702 elif bjam.variable('UNIX'):
703 jamuname = bjam.variable('JAMUNAME')
704 host_os_name = jamuname[0]
705 if host_os_name.startswith('SunOS'):
706 flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthreads'])
707 flags('gcc', 'FINDLIBS-SA', [], ['rt'])
708 elif host_os_name == 'BeOS':
709 # BeOS has no threading options, don't set anything here.
710 pass
711 elif host_os_name == 'Haiku':
712 flags('gcc', 'OPTIONS', ['<threading>multi'], ['-lroot'])
713 # there is no -lrt on Haiku, and -pthread is implicit
714 elif host_os_name.endswith('BSD'):
715 flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
716 # there is no -lrt on BSD
717 elif host_os_name == 'DragonFly':
718 flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
719 # there is no -lrt on BSD - DragonFly is a FreeBSD variant,
720 # which anoyingly doesn't say it's a *BSD.
721 elif host_os_name == 'IRIX':
722 # gcc on IRIX does not support multi-threading, don't set anything here.
723 pass
724 elif host_os_name == 'Darwin':
725 # Darwin has no threading options, don't set anything here.
726 pass
727 else:
728 flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
729 flags('gcc', 'FINDLIBS-SA', [], ['rt'])
730
731 def cpu_flags(toolset, variable, architecture, instruction_set, values, default=None):
732 #FIXME: for some reason this fails. Probably out of date feature code
733 ## if default:
734 ## flags(toolset, variable,
735 ## ['<architecture>' + architecture + '/<instruction-set>'],
736 ## values)
737 flags(toolset, variable,
738 #FIXME: same as above
739 [##'<architecture>/<instruction-set>' + instruction_set,
740 '<architecture>' + architecture + '/<instruction-set>' + instruction_set],
741 values)
742
743 # Set architecture/instruction-set options.
744 #
745 # x86 and compatible
746 flags('gcc', 'OPTIONS', ['<architecture>x86/<address-model>32'], ['-m32'])
747 flags('gcc', 'OPTIONS', ['<architecture>x86/<address-model>64'], ['-m64'])
748 cpu_flags('gcc', 'OPTIONS', 'x86', 'native', ['-march=native'])
749 cpu_flags('gcc', 'OPTIONS', 'x86', 'i486', ['-march=i486'])
750 cpu_flags('gcc', 'OPTIONS', 'x86', 'i586', ['-march=i586'])
751 cpu_flags('gcc', 'OPTIONS', 'x86', 'i686', ['-march=i686'], default=True)
752 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium', ['-march=pentium'])
753 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium-mmx', ['-march=pentium-mmx'])
754 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentiumpro', ['-march=pentiumpro'])
755 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium2', ['-march=pentium2'])
756 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium3', ['-march=pentium3'])
757 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium3m', ['-march=pentium3m'])
758 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium-m', ['-march=pentium-m'])
759 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium4', ['-march=pentium4'])
760 cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium4m', ['-march=pentium4m'])
761 cpu_flags('gcc', 'OPTIONS', 'x86', 'prescott', ['-march=prescott'])
762 cpu_flags('gcc', 'OPTIONS', 'x86', 'nocona', ['-march=nocona'])
763 cpu_flags('gcc', 'OPTIONS', 'x86', 'core2', ['-march=core2'])
764 cpu_flags('gcc', 'OPTIONS', 'x86', 'conroe', ['-march=core2'])
765 cpu_flags('gcc', 'OPTIONS', 'x86', 'conroe-xe', ['-march=core2'])
766 cpu_flags('gcc', 'OPTIONS', 'x86', 'conroe-l', ['-march=core2'])
767 cpu_flags('gcc', 'OPTIONS', 'x86', 'allendale', ['-march=core2'])
768 cpu_flags('gcc', 'OPTIONS', 'x86', 'wolfdale', ['-march=core2', '-msse4.1'])
769 cpu_flags('gcc', 'OPTIONS', 'x86', 'merom', ['-march=core2'])
770 cpu_flags('gcc', 'OPTIONS', 'x86', 'merom-xe', ['-march=core2'])
771 cpu_flags('gcc', 'OPTIONS', 'x86', 'kentsfield', ['-march=core2'])
772 cpu_flags('gcc', 'OPTIONS', 'x86', 'kentsfield-xe', ['-march=core2'])
773 cpu_flags('gcc', 'OPTIONS', 'x86', 'yorksfield', ['-march=core2'])
774 cpu_flags('gcc', 'OPTIONS', 'x86', 'penryn', ['-march=core2'])
775 cpu_flags('gcc', 'OPTIONS', 'x86', 'corei7', ['-march=corei7'])
776 cpu_flags('gcc', 'OPTIONS', 'x86', 'nehalem', ['-march=corei7'])
777 cpu_flags('gcc', 'OPTIONS', 'x86', 'corei7-avx', ['-march=corei7-avx'])
778 cpu_flags('gcc', 'OPTIONS', 'x86', 'sandy-bridge', ['-march=corei7-avx'])
779 cpu_flags('gcc', 'OPTIONS', 'x86', 'core-avx-i', ['-march=core-avx-i'])
780 cpu_flags('gcc', 'OPTIONS', 'x86', 'ivy-bridge', ['-march=core-avx-i'])
781 cpu_flags('gcc', 'OPTIONS', 'x86', 'haswell', ['-march=core-avx-i', '-mavx2', '-mfma', '-mbmi', '-mbmi2', '-mlzcnt'])
782 cpu_flags('gcc', 'OPTIONS', 'x86', 'k6', ['-march=k6'])
783 cpu_flags('gcc', 'OPTIONS', 'x86', 'k6-2', ['-march=k6-2'])
784 cpu_flags('gcc', 'OPTIONS', 'x86', 'k6-3', ['-march=k6-3'])
785 cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon', ['-march=athlon'])
786 cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-tbird', ['-march=athlon-tbird'])
787 cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-4', ['-march=athlon-4'])
788 cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-xp', ['-march=athlon-xp'])
789 cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-mp', ['-march=athlon-mp'])
790 ##
791 cpu_flags('gcc', 'OPTIONS', 'x86', 'k8', ['-march=k8'])
792 cpu_flags('gcc', 'OPTIONS', 'x86', 'opteron', ['-march=opteron'])
793 cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon64', ['-march=athlon64'])
794 cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-fx', ['-march=athlon-fx'])
795 cpu_flags('gcc', 'OPTIONS', 'x86', 'k8-sse3', ['-march=k8-sse3'])
796 cpu_flags('gcc', 'OPTIONS', 'x86', 'opteron-sse3', ['-march=opteron-sse3'])
797 cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon64-sse3', ['-march=athlon64-sse3'])
798 cpu_flags('gcc', 'OPTIONS', 'x86', 'amdfam10', ['-march=amdfam10'])
799 cpu_flags('gcc', 'OPTIONS', 'x86', 'barcelona', ['-march=barcelona'])
800 cpu_flags('gcc', 'OPTIONS', 'x86', 'bdver1', ['-march=bdver1'])
801 cpu_flags('gcc', 'OPTIONS', 'x86', 'bdver2', ['-march=bdver2'])
802 cpu_flags('gcc', 'OPTIONS', 'x86', 'bdver3', ['-march=bdver3'])
803 cpu_flags('gcc', 'OPTIONS', 'x86', 'btver1', ['-march=btver1'])
804 cpu_flags('gcc', 'OPTIONS', 'x86', 'btver2', ['-march=btver2'])
805 cpu_flags('gcc', 'OPTIONS', 'x86', 'winchip-c6', ['-march=winchip-c6'])
806 cpu_flags('gcc', 'OPTIONS', 'x86', 'winchip2', ['-march=winchip2'])
807 cpu_flags('gcc', 'OPTIONS', 'x86', 'c3', ['-march=c3'])
808 cpu_flags('gcc', 'OPTIONS', 'x86', 'c3-2', ['-march=c3-2'])
809 ##
810 cpu_flags('gcc', 'OPTIONS', 'x86', 'atom', ['-march=atom'])
811 # Sparc
812 flags('gcc', 'OPTIONS', ['<architecture>sparc/<address-model>32'], ['-m32'])
813 flags('gcc', 'OPTIONS', ['<architecture>sparc/<address-model>64'], ['-m64'])
814 cpu_flags('gcc', 'OPTIONS', 'sparc', 'v7', ['-mcpu=v7'], default=True)
815 cpu_flags('gcc', 'OPTIONS', 'sparc', 'cypress', ['-mcpu=cypress'])
816 cpu_flags('gcc', 'OPTIONS', 'sparc', 'v8', ['-mcpu=v8'])
817 cpu_flags('gcc', 'OPTIONS', 'sparc', 'supersparc', ['-mcpu=supersparc'])
818 cpu_flags('gcc', 'OPTIONS', 'sparc', 'sparclite', ['-mcpu=sparclite'])
819 cpu_flags('gcc', 'OPTIONS', 'sparc', 'hypersparc', ['-mcpu=hypersparc'])
820 cpu_flags('gcc', 'OPTIONS', 'sparc', 'sparclite86x', ['-mcpu=sparclite86x'])
821 cpu_flags('gcc', 'OPTIONS', 'sparc', 'f930', ['-mcpu=f930'])
822 cpu_flags('gcc', 'OPTIONS', 'sparc', 'f934', ['-mcpu=f934'])
823 cpu_flags('gcc', 'OPTIONS', 'sparc', 'sparclet', ['-mcpu=sparclet'])
824 cpu_flags('gcc', 'OPTIONS', 'sparc', 'tsc701', ['-mcpu=tsc701'])
825 cpu_flags('gcc', 'OPTIONS', 'sparc', 'v9', ['-mcpu=v9'])
826 cpu_flags('gcc', 'OPTIONS', 'sparc', 'ultrasparc', ['-mcpu=ultrasparc'])
827 cpu_flags('gcc', 'OPTIONS', 'sparc', 'ultrasparc3', ['-mcpu=ultrasparc3'])
828 # RS/6000 & PowerPC
829 flags('gcc', 'OPTIONS', ['<architecture>power/<address-model>32'], ['-m32'])
830 flags('gcc', 'OPTIONS', ['<architecture>power/<address-model>64'], ['-m64'])
831 cpu_flags('gcc', 'OPTIONS', 'power', '403', ['-mcpu=403'])
832 cpu_flags('gcc', 'OPTIONS', 'power', '505', ['-mcpu=505'])
833 cpu_flags('gcc', 'OPTIONS', 'power', '601', ['-mcpu=601'])
834 cpu_flags('gcc', 'OPTIONS', 'power', '602', ['-mcpu=602'])
835 cpu_flags('gcc', 'OPTIONS', 'power', '603', ['-mcpu=603'])
836 cpu_flags('gcc', 'OPTIONS', 'power', '603e', ['-mcpu=603e'])
837 cpu_flags('gcc', 'OPTIONS', 'power', '604', ['-mcpu=604'])
838 cpu_flags('gcc', 'OPTIONS', 'power', '604e', ['-mcpu=604e'])
839 cpu_flags('gcc', 'OPTIONS', 'power', '620', ['-mcpu=620'])
840 cpu_flags('gcc', 'OPTIONS', 'power', '630', ['-mcpu=630'])
841 cpu_flags('gcc', 'OPTIONS', 'power', '740', ['-mcpu=740'])
842 cpu_flags('gcc', 'OPTIONS', 'power', '7400', ['-mcpu=7400'])
843 cpu_flags('gcc', 'OPTIONS', 'power', '7450', ['-mcpu=7450'])
844 cpu_flags('gcc', 'OPTIONS', 'power', '750', ['-mcpu=750'])
845 cpu_flags('gcc', 'OPTIONS', 'power', '801', ['-mcpu=801'])
846 cpu_flags('gcc', 'OPTIONS', 'power', '821', ['-mcpu=821'])
847 cpu_flags('gcc', 'OPTIONS', 'power', '823', ['-mcpu=823'])
848 cpu_flags('gcc', 'OPTIONS', 'power', '860', ['-mcpu=860'])
849 cpu_flags('gcc', 'OPTIONS', 'power', '970', ['-mcpu=970'])
850 cpu_flags('gcc', 'OPTIONS', 'power', '8540', ['-mcpu=8540'])
851 cpu_flags('gcc', 'OPTIONS', 'power', 'power', ['-mcpu=power'])
852 cpu_flags('gcc', 'OPTIONS', 'power', 'power2', ['-mcpu=power2'])
853 cpu_flags('gcc', 'OPTIONS', 'power', 'power3', ['-mcpu=power3'])
854 cpu_flags('gcc', 'OPTIONS', 'power', 'power4', ['-mcpu=power4'])
855 cpu_flags('gcc', 'OPTIONS', 'power', 'power5', ['-mcpu=power5'])
856 cpu_flags('gcc', 'OPTIONS', 'power', 'powerpc', ['-mcpu=powerpc'])
857 cpu_flags('gcc', 'OPTIONS', 'power', 'powerpc64', ['-mcpu=powerpc64'])
858 cpu_flags('gcc', 'OPTIONS', 'power', 'rios', ['-mcpu=rios'])
859 cpu_flags('gcc', 'OPTIONS', 'power', 'rios1', ['-mcpu=rios1'])
860 cpu_flags('gcc', 'OPTIONS', 'power', 'rios2', ['-mcpu=rios2'])
861 cpu_flags('gcc', 'OPTIONS', 'power', 'rsc', ['-mcpu=rsc'])
862 cpu_flags('gcc', 'OPTIONS', 'power', 'rs64a', ['-mcpu=rs64'])
863 cpu_flags('gcc', 'OPTIONS', 's390x', 'z196', ['-march=z196'])
864 cpu_flags('gcc', 'OPTIONS', 's390x', 'zEC12', ['-march=zEC12'])
865 cpu_flags('gcc', 'OPTIONS', 's390x', 'z13', ['-march=z13'])
866 cpu_flags('gcc', 'OPTIONS', 's390x', 'z14', ['-march=z14'])
867 # AIX variant of RS/6000 & PowerPC
868 flags('gcc', 'OPTIONS', ['<architecture>power/<address-model>32/<target-os>aix'], ['-maix32'])
869 flags('gcc', 'OPTIONS', ['<architecture>power/<address-model>64/<target-os>aix'], ['-maix64'])
870 flags('gcc', 'AROPTIONS', ['<architecture>power/<address-model>64/<target-os>aix'], ['-X64'])