diff --git a/v2/tools/clang-darwin.jam b/v2/tools/clang-darwin.jam new file mode 100644 index 000000000..8548718e4 --- /dev/null +++ b/v2/tools/clang-darwin.jam @@ -0,0 +1,536 @@ +# Copyright 2003 Christopher Currie +# Copyright 2006 Dave Abrahams +# Copyright 2003, 2004, 2005, 2006 Vladimir Prus +# Copyright 2005-2007 Mat Marcus +# Copyright 2005-2007 Adobe Systems Incorporated +# Copyright 2007-2009 Rene Rivera +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +import feature : feature ; +import toolset : flags ; +import type ; +import common ; +import generators ; +import path : basename ; +import version ; +import property-set ; +import regex ; +import errors ; + +## Use a framework. +feature framework : : free ; + +## The MacOSX version to compile for, which maps to the SDK to use (sysroot). +feature macosx-version : : propagated link-incompatible symmetric optional ; + +## The minimal MacOSX version to target. +feature macosx-version-min : : propagated optional ; + +############################################################################# + +if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] +{ + .debug-configuration = true ; +} + +feature.extend toolset : clang-darwin ; +import clang-unix ; +feature.extend-subfeature toolset clang : platform : darwin ; + +toolset.inherit-generators clang-darwin + clang darwin + : clang-unix + : clang-unix.mingw.link clang-unix.mingw.link.dll + ; + +generators.override clang-darwin.prebuilt : builtin.prebuilt ; +generators.override clang-darwin.searched-lib-generator : searched-lib-generator ; + +# Override default do-nothing generators. +generators.override clang-darwin.compile.c.pch : pch.default-c-pch-generator ; +generators.override clang-darwin.compile.c++.pch : pch.default-cpp-pch-generator ; + +type.set-generated-target-suffix PCH : clang-darwin : gch ; + +toolset.inherit-rules clang-darwin : clang-unix : localize ; +toolset.inherit-flags clang-darwin : clang-unix + : static + arm/32 + arm/64 + arm/ + x86/32 + x86/64 + x86/ + power/32 + power/64 + power/ ; + +# Options: +# +# PATH +# Platform root path. The common autodetection will set this to +# "/Developer". And when a command is given it will be set to +# the corresponding "*.platform/Developer" directory. +# +rule init ( version ? : command * : options * : requirement * ) +{ + # First time around, figure what is host OSX version + if ! $(.host-osx-version) + { + .host-osx-version = [ MATCH "^([0-9.]+)" + : [ SHELL "/usr/bin/sw_vers -productVersion" ] ] ; + if $(.debug-configuration) + { + ECHO notice: OSX version on this machine is $(.host-osx-version) ; + } + } + + # - The root directory of the tool install. + local root = [ feature.get-values : $(options) ] ; + + # - The bin directory where to find the commands to execute. + local bin ; + + # - The configured compile driver command. + local command = [ common.get-invocation-command clang-darwin : clang++ : $(command) ] ; + + # The version as reported by the compiler + local real-version ; + + # - Autodetect the root and bin dir if not given. + if $(command) + { + bin ?= [ common.get-absolute-tool-path $(command[1]) ] ; + if $(bin) = "/usr/bin" + { + root ?= /Developer ; + } + else + { + local r = $(bin:D) ; + r = $(r:D) ; + root ?= $(r) ; + } + } + + # - Autodetect the version if not given. + if $(command) + { + # - The 'command' variable can have multiple elements. When calling + # the SHELL builtin we need a single string. + local command-string = $(command:J=" ") ; + real-version = [ MATCH "^([0-9.]+)" + : [ SHELL "$(command-string) -dumpversion" ] ] ; + version ?= $(real-version) ; + } + + .real-version.$(version) = $(real-version) ; + + # - Define the condition for this toolset instance. + local condition = + [ common.check-init-parameters clang-darwin $(requirement) : version $(version) ] ; + + # - Set the toolset generic common options. + common.handle-options clang-darwin : $(condition) : $(command) : $(options) ; + + # - Set the link flags common with the clang-unix toolset. + clang-unix.init-link-flags clang-darwin darwin $(condition) ; + + # - The symbol strip program. + local strip ; + if in $(options) + { + # We can turn off strip by specifying it as empty. In which + # case we switch to using the linker to do the strip. + flags clang-darwin.link.dll OPTIONS + $(condition)/LIB/shared/32/on : -Wl,-x ; + flags clang-darwin.link.dll OPTIONS + $(condition)/LIB/shared//on : -Wl,-x ; + flags clang-darwin.link OPTIONS + $(condition)/EXE/32/on : -s ; + flags clang-darwin.link OPTIONS + $(condition)/EXE//on : -s ; + } + else + { + # Otherwise we need to find a strip program to use. And hence + # also tell the link action that we need to use a strip + # post-process. + flags clang-darwin.link NEED_STRIP $(condition)/on : "" ; + strip = + [ common.get-invocation-command clang-darwin + : strip : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; + flags clang-darwin.link .STRIP $(condition) : $(strip[1]) ; + if $(.debug-configuration) + { + ECHO notice: using strip for $(condition) at $(strip[1]) ; + } + } + + # - The archive builder (libtool is the default as creating + # archives in darwin is complicated. + local archiver = + [ common.get-invocation-command clang-darwin + : libtool : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; + flags clang-darwin.archive .LIBTOOL $(condition) : $(archiver[1]) ; + if $(.debug-configuration) + { + ECHO notice: using archiver for $(condition) at $(archiver[1]) ; + } + + # - Initialize the SDKs available in the root for this tool. + local sdks = [ init-available-sdk-versions $(condition) : $(root) ] ; + + #~ ECHO --- ; + #~ ECHO --- bin :: $(bin) ; + #~ ECHO --- root :: $(root) ; + #~ ECHO --- version :: $(version) ; + #~ ECHO --- condition :: $(condition) ; + #~ ECHO --- strip :: $(strip) ; + #~ ECHO --- archiver :: $(archiver) ; + #~ ECHO --- sdks :: $(sdks) ; + #~ ECHO --- ; + #~ EXIT ; +} + +# Add and set options for a discovered SDK version. +local rule init-sdk ( condition * : root ? : version + : version-feature ? ) +{ + local rule version-to-feature ( version + ) + { + switch $(version[1]) + { + case iphone* : + { + return $(version[1])-$(version[2-]:J=.) ; + } + case mac* : + { + return $(version[2-]:J=.) ; + } + case * : + { + return $(version:J=.) ; + } + } + } + + if $(version-feature) + { + if $(.debug-configuration) + { + ECHO notice: available sdk for $(condition)/$(version-feature) at $(sdk) ; + } + + # Add the version to the features for specifying them. + if ! $(version-feature) in [ feature.values macosx-version ] + { + feature.extend macosx-version : $(version-feature) ; + } + if ! $(version-feature) in [ feature.values macosx-version-min ] + { + feature.extend macosx-version-min : $(version-feature) ; + } + + # Set the flags the version needs to compile with, first + # generic options. + flags clang-darwin.compile OPTIONS $(condition)/$(version-feature) + : -isysroot $(sdk) ; + flags clang-darwin.link OPTIONS $(condition)/$(version-feature) + : -isysroot $(sdk) ; + + # Then device variation options. + switch $(version[1]) + { + case iphone* : + { + flags clang-darwin.compile OPTIONS $(version-feature) + : -miphoneos-version-min=$(version[2-]:J=.) ; + flags clang-darwin.link OPTIONS $(version-feature) + : -miphoneos-version-min=$(version[2-]:J=.) ; + } + + case mac* : + { + flags clang-darwin.compile OPTIONS $(version-feature) + : -miphoneos-version-min=$(version[2-]:J=.) ; + flags clang-darwin.link OPTIONS $(version-feature) + : -miphoneos-version-min=$(version[2-]:J=.) ; + } + } + + return $(version-feature) ; + } + else if $(version[4]) + { + # We have a patch version of an SDK. We want to set up + # both the specific patch version, and the minor version. + # So we recurse to set up the minor version. Plus the minor version. + return + [ init-sdk $(condition) : $(root) + : $(version[1-3]) : [ version-to-feature $(version[1-3]) ] ] + [ init-sdk $(condition) : $(root) + : $(version) : [ version-to-feature $(version) ] ] ; + } + else + { + # Yes, this is intentionally recursive. + return + [ init-sdk $(condition) : $(root) + : $(version) : [ version-to-feature $(version) ] ] ; + } +} + +# Determine the MacOSX SDK versions installed and their locations. +local rule init-available-sdk-versions ( condition * : root ? ) +{ + root ?= /Developer ; + local sdks-root = $(root)/SDKs ; + local sdks = [ GLOB $(sdks-root) : MacOSX*.sdk iPhoneOS*.sdk iPhoneSimulator*.sdk ] ; + local result ; + for local sdk in $(sdks) + { + local sdk-match = [ MATCH ([^0-9]+)([0-9]+)[.]([0-9x]+)[.]?([0-9x]+)? : $(sdk:D=) ] ; + local sdk-platform = $(sdk-match[1]:L) ; + local sdk-version = $(sdk-match[2-]) ; + if $(sdk-version) + { + switch $(sdk-platform) + { + case macosx : + { + sdk-version = mac $(sdk-version) ; + } + case iphoneos : + { + sdk-version = iphone $(sdk-version) ; + } + case iphonesimulator : + { + sdk-version = iphonesim $(sdk-version) ; + } + case * : + { + sdk-version = $(sdk-version:J=-) ; + } + } + result += [ init-sdk $(condition) : $(sdk) : $(sdk-version) ] ; + } + } + return $(result) ; +} + +# Generic options. +flags clang-darwin.compile OPTIONS ; + +# The following adds objective-c support to clang-darwin. +# Thanks to http://thread.gmane.org/gmane.comp.lib.boost.build/13759 + +generators.register-c-compiler clang-darwin.compile.m : OBJECTIVE_C : OBJ : clang-darwin ; +generators.register-c-compiler clang-darwin.compile.mm : OBJECTIVE_CPP : OBJ : clang-darwin ; + +rule setup-address-model ( targets * : sources * : properties * ) +{ + local ps = [ property-set.create $(properties) ] ; + local arch = [ $(ps).get ] ; + local address-model = [ $(ps).get ] ; + local osx-version = [ $(ps).get ] ; + local clang-unix-version = [ $(ps).get ] ; + clang-unix-version = $(.real-version.$(clang-unix-version)) ; + local options ; + + local support-ppc64 = 1 ; + + osx-version ?= $(.host-osx-version) ; + + switch $(osx-version) + { + case iphone* : + { + support-ppc64 = ; + } + + case * : + if $(osx-version) && ! [ version.version-less [ regex.split $(osx-version) \\. ] : 10 6 ] + { + # When targeting 10.6: + # - clang-unix 4.2 will give a compiler errir if ppc64 compilation is requested + # - clang-unix 4.0 will compile fine, somehow, but then fail at link time + support-ppc64 = ; + } + } + switch $(arch) + { + case combined : + { + if $(address-model) = 32_64 { + if $(support-ppc64) { + options = -arch i386 -arch ppc -arch x86_64 -arch ppc64 ; + } else { + # Build 3-way binary + options = -arch i386 -arch ppc -arch x86_64 ; + } + } else if $(address-model) = 64 { + if $(support-ppc64) { + options = -arch x86_64 -arch ppc64 ; + } else { + errors.user-error "64-bit PPC compilation is not supported when targeting OSX 10.6 or later" ; + } + } else { + options = -arch i386 -arch ppc ; + } + } + + case x86 : + { + if $(address-model) = 32_64 { + options = -arch i386 -arch x86_64 ; + } else if $(address-model) = 64 { + options = -arch x86_64 ; + } else { + options = -arch i386 ; + } + } + + case power : + { + if ! $(support-ppc64) + && ( $(address-model) = 32_64 || $(address-model) = 64 ) + { + errors.user-error "64-bit PPC compilation is not supported when targeting OSX 10.6 or later" ; + } + + if $(address-model) = 32_64 { + options = -arch ppc -arch ppc64 ; + } else if $(address-model) = 64 { + options = -arch ppc64 ; + } else { + options = -arch ppc ; + } + } + + case arm : + { + options = -arch armv6 ; + } + } + + if $(options) + { + OPTIONS on $(targets) += $(options) ; + } +} + +rule setup-threading ( targets * : sources * : properties * ) +{ + clang-unix.setup-threading $(targets) : $(sources) : $(properties) ; +} + +rule setup-fpic ( targets * : sources * : properties * ) +{ + clang-unix.setup-fpic $(targets) : $(sources) : $(properties) ; +} + +rule compile.m ( targets * : sources * : properties * ) +{ + LANG on $(<) = "-x objective-c" ; + clang-unix.setup-fpic $(targets) : $(sources) : $(properties) ; + setup-address-model $(targets) : $(sources) : $(properties) ; +} + +actions compile.m +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +rule compile.mm ( targets * : sources * : properties * ) +{ + LANG on $(<) = "-x objective-c++" ; + clang-unix.setup-fpic $(targets) : $(sources) : $(properties) ; + setup-address-model $(targets) : $(sources) : $(properties) ; +} + +actions compile.mm +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +# Set the max header padding to allow renaming of libs for installation. +flags clang-darwin.link.dll OPTIONS : -headerpad_max_install_names ; + +# To link the static runtime we need to link to all the core runtime libraries. +flags clang-darwin.link OPTIONS static + : -nodefaultlibs -shared-libgcc -lstdc++-static -lgcc_eh -lgcc -lSystem ; + +# Strip as much as possible when optimizing. +flags clang-darwin.link OPTIONS speed : -Wl,-dead_strip -no_dead_strip_inits_and_terms ; +flags clang-darwin.link OPTIONS space : -Wl,-dead_strip -no_dead_strip_inits_and_terms ; + +# Dynamic/shared linking. +flags clang-darwin.compile OPTIONS shared : -dynamic ; + +# Misc options. +flags clang-darwin.compile OPTIONS : -gdwarf-2 ; + +# Add the framework names to use. +flags clang-darwin.link FRAMEWORK ; + +# This is flag is useful for debugging the link step +# uncomment to see what libtool is doing under the hood +#~ flags clang-darwin.link.dll OPTIONS : -Wl,-v ; + +_ = " " ; + +# set up the -F option to include the paths to any frameworks used. +local rule prepare-framework-path ( target + ) +{ + # The -framework option only takes basename of the framework. + # The -F option specifies the directories where a framework + # is searched for. So, if we find feature + # with some path, we need to generate property -F option. + local framework-paths = [ on $(target) return $(FRAMEWORK:D) ] ; + + # Be sure to generate no -F if there's no path. + for local framework-path in $(framework-paths) + { + if $(framework-path) != "" + { + FRAMEWORK_PATH on $(target) += -F$(framework-path) ; + } + } +} + +rule link ( targets * : sources * : properties * ) +{ + setup-address-model $(targets) : $(sources) : $(properties) ; + prepare-framework-path $(<) ; +} + +# Note that using strip without any options was reported to result in broken +# binaries, at least on OS X 10.5.5, see: +# http://svn.boost.org/trac/boost/ticket/2347 +# So we pass -S -x. +actions link bind LIBRARIES +{ + "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS) + $(NEED_STRIP)"$(.STRIP)" $(NEED_STRIP)-S $(NEED_STRIP)-x $(NEED_STRIP)"$(<)" +} + +rule link.dll ( targets * : sources * : properties * ) +{ + setup-address-model $(targets) : $(sources) : $(properties) ; + prepare-framework-path $(<) ; +} + +actions link.dll bind LIBRARIES +{ + "$(CONFIG_COMMAND)" -dynamiclib -Wl,-single_module -install_name "$(<:B)$(<:S)" -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS) +} + +# We use libtool instead of ar to support universal binary linking +# TODO: Find a way to use the underlying tools, i.e. lipo, to do this. +actions piecemeal archive +{ + "$(.LIBTOOL)" -static -o "$(<:T)" $(ARFLAGS) "$(>:T)" +} diff --git a/v2/tools/clang-unix.jam b/v2/tools/clang-unix.jam new file mode 100644 index 000000000..5c55faf84 --- /dev/null +++ b/v2/tools/clang-unix.jam @@ -0,0 +1,990 @@ +# Copyright 2001 David Abrahams. +# Copyright 2002-2006 Rene Rivera. +# Copyright 2002-2003 Vladimir Prus. +# Copyright (c) 2005 Reece H. Dunn. +# Copyright 2006 Ilya Sokolov. +# Copyright 2007 Roland Schwarz +# Copyright 2007 Boris Gubenko. +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import "class" : new ; +import common ; +import errors ; +import feature ; +import generators ; +import os ; +import pch ; +import property ; +import property-set ; +import toolset ; +import type ; +import rc ; +import regex ; +import set ; +import unix ; + + +if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] +{ + .debug-configuration = true ; +} + + +feature.extend toolset : clang-unix ; +# feature.subfeature toolset clang : flavor : : optional ; + +toolset.inherit-generators clang-unix : unix : unix.link unix.link.dll ; +toolset.inherit-flags clang-unix : unix ; +toolset.inherit-rules clang-unix : unix ; + +generators.override clang-unix.prebuilt : builtin.prebuilt ; +generators.override clang-unix.searched-lib-generator : searched-lib-generator ; + +# Make clang-unix toolset object files use the "o" suffix on all platforms. +type.set-generated-target-suffix OBJ : clang-unix : o ; +type.set-generated-target-suffix OBJ : clang-unix windows : o ; +type.set-generated-target-suffix OBJ : clang-unix cygwin : o ; + +# Initializes the clang-unix toolset for the given version. If necessary, command may +# be used to specify where the compiler is located. The parameter 'options' is a +# space-delimited list of options, each one specified as +# option-value. Valid option names are: cxxflags, linkflags and +# linker-type. Accepted linker-type values are aix, darwin, gnu, hpux, osf or +# sun and the default value will be selected based on the current OS. +# Example: +# using clang-unix : 1.5 : : foo bar sun ; +# +rule init ( version ? : command * : options * ) +{ + # Information about the clang command... + # The command. + local command = [ common.get-invocation-command clang-unix : clang++ : $(command) ] ; + # The root directory of the tool install. + local root = [ feature.get-values : $(options) ] ; + # The bin directory where to find the command to execute. + local bin ; + # The flavor of compiler. + local flavor = [ feature.get-values : $(options) ] ; + # Autodetect the root and bin dir if not given. + if $(command) + { + bin ?= [ common.get-absolute-tool-path $(command[-1]) ] ; + root ?= $(bin:D) ; + } + # The 'command' variable can have multiple elements. When calling + # the SHELL builtin we need a single string. + local command-string = $(command:J=" ") ; + # Autodetect the version and flavor if not given. + if $(command) + { + local machine = [ MATCH "^([^ ]+)" + : [ SHELL "$(command-string) -dumpmachine" ] ] ; + version ?= [ MATCH "^([0-9.]+)" + : [ SHELL "$(command-string) -dumpversion" ] ] ; + switch $(machine:L) + { + case *mingw* : flavor ?= mingw ; + } + } + + local condition ; + if $(flavor) + { + condition = [ common.check-init-parameters clang-unix + : version $(version) + : flavor $(flavor) + ] ; + } + else + { + condition = [ common.check-init-parameters clang-unix + : version $(version) + ] ; + condition = $(condition) ; #/ ; + } + + common.handle-options clang-unix : $(condition) : $(command) : $(options) ; + + local linker = [ feature.get-values : $(options) ] ; + # The logic below should actually be keyed on + if ! $(linker) + { + if [ os.name ] = OSF + { + linker = osf ; + } + else if [ os.name ] = HPUX + { + linker = hpux ; + } + else if [ os.name ] = AIX + { + linker = aix ; + } + else if [ os.name ] = SOLARIS + { + linker = sun ; + } + else + { + linker = gnu ; + } + } + init-link-flags clang-unix $(linker) $(condition) ; + + + # If clang is installed in non-standard location, we'd need to add + # LD_LIBRARY_PATH when running programs created with it (for unit-test/run + # rules). + if $(command) + { + # On multilib 64-bit boxes, there are both 32-bit and 64-bit libraries + # and all must be added to LD_LIBRARY_PATH. The linker will pick the + # right onces. Note that we don't provide a clean way to build 32-bit + # binary with 64-bit compiler, but user can always pass -m32 manually. + local lib_path = $(root)/bin $(root)/lib $(root)/lib32 $(root)/lib64 ; + if $(.debug-configuration) + { + ECHO notice: using clang libraries :: $(condition) :: $(lib_path) ; + } + toolset.flags clang-unix.link RUN_PATH $(condition) : $(lib_path) ; + } + + # If it's not a system clang install we should adjust the various programs as + # needed to prefer using the install specific versions. This is essential + # for correct use of MinGW and for cross-compiling. + + local nl = " +" ; + + # - The archive builder. + local archiver = [ common.get-invocation-command clang-unix + : [ NORMALIZE_PATH [ MATCH "(.*)[$(nl)]+" : [ SHELL "$(command-string) -print-prog-name=ar" ] ] ] + : [ feature.get-values : $(options) ] + : $(bin) + : search-path ] ; + toolset.flags clang-unix.archive .AR $(condition) : $(archiver[1]) ; + if $(.debug-configuration) + { + ECHO notice: using clang-unix archiver :: $(condition) :: $(archiver[1]) ; + } + + # - Ranlib + local ranlib = [ common.get-invocation-command clang-unix + : [ NORMALIZE_PATH [ MATCH "(.*)[$(nl)]+" : [ SHELL "$(command-string) -print-prog-name=ranlib" ] ] ] + : [ feature.get-values : $(options) ] + : $(bin) + : search-path ] ; + toolset.flags clang-unix.archive .RANLIB $(condition) : $(ranlib[1]) ; + if $(.debug-configuration) + { + ECHO notice: using clang-unix ranlib :: $(condition) :: $(ranlib[1]) ; + } + + + # - The resource compiler. + local rc = + [ common.get-invocation-command-nodefault clang-unix + : windres : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; + local rc-type = + [ feature.get-values : $(options) ] ; + rc-type ?= windres ; + if ! $(rc) + { + # If we can't find an RC compiler we fallback to a null RC compiler that + # creates empty object files. This allows the same Jamfiles to work + # across the board. The null RC uses the assembler to create the empty + # objects, so configure that. + rc = [ common.get-invocation-command clang-unix : as : : $(bin) : search-path ] ; + rc-type = null ; + } + rc.configure $(rc) : $(condition) : $(rc-type) ; +} + +if [ os.name ] = NT +{ + # This causes single-line command invocation to not go through .bat files, + # thus avoiding command-line length limitations. + JAMSHELL = % ; +} + +generators.register-c-compiler clang-unix.compile.c++ : CPP : OBJ : clang-unix ; +generators.register-c-compiler clang-unix.compile.c : C : OBJ : clang-unix ; +generators.register-c-compiler clang-unix.compile.asm : ASM : OBJ : clang-unix ; + +# pch support + +# The compiler looks for a precompiled header in each directory just before it +# looks for the include file in that directory. The name searched for is the +# name specified in the #include directive with ".gch" suffix appended. The +# logic in clang-unix-pch-generator will make sure that BASE_PCH suffix is appended to +# full name of the header. + +type.set-generated-target-suffix PCH : clang-unix : gch ; + +# clang-specific pch generator. +class clang-unix-pch-generator : pch-generator +{ + import project ; + import property-set ; + import type ; + + rule run-pch ( project name ? : property-set : sources + ) + { + # Find the header in sources. Ignore any CPP sources. + local header ; + for local s in $(sources) + { + if [ type.is-derived [ $(s).type ] H ] + { + header = $(s) ; + } + } + + # Error handling: Base header file name should be the same as the base + # precompiled header name. + local header-name = [ $(header).name ] ; + local header-basename = $(header-name:B) ; + if $(header-basename) != $(name) + { + local location = [ $(project).project-module ] ; + errors.user-error "in" $(location)": pch target name `"$(name)"' should be the same as the base name of header file `"$(header-name)"'" ; + } + + local pch-file = [ generator.run $(project) $(name) : $(property-set) + : $(header) ] ; + + # return result of base class and pch-file property as usage-requirements + return + [ property-set.create $(pch-file) -Winvalid-pch ] + $(pch-file) + ; + } + + # Calls the base version specifying source's name as the name of the created + # target. As result, the PCH will be named whatever.hpp.gch, and not + # whatever.gch. + rule generated-targets ( sources + : property-set : project name ? ) + { + name = [ $(sources[1]).name ] ; + return [ generator.generated-targets $(sources) + : $(property-set) : $(project) $(name) ] ; + } +} + +# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The +# latter have HPP type, but HPP type is derived from H. The type of compilation +# is determined entirely by the destination type. +generators.register [ new clang-unix-pch-generator clang-unix.compile.c.pch : H : C_PCH : on clang-unix ] ; +generators.register [ new clang-unix-pch-generator clang-unix.compile.c++.pch : H : CPP_PCH : on clang-unix ] ; + +# Override default do-nothing generators. +generators.override clang-unix.compile.c.pch : pch.default-c-pch-generator ; +generators.override clang-unix.compile.c++.pch : pch.default-cpp-pch-generator ; + +toolset.flags clang-unix.compile PCH_FILE on : ; + +# Declare flags and action for compilation. +toolset.flags clang-unix.compile OPTIONS off : -O0 ; +toolset.flags clang-unix.compile OPTIONS speed : -O3 ; +toolset.flags clang-unix.compile OPTIONS space : -Os ; + +toolset.flags clang-unix.compile OPTIONS off : -fno-inline ; +toolset.flags clang-unix.compile OPTIONS on : -Wno-inline ; +toolset.flags clang-unix.compile OPTIONS full : -finline-functions -Wno-inline ; + +toolset.flags clang-unix.compile OPTIONS off : -w ; +toolset.flags clang-unix.compile OPTIONS on : -Wall ; +toolset.flags clang-unix.compile OPTIONS all : -Wall -pedantic ; +toolset.flags clang-unix.compile OPTIONS on : -Werror ; + +toolset.flags clang-unix.compile OPTIONS on : -g ; +toolset.flags clang-unix.compile OPTIONS on : -pg ; +toolset.flags clang-unix.compile OPTIONS off : -fno-rtti ; + +rule setup-fpic ( targets * : sources * : properties * ) +{ + local link = [ feature.get-values link : $(properties) ] ; + if $(link) = shared + { + local target = [ feature.get-values target-os : $(properties) ] ; + + # This logic will add -fPIC for all compilations: + # + # lib a : a.cpp b ; + # obj b : b.cpp ; + # exe c : c.cpp a d ; + # obj d : d.cpp ; + # + # This all is fine, except that 'd' will be compiled with -fPIC even though + # it is not needed, as 'd' is used only in exe. However, it is hard to + # detect where a target is going to be used. Alternatively, we can set -fPIC + # only when main target type is LIB but than 'b' would be compiled without + # -fPIC which would lead to link errors on x86-64. So, compile everything + # with -fPIC. + # + # Yet another alternative would be to create a propagated + # feature and set it when building shared libraries, but that would be hard + # to implement and would increase the target path length even more. + + # On Windows, fPIC is default, specifying -fPIC explicitly leads to + # a warning. + if $(target) != cygwin && $(target) != windows + { + OPTIONS on $(targets) += -fPIC ; + } + } +} + +rule setup-address-model ( targets * : sources * : properties * ) +{ + local model = [ feature.get-values address-model : $(properties) ] ; + if $(model) + { + local option ; + local os = [ feature.get-values target-os : $(properties) ] ; + if $(os) = aix + { + if $(model) = 32 + { + option = -maix32 ; + } + else + { + option = -maix64 ; + } + } + else + { + if $(model) = 32 + { + option = -m32 ; + } + else if $(model) = 64 + { + option = -m64 ; + } + # For darwin, the model can be 32_64. darwin.jam will handle that + # on its own. + } + OPTIONS on $(targets) += $(option) ; + } +} + + +# FIXME: this should not use os.name. +if [ os.name ] != NT && [ os.name ] != OSF && [ os.name ] != HPUX && [ os.name ] != AIX +{ + # OSF does have an option called -soname but it does not seem to work as + # expected, therefore it has been disabled. + HAVE_SONAME = "" ; + SONAME_OPTION = -h ; +} + +# HPUX, for some reason, seem to use '+h', not '-h'. +if [ os.name ] = HPUX +{ + HAVE_SONAME = "" ; + SONAME_OPTION = +h ; +} + +toolset.flags clang-unix.compile USER_OPTIONS ; +toolset.flags clang-unix.compile.c++ USER_OPTIONS ; +toolset.flags clang-unix.compile DEFINES ; +toolset.flags clang-unix.compile INCLUDES ; +toolset.flags clang-unix.compile.c++ TEMPLATE_DEPTH ; + +rule compile.c++.pch ( targets * : sources * : properties * ) +{ + setup-threading $(targets) : $(sources) : $(properties) ; + setup-fpic $(targets) : $(sources) : $(properties) ; + setup-address-model $(targets) : $(sources) : $(properties) ; +} + +actions compile.c++.pch +{ + "$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +rule compile.c.pch ( targets * : sources * : properties * ) +{ + setup-threading $(targets) : $(sources) : $(properties) ; + setup-fpic $(targets) : $(sources) : $(properties) ; + setup-address-model $(targets) : $(sources) : $(properties) ; +} + +actions compile.c.pch +{ + "$(CONFIG_COMMAND)" -x c-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +rule compile.c++ ( targets * : sources * : properties * ) +{ + setup-threading $(targets) : $(sources) : $(properties) ; + setup-fpic $(targets) : $(sources) : $(properties) ; + setup-address-model $(targets) : $(sources) : $(properties) ; + + # Some extensions are compiled as C++ by default. For others, we need to + # pass -x c++. We could always pass -x c++ but distcc does not work with it. + if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C + { + LANG on $(<) = "-x c++" ; + } + DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; + + # Here we want to raise the template-depth parameter value to something + # higher than the default value of 17. Note that we could do this using the + # feature.set-default rule but we do not want to set the default value for + # all toolsets as well. + # + # TODO: This 'modified default' has been inherited from some 'older Boost + # Build implementation' and has most likely been added to make some Boost + # library parts compile correctly. We should see what exactly prompted this + # and whether we can get around the problem more locally. + local template-depth = [ on $(<) return $(TEMPLATE_DEPTH) ] ; + if ! $(template-depth) + { + TEMPLATE_DEPTH on $(<) = 128 ; + } +} + +rule compile.c ( targets * : sources * : properties * ) +{ + setup-threading $(targets) : $(sources) : $(properties) ; + setup-fpic $(targets) : $(sources) : $(properties) ; + setup-address-model $(targets) : $(sources) : $(properties) ; + + # If we use the name clang++ then default file suffix -> language mapping does + # not work. So have to pass -x option. Maybe, we can work around this by + # allowing the user to specify both C and C++ compiler names. + #if $(>:S) != .c + #{ + LANG on $(<) = "-x c" ; + #} + DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; +} + +actions compile.c++ bind PCH_FILE +{ + "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<:W)" "$(>:W)" +} + +actions compile.c bind PCH_FILE +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +rule compile.asm +{ + LANG on $(<) = "-x assembler-with-cpp" ; +} + +actions compile.asm +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +# The class which check that we don't try to use the static +# property while creating or using shared library, since it's not supported by +# clang/libc. +class clang-unix-linking-generator : unix-linking-generator +{ + rule run ( project name ? : property-set : sources + ) + { + # TODO: Replace this with the use of a target-os property. + local no-static-link = ; + if [ modules.peek : UNIX ] + { + switch [ modules.peek : JAMUNAME ] + { + case * : no-static-link = true ; + } + } + + local properties = [ $(property-set).raw ] ; + local reason ; + if $(no-static-link) && static in $(properties) + { + if shared in $(properties) + { + reason = + "On clang, DLL can't be build with 'static'." ; + } + else if [ type.is-derived $(self.target-types[1]) EXE ] + { + for local s in $(sources) + { + local type = [ $(s).type ] ; + if $(type) && [ type.is-derived $(type) SHARED_LIB ] + { + reason = + "On clang, using DLLS together with the" + "static options is not possible " ; + } + } + } + } + if $(reason) + { + ECHO warning: + $(reason) ; + ECHO warning: + "It is suggested to use 'static' together" + "with 'static'." ; + return ; + } + else + { + local generated-targets = [ unix-linking-generator.run $(project) + $(name) : $(property-set) : $(sources) ] ; + return $(generated-targets) ; + } + } +} + +# The set of permissible input types is different on mingw. +# So, define two sets of generators, with mingw generators +# selected when target-os=windows. + +local g ; +g = [ new clang-unix-linking-generator clang-unix.mingw.link + : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB + : EXE + : clang-unix windows ] ; +$(g).set-rule-name clang-unix.link ; +generators.register $(g) ; + +g = [ new clang-unix-linking-generator clang-unix.mingw.link.dll + : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB + : IMPORT_LIB SHARED_LIB + : clang-unix windows ] ; +$(g).set-rule-name clang-unix.link.dll ; +generators.register $(g) ; + +generators.register + [ new clang-unix-linking-generator clang-unix.link + : LIB OBJ + : EXE + : clang-unix ] ; +generators.register + [ new clang-unix-linking-generator clang-unix.link.dll + : LIB OBJ + : SHARED_LIB + : clang-unix ] ; + +generators.override clang-unix.mingw.link : clang-unix.link ; +generators.override clang-unix.mingw.link.dll : clang-unix.link.dll ; + +# Cygwin is similar to msvc and mingw in that it uses import libraries. +# While in simple cases, it can directly link to a shared library, +# it is believed to be slower, and not always possible. Define cygwin-specific +# generators here. + +g = [ new clang-unix-linking-generator clang-unix.cygwin.link + : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB + : EXE + : clang-unix cygwin ] ; +$(g).set-rule-name clang-unix.link ; +generators.register $(g) ; + +g = [ new clang-unix-linking-generator clang-unix.cygwin.link.dll + : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB + : IMPORT_LIB SHARED_LIB + : clang-unix cygwin ] ; +$(g).set-rule-name clang-unix.link.dll ; +generators.register $(g) ; + +generators.override clang-unix.cygwin.link : clang-unix.link ; +generators.override clang-unix.cygwin.link.dll : clang-unix.link.dll ; + +# Declare flags for linking. +# First, the common flags. +toolset.flags clang-unix.link OPTIONS on : -g ; +toolset.flags clang-unix.link OPTIONS on : -pg ; +toolset.flags clang-unix.link USER_OPTIONS ; +toolset.flags clang-unix.link LINKPATH ; +toolset.flags clang-unix.link FINDLIBS-ST ; +toolset.flags clang-unix.link FINDLIBS-SA ; +toolset.flags clang-unix.link LIBRARIES ; + +toolset.flags clang-unix.link.dll .IMPLIB-COMMAND windows : "-Wl,--out-implib," ; +toolset.flags clang-unix.link.dll .IMPLIB-COMMAND cygwin : "-Wl,--out-implib," ; + +# For static we made sure there are no dynamic libraries in the +# link. On HP-UX not all system libraries exist as archived libraries (for +# example, there is no libunwind.a), so, on this platform, the -static option +# cannot be specified. +if [ os.name ] != HPUX +{ + toolset.flags clang-unix.link OPTIONS static : -static ; +} + +# Now, the vendor specific flags. +# The parameter linker can be either aix, darwin, gnu, hpux, osf or sun. +rule init-link-flags ( toolset linker condition ) +{ + switch $(linker) + { + case aix : + { + # + # On AIX we *have* to use the native linker. + # + # Using -brtl, the AIX linker will look for libraries with both the .a + # and .so extensions, such as libfoo.a and libfoo.so. Without -brtl, the + # AIX linker looks only for libfoo.a. Note that libfoo.a is an archived + # file that may contain shared objects and is different from static libs + # as on Linux. + # + # The -bnoipath strips the prepending (relative) path of libraries from + # the loader section in the target library or executable. Hence, during + # load-time LIBPATH (identical to LD_LIBRARY_PATH) or a hard-coded + # -blibpath (*similar* to -lrpath/-lrpath-link) is searched. Without + # this option, the prepending (relative) path + library name is + # hard-coded in the loader section, causing *only* this path to be + # searched during load-time. Note that the AIX linker does not have an + # -soname equivalent, this is as close as it gets. + # + # The above options are definately for AIX 5.x, and most likely also for + # AIX 4.x and AIX 6.x. For details about the AIX linker see: + # http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf + # + + toolset.flags $(toolset).link OPTIONS : -Wl,-brtl -Wl,-bnoipath + : unchecked ; + } + + case darwin : + { + # On Darwin, the -s option to ld does not work unless we pass -static, + # and passing -static unconditionally is a bad idea. So, don't pass -s. + # at all, darwin.jam will use separate 'strip' invocation. + toolset.flags $(toolset).link RPATH $(condition) : : unchecked ; + toolset.flags $(toolset).link RPATH_LINK $(condition) : : unchecked ; + } + + case gnu : + { + # Strip the binary when no debugging is needed. We use --strip-all flag + # as opposed to -s since icc (intel's compiler) is generally + # option-compatible with and inherits from the clang toolset, but does not + # support -s. + toolset.flags $(toolset).link OPTIONS $(condition)/on : -Wl,--strip-all : unchecked ; + toolset.flags $(toolset).link RPATH $(condition) : : unchecked ; + toolset.flags $(toolset).link RPATH_LINK $(condition) : : unchecked ; + toolset.flags $(toolset).link START-GROUP $(condition) : -Wl,--start-group : unchecked ; + toolset.flags $(toolset).link END-GROUP $(condition) : -Wl,--end-group : unchecked ; + + # gnu ld has the ability to change the search behaviour for libraries + # referenced by -l switch. These modifiers are -Bstatic and -Bdynamic + # and change search for -l switches that follow them. The following list + # shows the tried variants. + # The search stops at the first variant that has a match. + # *nix: -Bstatic -lxxx + # libxxx.a + # + # *nix: -Bdynamic -lxxx + # libxxx.so + # libxxx.a + # + # windows (mingw,cygwin) -Bstatic -lxxx + # libxxx.a + # xxx.lib + # + # windows (mingw,cygwin) -Bdynamic -lxxx + # libxxx.dll.a + # xxx.dll.a + # libxxx.a + # xxx.lib + # cygxxx.dll (*) + # libxxx.dll + # xxx.dll + # libxxx.a + # + # (*) This is for cygwin + # Please note that -Bstatic and -Bdynamic are not a guarantee that a + # static or dynamic lib indeed gets linked in. The switches only change + # search patterns! + + # On *nix mixing shared libs with static runtime is not a good idea. + toolset.flags $(toolset).link FINDLIBS-ST-PFX $(condition)/shared + : -Wl,-Bstatic : unchecked ; + toolset.flags $(toolset).link FINDLIBS-SA-PFX $(condition)/shared + : -Wl,-Bdynamic : unchecked ; + + # On windows allow mixing of static and dynamic libs with static + # runtime. + toolset.flags $(toolset).link FINDLIBS-ST-PFX $(condition)/static/windows + : -Wl,-Bstatic : unchecked ; + toolset.flags $(toolset).link FINDLIBS-SA-PFX $(condition)/static/windows + : -Wl,-Bdynamic : unchecked ; + toolset.flags $(toolset).link OPTIONS $(condition)/static/windows + : -Wl,-Bstatic : unchecked ; + } + + case hpux : + { + toolset.flags $(toolset).link OPTIONS $(condition)/on + : -Wl,-s : unchecked ; + toolset.flags $(toolset).link OPTIONS $(condition)/shared + : -fPIC : unchecked ; + } + + case osf : + { + # No --strip-all, just -s. + toolset.flags $(toolset).link OPTIONS $(condition)/on + : -Wl,-s : unchecked ; + toolset.flags $(toolset).link RPATH $(condition) : + : unchecked ; + # This does not supports -R. + toolset.flags $(toolset).link RPATH_OPTION $(condition) : -rpath + : unchecked ; + # -rpath-link is not supported at all. + } + + case sun : + { + toolset.flags $(toolset).link OPTIONS $(condition)/on + : -Wl,-s : unchecked ; + toolset.flags $(toolset).link RPATH $(condition) : + : unchecked ; + # Solaris linker does not have a separate -rpath-link, but allows to use + # -L for the same purpose. + toolset.flags $(toolset).link LINKPATH $(condition) : + : unchecked ; + + # This permits shared libraries with non-PIC code on Solaris. + # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the + # following is not needed. Whether -fPIC should be hardcoded, is a + # separate question. + # AH, 2004/10/16: it is still necessary because some tests link against + # static libraries that were compiled without PIC. + toolset.flags $(toolset).link OPTIONS $(condition)/shared + : -mimpure-text : unchecked ; + } + + case * : + { + errors.user-error + "$(toolset) initialization: invalid linker '$(linker)'" : + "The value '$(linker)' specified for is not recognized." : + "Possible values are 'aix', 'darwin', 'gnu', 'hpux', 'osf' or 'sun'" ; + } + } +} + +# Enclose the RPATH variable on 'targets' in (double) quotes, +# unless it's already enclosed in single quotes. +# This special casing is done because it's common to pass +# '$ORIGIN' to linker -- and it has to have single quotes +# to prevent expansion by shell -- and if we add double +# quotes then preventing properties of single quotes disappear. +rule quote-rpath ( targets * ) +{ + local r = [ on $(targets[1]) return $(RPATH) ] ; + if ! [ MATCH "('.*')" : $(r) ] + { + r = "\"$(r)\"" ; + } + RPATH on $(targets) = $(r) ; +} + +# Declare actions for linking. +rule link ( targets * : sources * : properties * ) +{ + setup-threading $(targets) : $(sources) : $(properties) ; + setup-address-model $(targets) : $(sources) : $(properties) ; + SPACE on $(targets) = " " ; + # Serialize execution of the 'link' action, since running N links in + # parallel is just slower. For now, serialize only clang links, it might be a + # good idea to serialize all links. + JAM_SEMAPHORE on $(targets) = clang-unix-link-semaphore ; + quote-rpath $(targets) ; +} + +actions link bind LIBRARIES +{ + "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) + +} + +# Default value. Mostly for the sake of intel-linux that inherits from clang, but +# does not have the same logic to set the .AR variable. We can put the same +# logic in intel-linux, but that's hardly worth the trouble as on Linux, 'ar' is +# always available. +.AR = ar ; +.RANLIB = ranlib ; + +toolset.flags clang-unix.archive AROPTIONS ; + +rule archive ( targets * : sources * : properties * ) +{ + # Always remove archive and start again. Here is the rationale from + # + # Andre Hentz: + # + # I had a file, say a1.c, that was included into liba.a. I moved a1.c to + # a2.c, updated my Jamfiles and rebuilt. My program was crashing with absurd + # errors. After some debugging I traced it back to the fact that a1.o was + # *still* in liba.a + # + # Rene Rivera: + # + # Originally removing the archive was done by splicing an RM onto the + # archive action. That makes archives fail to build on NT when they have + # many files because it will no longer execute the action directly and blow + # the line length limit. Instead we remove the file in a different action, + # just before building the archive. + # + local clean.a = $(targets[1])(clean) ; + TEMPORARY $(clean.a) ; + NOCARE $(clean.a) ; + LOCATE on $(clean.a) = [ on $(targets[1]) return $(LOCATE) ] ; + DEPENDS $(clean.a) : $(sources) ; + DEPENDS $(targets) : $(clean.a) ; + common.RmTemps $(clean.a) : $(targets) ; +} + +# Declare action for creating static libraries. +# The letter 'r' means to add files to the archive with replacement. Since we +# remove archive, we don't care about replacement, but there's no option "add +# without replacement". +# The letter 'c' suppresses the warning in case the archive does not exists yet. +# That warning is produced only on some platforms, for whatever reasons. +actions piecemeal archive +{ + "$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)" + "$(.RANLIB)" "$(<)" +} + +rule link.dll ( targets * : sources * : properties * ) +{ + setup-threading $(targets) : $(sources) : $(properties) ; + setup-address-model $(targets) : $(sources) : $(properties) ; + SPACE on $(targets) = " " ; + JAM_SEMAPHORE on $(targets) = clang-unix-link-semaphore ; + quote-rpath $(targets) ; +} + +# Differs from 'link' above only by -shared. +actions link.dll bind LIBRARIES +{ + "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) +} + +rule setup-threading ( targets * : sources * : properties * ) +{ + local threading = [ feature.get-values threading : $(properties) ] ; + if $(threading) = multi + { + local target = [ feature.get-values target-os : $(properties) ] ; + local option ; + local libs ; + + switch $(target) + { + case windows : + { + option = -mthreads ; + } + case cygwin : + { + option = -mthreads ; + } + case solaris : + { + option = -pthreads ; + libs = rt ; + } + case beos : + { + # BeOS has no threading options, so do not set anything here. + } + case *bsd : + { + option = -pthread ; + # There is no -lrt on BSD. + } + case sgi : + { + # clang on IRIX does not support multi-threading so do not set anything + # here. + } + case darwin : + { + # Darwin has no threading options so do not set anything here. + } + case * : + { + option = -pthread ; + libs = rt ; + } + } + + if $(option) + { + OPTIONS on $(targets) += $(option) ; + } + if $(libs) + { + FINDLIBS-SA on $(targets) += $(libs) ; + } + } +} + +local rule cpu-flags ( toolset variable : architecture : instruction-set + : values + : default ? ) +{ + if $(default) + { + toolset.flags $(toolset) $(variable) + $(architecture)/ + : $(values) ; + } + toolset.flags $(toolset) $(variable) + /$(instruction-set) + $(architecture)/$(instruction-set) + : $(values) ; +} + +# Set architecture/instruction-set options. +# +# x86 and compatible +cpu-flags clang-unix OPTIONS : x86 : native : -march=native : default ; +cpu-flags clang-unix OPTIONS : x86 : i386 : -march=i386 ; +cpu-flags clang-unix OPTIONS : x86 : i486 : -march=i486 ; +cpu-flags clang-unix OPTIONS : x86 : i586 : -march=i586 ; +cpu-flags clang-unix OPTIONS : x86 : i686 : -march=i686 ; +cpu-flags clang-unix OPTIONS : x86 : pentium : -march=pentium ; +cpu-flags clang-unix OPTIONS : x86 : pentium-mmx : -march=pentium-mmx ; +cpu-flags clang-unix OPTIONS : x86 : pentiumpro : -march=pentiumpro ; +cpu-flags clang-unix OPTIONS : x86 : pentium2 : -march=pentium2 ; +cpu-flags clang-unix OPTIONS : x86 : pentium3 : -march=pentium3 ; +cpu-flags clang-unix OPTIONS : x86 : pentium3m : -march=pentium3m ; +cpu-flags clang-unix OPTIONS : x86 : pentium-m : -march=pentium-m ; +cpu-flags clang-unix OPTIONS : x86 : pentium4 : -march=pentium4 ; +cpu-flags clang-unix OPTIONS : x86 : pentium4m : -march=pentium4m ; +cpu-flags clang-unix OPTIONS : x86 : prescott : -march=prescott ; +cpu-flags clang-unix OPTIONS : x86 : nocona : -march=nocona ; +cpu-flags clang-unix OPTIONS : x86 : core2 : -march=core2 ; +cpu-flags clang-unix OPTIONS : x86 : k6 : -march=k6 ; +cpu-flags clang-unix OPTIONS : x86 : k6-2 : -march=k6-2 ; +cpu-flags clang-unix OPTIONS : x86 : k6-3 : -march=k6-3 ; +cpu-flags clang-unix OPTIONS : x86 : athlon : -march=athlon ; +cpu-flags clang-unix OPTIONS : x86 : athlon-tbird : -march=athlon-tbird ; +cpu-flags clang-unix OPTIONS : x86 : athlon-4 : -march=athlon-4 ; +cpu-flags clang-unix OPTIONS : x86 : athlon-xp : -march=athlon-xp ; +cpu-flags clang-unix OPTIONS : x86 : athlon-mp : -march=athlon-mp ; +## +cpu-flags clang-unix OPTIONS : x86 : k8 : -march=k8 ; +cpu-flags clang-unix OPTIONS : x86 : opteron : -march=opteron ; +cpu-flags clang-unix OPTIONS : x86 : athlon64 : -march=athlon64 ; +cpu-flags clang-unix OPTIONS : x86 : athlon-fx : -march=athlon-fx ; +cpu-flags clang-unix OPTIONS : x86 : winchip-c6 : -march=winchip-c6 ; +cpu-flags clang-unix OPTIONS : x86 : winchip2 : -march=winchip2 ; +cpu-flags clang-unix OPTIONS : x86 : c3 : -march=c3 ; +cpu-flags clang-unix OPTIONS : x86 : c3-2 : -march=c3-2 ; + diff --git a/v2/tools/clang.jam b/v2/tools/clang.jam new file mode 100644 index 000000000..818ba8778 --- /dev/null +++ b/v2/tools/clang.jam @@ -0,0 +1,27 @@ +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt +# or copy at http://www.boost.org/LICENSE_1_0.txt) + +# This is a generic 'clang' toolset. Depending on the current system, it +# forwards either to 'clang-unix' or 'clang-darwin' modules. + +import feature ; +import os ; +import toolset ; + +feature.extend toolset : clang ; +feature.subfeature toolset clang : platform : : propagated link-incompatible ; + +rule init ( * : * ) +{ + if [ os.name ] = MACOSX + { + toolset.using clang-darwin : + $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; + } + else + { + toolset.using clang-unix : + $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; + } +} diff --git a/v2/tools/common.jam b/v2/tools/common.jam index 05cd392d2..f56b9d00e 100644 --- a/v2/tools/common.jam +++ b/v2/tools/common.jam @@ -825,6 +825,8 @@ local rule toolset-tag ( name : type ? : property-set ) switch [ $(property-set).get ] { case borland* : tag += bcb ; + case clang-unix* : tag += gcc ; + case clang-darwin* : tag += xgcc ; case como* : tag += como ; case cw : tag += cw ; case darwin* : tag += xgcc ;