diff options
Diffstat (limited to 'tools/build/src')
45 files changed, 584 insertions, 110 deletions
diff --git a/tools/build/src/build/feature.jam b/tools/build/src/build/feature.jam index ee6abc591..e58edcbed 100644 --- a/tools/build/src/build/feature.jam +++ b/tools/build/src/build/feature.jam @@ -30,6 +30,7 @@ local rule setup ( ) link-incompatible subfeature order-sensitive + hidden ; .all-features = ; diff --git a/tools/build/src/build/feature.py b/tools/build/src/build/feature.py index 386e49931..827dae340 100644 --- a/tools/build/src/build/feature.py +++ b/tools/build/src/build/feature.py @@ -196,12 +196,12 @@ def set_default (feature, value): bad_attribute = "free" elif attributes & Feature.OPTIONAL: bad_attribute = "optional" - + if bad_attribute: raise InvalidValue ("%s property %s cannot have a default" % (bad_attribute, feature.name())) - + if not value in f.values(): - raise InvalidValue ("The specified default value, '%s' is invalid.\n" % value + "allowed values are: %s" % values) + raise InvalidValue ("The specified default value, '%s' is invalid.\n" % value + "allowed values are: %s" % f.values()) f.set_default(value) diff --git a/tools/build/src/build/project.jam b/tools/build/src/build/project.jam index c9a090982..83d0377e4 100644 --- a/tools/build/src/build/project.jam +++ b/tools/build/src/build/project.jam @@ -50,7 +50,7 @@ import sequence ; # Jamfile at that location is loaded already, does nothing. Returns the project # module for the Jamfile. # -rule load ( jamfile-location ) +rule load ( jamfile-location : synthesize ? ) { local module-name = [ module-name $(jamfile-location) ] ; # If Jamfile is already loaded, do not try again. @@ -61,7 +61,7 @@ rule load ( jamfile-location ) ECHO Loading Jamfile at '$(jamfile-location)' ; } - load-jamfile $(jamfile-location) : $(module-name) ; + load-jamfile $(jamfile-location) : $(module-name) : $(synthesize) ; # We want to make sure that child project are loaded only after parent # projects. In particular, because parent projects define attributes @@ -270,14 +270,14 @@ rule find-jamfile ( # the file as indicated by the JAMFILE patterns. Effect of calling this rule # twice with the same 'dir' is undefined. # -local rule load-jamfile ( dir : jamfile-module ) +local rule load-jamfile ( dir : jamfile-module : synthesize ? ) { # See if the Jamfile is where it should be. # local jamfile-to-load = [ path.glob $(dir) : $(JAMROOT) ] ; if ! $(jamfile-to-load) { - jamfile-to-load = [ find-jamfile $(dir) ] ; + jamfile-to-load = [ find-jamfile $(dir) : $(synthesize) ] ; } if $(jamfile-to-load[2]) @@ -286,6 +286,11 @@ local rule load-jamfile ( dir : jamfile-module ) errors.error "Multiple Jamfiles found at '$(dir)'" : "Filenames are: " $(jamfile-to-load:D=) ; } + + if ! $(jamfile-to-load) && $(synthesize) + { + jamfile-to-load = $(dir)/@ ; + } # Now load the Jamfile in its own context. # The call to 'initialize' may load the parent Jamfile, which might contain @@ -307,14 +312,24 @@ local rule load-jamfile ( dir : jamfile-module ) local saved-project = $(.current-project) ; mark-as-user $(jamfile-module) ; - modules.load $(jamfile-module) : [ path.native $(jamfile-to-load) ] - : . ; - if [ MATCH ^($(JAMROOT))$ : $(jamfile-to-load:BS) ] + if $(jamfile-to-load:B) = "@" { - jamfile = [ find-jamfile $(dir) : no-errors ] ; - if $(jamfile) + # Not a real jamfile to load. Synthsize the load. + modules.poke $(jamfile-module) : __name__ : $(jamfile-module) ; + modules.poke $(jamfile-module) : __file__ : [ path.native $(jamfile-to-load) ] ; + modules.poke $(jamfile-module) : __binding__ : [ path.native $(jamfile-to-load) ] ; + } + else + { + modules.load $(jamfile-module) : [ path.native $(jamfile-to-load) ] + : . ; + if [ MATCH ^($(JAMROOT))$ : $(jamfile-to-load:BS) ] { - load-aux $(jamfile-module) : [ path.native $(jamfile) ] ; + jamfile = [ find-jamfile $(dir) : no-errors ] ; + if $(jamfile) + { + load-aux $(jamfile-module) : [ path.native $(jamfile) ] ; + } } } @@ -902,7 +917,7 @@ rule target ( project-module ) # extensions are really projects, they can be initialized as a module would be # with the "using" (project.project-rules.using) mechanism. # -rule extension ( id : options * : * ) +rule extension ( id space ? : options * : * ) { # The caller is a standalone module for the extension. local mod = [ CALLER_MODULE ] ; @@ -921,15 +936,19 @@ rule extension ( id : options * : * ) { root-project = [ project.attribute $(root-project) parent-module ] ; } + + # Default to creating extensions in /ext/.. project space. + local id = $(1[1]) ; + local space = $(1[2]) ; + space ?= ext ; # Create the project data, and bring in the project rules into the # module. project.initialize $(__name__) : [ path.join [ project.attribute - $(root-project) location ] ext $(1:L) ] ; + $(root-project) location ] $(space:L) $(id:L) ] ; - # Create the project itself, i.e. the attributes. All extensions are - # created in the "/ext" project space. - project /ext/$(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : + # Create the project itself, i.e. the attributes. + project /$(space:L)/$(id:L) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) : $(18) : $(19) ; local attributes = [ project.attributes $(__name__) ] ; diff --git a/tools/build/src/build/property.jam b/tools/build/src/build/property.jam index ff28dfd20..78a9744b1 100644 --- a/tools/build/src/build/property.jam +++ b/tools/build/src/build/property.jam @@ -237,12 +237,15 @@ rule as-path ( properties * ) local components ; for local p in $(properties) { - if $(p:G) + if ! hidden in [ feature.attributes $(p:G) ] { - local f = [ utility.ungrist $(p:G) ] ; - p = $(f)-$(p:G=) ; + if $(p:G) + { + local f = [ utility.ungrist $(p:G) ] ; + p = $(f)-$(p:G=) ; + } + components += [ $(.abbrev) $(p) ] ; } - components += [ $(.abbrev) $(p) ] ; } $(entry) = $(components:J=/) ; diff --git a/tools/build/src/build/property.py b/tools/build/src/build/property.py index dab83c7c8..f851c9e5e 100644 --- a/tools/build/src/build/property.py +++ b/tools/build/src/build/property.py @@ -1,4 +1,4 @@ -# Status: ported, except for tests and --abbreviate-paths. +# Status: ported, except for tests. # Base revision: 64070 # # Copyright 2001, 2002, 2003 Dave Abrahams @@ -8,6 +8,7 @@ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) import re +import sys from b2.util.utility import * from b2.build import feature from b2.util import sequence, qualify_jam_action @@ -25,6 +26,8 @@ __re_separate_condition_and_property = re.compile (r'(.*):(<.*)') __not_applicable_feature='not-applicable-in-this-context' feature.feature(__not_applicable_feature, [], ['free']) +__abbreviated_paths = False + class Property(object): __slots__ = ('_feature', '_value', '_condition') @@ -62,9 +65,9 @@ class Property(object): return hash((self._feature, self._value, tuple(self._condition))) def __cmp__(self, other): - return cmp((self._feature, self._value, self._condition), - (other._feature, other._value, other._condition)) - + return cmp((self._feature.name(), self._value, self._condition), + (other._feature.name(), other._value, other._condition)) + def create_from_string(s, allow_condition=False,allow_missing_value=False): @@ -130,10 +133,19 @@ def reset (): # A cache of results from as_path __results = {} - + reset () - + +def set_abbreviated_paths(on=True): + global __abbreviated_paths + __abbreviated_paths = on + + +def get_abbreviated_paths(): + return __abbreviated_paths or '--abbreviated-paths' in sys.argv + + def path_order (x, y): """ Helper for as_path, below. Orders properties with the implicit ones first, and within the two sections in alphabetical order of feature diff --git a/tools/build/src/build/property_set.py b/tools/build/src/build/property_set.py index 6b3643045..37fe46631 100644 --- a/tools/build/src/build/property_set.py +++ b/tools/build/src/build/property_set.py @@ -12,9 +12,10 @@ from b2.util.utility import * import property, feature import b2.build.feature from b2.exceptions import * +from b2.build.property import get_abbreviated_paths from b2.util.sequence import unique from b2.util.set import difference -from b2.util import cached +from b2.util import cached, abbreviate_dashed from b2.manager import get_manager @@ -41,7 +42,7 @@ def create (raw_properties = []): else: x = [property.create_from_string(ps) for ps in raw_properties] x.sort() - x = unique (x) + x = unique(x, stable=True) # FIXME: can we do better, e.g. by directly computing # hash value of the list? @@ -350,7 +351,10 @@ class PropertySet: if p.feature().implicit(): components.append(p.value()) else: - components.append(p.feature().name() + "-" + p.value()) + value = p.feature().name() + "-" + p.value() + if property.get_abbreviated_paths(): + value = abbreviate_dashed(value) + components.append(value) self.as_path_ = '/'.join (components) diff --git a/tools/build/src/build/version.py b/tools/build/src/build/version.py new file mode 100644 index 000000000..1efe3b5c5 --- /dev/null +++ b/tools/build/src/build/version.py @@ -0,0 +1,38 @@ +import os +import sys + +import bjam + + +from b2.manager import get_manager + + +MANAGER = get_manager() +ERROR_HANDLER = MANAGER.errors() + +_major = "2014" +_minor = "03" + + +def boost_build(): + return "{}.{}-svn".format(_major, _minor) + + +def verify_engine_version(): + major, minor, _ = v = bjam.variable('JAM_VERSION') + if major != _major or minor != _minor: + from textwrap import dedent + engine = sys.argv[0] + core = os.path.dirname(os.path.dirname(__file__)) + print dedent("""\ + warning: mismatched version of Boost.Build engine core + warning: Boost.Build engine "{}" is "{}" + warning: Boost.Build core at {} is {} + """.format(engine, '.'.join(v), core, boost_build())) + return False + return True + + +def report(): + if verify_engine_version(): + print "Boost.Build " + boost_build() diff --git a/tools/build/src/build/virtual-target.jam b/tools/build/src/build/virtual-target.jam index 3103c3051..264616db6 100644 --- a/tools/build/src/build/virtual-target.jam +++ b/tools/build/src/build/virtual-target.jam @@ -432,6 +432,10 @@ class abstract-file-target : virtual-target { ps = [ property-set.empty ] ; } + + # Add this target object for use in getting additional information + # when tagging. + ps = [ property-set.create [ $(ps).raw ] <target>$(__name__) ] ; local tag = [ $(ps).get <tag> ] ; @@ -1092,7 +1096,7 @@ rule register-actual-name ( actual-name : virtual-target ) errors.user-error "Name clash for '$(actual-name)'" : "" : "Tried to build the target twice, with property sets having " - : "these incompabile properties:" + : "these incompatible properties:" : "" : " - " $(properties-removed) : " - " $(properties-added) @@ -1285,7 +1289,7 @@ class subvariant # Returns the properties specifying implicit include paths to generated # headers. This traverses all targets in this subvariant and subvariants - # referred by <implicit-dependecy> properties. For all targets of type + # referred by <implicit-dependency> properties. For all targets of type # 'target-type' (or for all targets, if 'target-type' is not specified), the # result will contain <$(feature)>path-to-that-target. # diff --git a/tools/build/src/build_system.py b/tools/build/src/build_system.py index c5757c817..6bd05d1d9 100644 --- a/tools/build/src/build_system.py +++ b/tools/build/src/build_system.py @@ -455,7 +455,7 @@ def main_real(): import b2.build.configure as configure if "--version" in sys.argv: - + from b2.build import version version.report() return @@ -804,7 +804,7 @@ def main_real(): j = option.get("jobs") if j: - bjam.call("set-variable", PARALLELISM, j) + bjam.call("set-variable", 'PARALLELISM', j) k = option.get("keep-going", "true", "true") if k in ["on", "yes", "true"]: diff --git a/tools/build/src/contrib/boost.py b/tools/build/src/contrib/boost.py index e0bbcf34d..e256fe965 100644 --- a/tools/build/src/contrib/boost.py +++ b/tools/build/src/contrib/boost.py @@ -271,7 +271,7 @@ def tag_maybe(param): def tag_system(name, type, prop_set): return common.format_name(['<base>'] + tag_maybe(__build_id), name, type, prop_set) -def tag_system(name, type, prop_set): +def tag_tagged(name, type, prop_set): return common.format_name(['<base>', '<threading>', '<runtime>'] + tag_maybe(__build_id), name, type, prop_set) def tag_versioned(name, type, prop_set): diff --git a/tools/build/src/contrib/modular.jam b/tools/build/src/contrib/modular.jam new file mode 100644 index 000000000..917dfbaa5 --- /dev/null +++ b/tools/build/src/contrib/modular.jam @@ -0,0 +1,141 @@ +# Copyright Rene Rivera 2015 +# 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) + +#alias library +# : +# : : : <include>include +# ; + +import path ; +import project ; +import modules ; +import regex ; + +rule find ( target-refs + ) +{ + process-args ; + + local caller-mod = [ CALLER_MODULE ] ; + local caller-dir = [ modules.peek $(caller-mod) : __file__ ] ; + caller-dir = $(caller-dir:D) ; + caller-dir = [ path.root $(caller-dir) [ path.pwd ] ] ; + + for local target-ref in $(target-refs) + { + local ref = [ MATCH ^(.*)//.* : $(target-ref:G=) ] ; + local search-prefix ; + local search-sub ; + for local prefix in $(.search-path-prefix) + { + if ! $(search-prefix) + { + local search-match = [ MATCH ^($(prefix))/(.*)$ : $(ref) ] ; + search-prefix = $(search-match[1]) ; + search-sub = $(search-match[2]) ; + } + } + local found = [ path.glob $(.search-path.$(search-prefix)) : $(search-sub) ] ; + found = $(found[1]) ; + if $(found) + { + local lib-ref = [ regex.split $(search-sub) / ] ; + lib-ref = $(search-prefix)/$(lib-ref[1]) ; + local lib-path = [ path.relative-to $(caller-dir) $(found) ] ; + library $(lib-ref) $(caller-mod) : $(lib-path) ; + } + } + + return $(target-refs) ; +} + +rule library ( name caller-module ? : root ) +{ + process-args ; + + # Dir path of caller to base paths from. + caller-module ?= [ CALLER_MODULE ] ; + local caller-dir = [ modules.peek $(caller-module) : __file__ ] ; + caller-dir = $(caller-dir:D) ; + + # Find the various parts of the library. + local lib-dir = [ path.root [ path.root $(root) $(caller-dir) ] [ path.pwd ] ] ; + local lib-contents = [ path.glob $(lib-dir) : "include" "build" ] ; + lib-contents = $(lib-contents:D=) ; + # "include" dir for library.. + local include-dir ; + if "include" in $(lib-contents) + { + include-dir = include ; + } + + # Does it look like a library? + if $(include-dir) + { + # Load/create/declare library project. + local lib-module = [ project.find $(root) : $(caller-dir) ] ; + if ! $(lib-module) + { + lib-module = [ project.load + [ path.root [ path.make $(root) ] $(caller-dir) ] : synthesize ] ; + } + local lib-target = [ project.target $(lib-module) ] ; + + # We move to the library project module to define the various + # targets others use for the library. + if ! [ modules.peek $(lib-module) : __library__ ] + { + modules.poke $(lib-module) : __library__ : $(name) ; + project.push-current $(lib-target) ; + + # Declare the library alias. + modules.call-in $(lib-module) : alias library + : # Sources + : # Requirements + : # Default Build + : # Usage Requirements + <include>$(include-dir) + ; + + project.pop-current ; + } + + # Declare project alternate ID. + modules.call-in $(caller-module) : use-project $(name) : $(root) ; + } +} + +# Add a location, i.e. directory, where to search for libraries. +# The optional 'prefix' indicates which rooted-prefixes the new +# search dir applies to. The prefix defaults to '/'. +rule add-location ( dir prefix ? : base-dir ? ) +{ + process-args ; + + prefix ?= "/" ; + + # Dir path of caller to base paths from. + caller-module ?= [ CALLER_MODULE ] ; + local caller-dir = [ modules.peek $(caller-module) : __file__ ] ; + caller-dir = $(caller-dir:D) ; + + base-dir ?= $(caller-dir) ; + + .search-path-prefix += $(prefix) ; + .search-path.$(prefix) += [ path.root [ path.root $(dir) $(base-dir) ] [ path.pwd ] ] ; +} + +local rule process-args ( ) +{ + if ! $(.did-process-args) + { + .did-process-args = yes ; + local argv = [ modules.peek : ARGV ] ; + local dirs = [ MATCH ^--modular-search-dir=(.*)$ : $(argv) ] ; + for local dir in $(dirs) + { + add-location $(dir) : [ path.pwd ] ; + } + } +} diff --git a/tools/build/src/engine/Jambase b/tools/build/src/engine/Jambase index 94f8fbde5..6e7b7a2be 100644 --- a/tools/build/src/engine/Jambase +++ b/tools/build/src/engine/Jambase @@ -855,6 +855,18 @@ else if $(OS) = BEOS NOARSCAN ?= true ; STDHDRS ?= /boot/develop/headers/posix ; } +else if $(OS) = HAIKU +{ + BINDIR ?= /boot/system/non-packaged/bin ; + CC ?= gcc ; + C++ ?= $(CC) ; + FORTRAN ?= "" ; + LIBDIR ?= /boot/system/non-packaged/lib ; + LINK ?= gcc ; + LINKLIBS ?= -lnetwork ; + NOARSCAN ?= true ; + STDHDRS ?= /boot/system/develop/headers/posix ; +} else if $(UNIX) { switch $(OS) diff --git a/tools/build/src/engine/boehm_gc/dyn_load.c b/tools/build/src/engine/boehm_gc/dyn_load.c index 36968ba5d..eed9253e3 100644 --- a/tools/build/src/engine/boehm_gc/dyn_load.c +++ b/tools/build/src/engine/boehm_gc/dyn_load.c @@ -64,7 +64,7 @@ static int (*GC_has_static_roots)(const char *, void *, size_t); !defined(AIX) && !defined(SCO_ELF) && !defined(DGUX) && \ !(defined(FREEBSD) && defined(__ELF__)) && \ !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \ - !defined(DARWIN) && !defined(CYGWIN32) + !defined(DARWIN) && !defined(CYGWIN32) && !defined(HAIKU) --> We only know how to find data segments of dynamic libraries for the --> above. Additional SVR4 variants might not be too --> hard to add. @@ -82,6 +82,10 @@ static int (*GC_has_static_roots)(const char *, void *, size_t); # define ELFSIZE ARCH_ELFSIZE #endif +#if defined(HAIKU) +// purposefully empty +#endif + #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \ (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \ (defined(NETBSD) && defined(__ELF__)) || defined(HURD) @@ -216,7 +220,8 @@ void GC_register_dynamic_libraries() #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \ (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \ - (defined(NETBSD) && defined(__ELF__)) || defined(HURD) + (defined(NETBSD) && defined(__ELF__)) || defined(HURD) \ + defined(HAIKU) #ifdef USE_PROC_FOR_LIBRARIES diff --git a/tools/build/src/engine/boehm_gc/include/gc.h b/tools/build/src/engine/boehm_gc/include/gc.h index cc950888f..590a868d6 100644 --- a/tools/build/src/engine/boehm_gc/include/gc.h +++ b/tools/build/src/engine/boehm_gc/include/gc.h @@ -494,7 +494,7 @@ GC_API void * GC_malloc_atomic_ignore_off_page(size_t lb); /* of compilers. */ /* This may also be desirable if it is possible but expensive to */ /* retrieve the call chain. */ -#if (defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) \ +#if (defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) \ || defined(__FreeBSD__) || defined(__DragonFly__)) & !defined(GC_CAN_SAVE_CALL_STACKS) # define GC_ADD_CALLER # if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) diff --git a/tools/build/src/engine/boehm_gc/include/gc_config_macros.h b/tools/build/src/engine/boehm_gc/include/gc_config_macros.h index 66abf0b1e..762162a34 100644 --- a/tools/build/src/engine/boehm_gc/include/gc_config_macros.h +++ b/tools/build/src/engine/boehm_gc/include/gc_config_macros.h @@ -45,7 +45,8 @@ || defined(GC_AIX_THREADS) \ || defined(GC_LINUX_THREADS) \ || defined(GC_NETBSD_THREADS) \ - || defined(GC_GNU_THREADS)) + || defined(GC_GNU_THREADS) \ + || defined(GC_HAIKU_THREADS)) # define _REENTRANT /* Better late than never. This fails if system headers that */ /* depend on this were previously included. */ @@ -65,7 +66,7 @@ defined(GC_DGUX386_THREADS) || defined(GC_DARWIN_THREADS) || \ defined(GC_AIX_THREADS) || defined(GC_NETBSD_THREADS) || \ (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__)) || \ - defined(GC_GNU_THREADS) + defined(GC_GNU_THREADS) || defined(GC_HAIKU_THREADS) # define GC_PTHREADS # endif diff --git a/tools/build/src/engine/boehm_gc/include/private/gcconfig.h b/tools/build/src/engine/boehm_gc/include/private/gcconfig.h index 20f35bc3a..61cf9eacb 100644 --- a/tools/build/src/engine/boehm_gc/include/private/gcconfig.h +++ b/tools/build/src/engine/boehm_gc/include/private/gcconfig.h @@ -215,6 +215,10 @@ # define BEOS # define mach_type_known # endif +# if defined(__HAIKU__) && defined(_X86_) +# define I386 +# define HAIKU +# define mach_type_known # if defined(LINUX) && (defined(i386) || defined(__i386__)) # define I386 # define mach_type_known @@ -1014,6 +1018,13 @@ extern int etext[]; # define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) # endif +# ifdef HAIKU +# define OS_TYPE "HAIKU" +# include <OS.h> +# define GETPAGESIZE() B_PAGE_SIZE +# extern int etext[]; +# define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) +# endif # ifdef SOLARIS # define OS_TYPE "SOLARIS" extern int _etext[], _end[]; diff --git a/tools/build/src/engine/boehm_gc/os_dep.c b/tools/build/src/engine/boehm_gc/os_dep.c index bb8fa08f6..2dd087fbe 100644 --- a/tools/build/src/engine/boehm_gc/os_dep.c +++ b/tools/build/src/engine/boehm_gc/os_dep.c @@ -777,6 +777,17 @@ ptr_t GC_get_main_stack_base(void){ # endif /* BEOS */ +# ifdef HAIKU +# include <OS.h> +ptr_t GC_get_main_stack_base(void) +{ + thread_info th; + get_thread_info(find_thread(NULL), &th); + return th.stack_end; +} +# endif + + # ifdef OS2 ptr_t GC_get_main_stack_base(void) @@ -1097,7 +1108,7 @@ ptr_t GC_get_main_stack_base(void) #if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \ && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) \ - && !defined(CYGWIN32) + && !defined(CYGWIN32) && !defined(HAIKU) ptr_t GC_get_main_stack_base(void) { @@ -1154,7 +1165,7 @@ ptr_t GC_get_main_stack_base(void) # endif /* STACKBOTTOM */ } -# endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS */ +# endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS, !HAIKU */ #if defined(GC_LINUX_THREADS) && !defined(HAVE_GET_STACK_BASE) diff --git a/tools/build/src/engine/build.bat b/tools/build/src/engine/build.bat index c96e508e7..0fdb804b6 100644 --- a/tools/build/src/engine/build.bat +++ b/tools/build/src/engine/build.bat @@ -613,3 +613,4 @@ goto Set_Args :Skip_Jam :Finish +exit /b %ERRORLEVEL% diff --git a/tools/build/src/engine/build.sh b/tools/build/src/engine/build.sh index 470ea3c07..6dbc70633 100755 --- a/tools/build/src/engine/build.sh +++ b/tools/build/src/engine/build.sh @@ -142,16 +142,27 @@ case $BOOST_JAM_TOOLSET in ;; intel-linux) - if test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel/cc/9.0/ - elif test -r /opt/intel_cc_80/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel_cc_80/ - elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler70/ia32/ - elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler60/ia32/ - elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then - BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler50/ia32/ + which icc >/dev/null 2>&1 + if test $? ; then + BOOST_JAM_CC=$(which icc) + echo "Found $BOOST_JAM_CC in environment" + BOOST_JAM_TOOLSET_ROOT=$(echo $BOOST_JAM_CC | sed -e 's/bin.*\/icc//') + # probably the most widespread + ARCH=intel64 + else + echo "No intel compiler in current path" + echo "Look in a few old place for legacy reason" + if test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then + BOOST_JAM_TOOLSET_ROOT=/opt/intel/cc/9.0/ + elif test -r /opt/intel_cc_80/bin/iccvars.sh ; then + BOOST_JAM_TOOLSET_ROOT=/opt/intel_cc_80/ + elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then + BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler70/ia32/ + elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then + BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler60/ia32/ + elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then + BOOST_JAM_TOOLSET_ROOT=/opt/intel/compiler50/ia32/ + fi fi if test -r ${BOOST_JAM_TOOLSET_ROOT}bin/iccvars.sh ; then # iccvars does not change LD_RUN_PATH. We adjust LD_RUN_PATH here in @@ -164,9 +175,11 @@ case $BOOST_JAM_TOOLSET in LD_RUN_PATH="${BOOST_JAM_TOOLSET_ROOT}lib:${LD_RUN_PATH}" fi export LD_RUN_PATH - . ${BOOST_JAM_TOOLSET_ROOT}bin/iccvars.sh + . ${BOOST_JAM_TOOLSET_ROOT}bin/iccvars.sh $ARCH + fi + if test -z "$BOOST_JAM_CC" ; then + BOOST_JAM_CC=icc fi - BOOST_JAM_CC=icc ;; vacpp) diff --git a/tools/build/src/engine/builtins.c b/tools/build/src/engine/builtins.c index daa73db9a..162c3d295 100644 --- a/tools/build/src/engine/builtins.c +++ b/tools/build/src/engine/builtins.c @@ -759,8 +759,9 @@ static int has_wildcards( char const * const str ) static LIST * append_if_exists( LIST * list, OBJECT * file ) { - return file_query( file ) - ? list_push_back( list, object_copy( file ) ) + file_info_t * info = file_query( file ); + return info + ? list_push_back( list, object_copy( info->name ) ) : list ; } diff --git a/tools/build/src/engine/execunix.c b/tools/build/src/engine/execunix.c index 965e58011..297c00377 100644 --- a/tools/build/src/engine/execunix.c +++ b/tools/build/src/engine/execunix.c @@ -137,6 +137,9 @@ void exec_cmd LIST * shell ) { + struct sigaction ignore, saveintr, savequit; + sigset_t chldmask, savemask; + int const slot = get_free_cmdtab_slot(); int out[ 2 ]; int err[ 2 ]; @@ -203,6 +206,21 @@ void exec_cmd if ( globs.pipe_action ) fcntl( err[ EXECCMD_PIPE_READ ], F_SETFD, FD_CLOEXEC ); + /* ignore SIGINT and SIGQUIT */ + ignore.sa_handler = SIG_IGN; + sigemptyset(&ignore.sa_mask); + ignore.sa_flags = 0; + if (sigaction(SIGINT, &ignore, &saveintr) < 0) + return; + if (sigaction(SIGQUIT, &ignore, &savequit) < 0) + return; + + /* block SIGCHLD */ + sigemptyset(&chldmask); + sigaddset(&chldmask, SIGCHLD); + if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0) + return; + if ( ( cmdtab[ slot ].pid = vfork() ) == -1 ) { perror( "vfork" ); @@ -216,6 +234,11 @@ void exec_cmd /*****************/ int const pid = getpid(); + /* restore previous signals */ + sigaction(SIGINT, &saveintr, NULL); + sigaction(SIGQUIT, &savequit, NULL); + sigprocmask(SIG_SETMASK, &savemask, NULL); + /* Redirect stdout and stderr to pipes inherited from the parent. */ dup2( out[ EXECCMD_PIPE_WRITE ], STDOUT_FILENO ); dup2( globs.pipe_action ? err[ EXECCMD_PIPE_WRITE ] : @@ -236,7 +259,10 @@ void exec_cmd r_limit.rlim_max = globs.timeout; setrlimit( RLIMIT_CPU, &r_limit ); } - setpgid( pid, pid ); + if (0 != setpgid( pid, pid )) { + perror("setpgid(child)"); + /* exit( EXITBAD ); */ + } execvp( argv[ 0 ], (char * *)argv ); perror( "execvp" ); _exit( 127 ); @@ -245,7 +271,9 @@ void exec_cmd /******************/ /* Parent process */ /******************/ - setpgid( cmdtab[ slot ].pid, cmdtab[ slot ].pid ); + + /* redundant call, ignore return value */ + setpgid(cmdtab[ slot ].pid, cmdtab[ slot ].pid); /* Parent not need the write pipe ends used by the child. */ close( out[ EXECCMD_PIPE_WRITE ] ); @@ -281,6 +309,11 @@ void exec_cmd /* Save input data into the selected running commands table slot. */ cmdtab[ slot ].func = func; cmdtab[ slot ].closure = closure; + + /* restore previous signals */ + sigaction(SIGINT, &saveintr, NULL); + sigaction(SIGQUIT, &savequit, NULL); + sigprocmask(SIG_SETMASK, &savemask, NULL); } #undef EXECCMD_PIPE_READ @@ -448,10 +481,17 @@ void exec_wait() /* select() will wait for I/O on a descriptor, a signal, or timeout. */ { + /* disable child termination signals while in select */ int ret; + sigset_t sigmask; + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGCHLD); + sigprocmask(SIG_BLOCK, &sigmask, NULL); while ( ( ret = select( fd_max + 1, &fds, 0, 0, ptv ) ) == -1 ) if ( errno != EINTR ) break; + /* restore original signal mask by unblocking sigchld */ + sigprocmask(SIG_UNBLOCK, &sigmask, NULL); if ( ret <= 0 ) continue; } diff --git a/tools/build/src/engine/fileunix.c b/tools/build/src/engine/fileunix.c index bff3a42f5..e8ea51507 100644 --- a/tools/build/src/engine/fileunix.c +++ b/tools/build/src/engine/fileunix.c @@ -80,7 +80,10 @@ struct ar_hdr /* archive file member header - printable ascii */ }; #endif -#if defined( OS_QNX ) || defined( OS_BEOS ) || defined( OS_MPEIX ) +#if defined( OS_QNX ) || \ + defined( OS_BEOS ) || \ + defined( OS_HAIKU ) || \ + defined( OS_MPEIX ) # define NO_AR # define HAVE_AR #endif diff --git a/tools/build/src/engine/function.c b/tools/build/src/engine/function.c index 690855e14..d9ad754e4 100644 --- a/tools/build/src/engine/function.c +++ b/tools/build/src/engine/function.c @@ -228,9 +228,18 @@ STACK * stack_global() return &result; } +struct list_alignment_helper +{ + char ch; + LIST * l; +}; + +#define LISTPTR_ALIGN_BASE ( sizeof( struct list_alignment_helper ) - sizeof( LIST * ) ) +#define LISTPTR_ALIGN ( ( LISTPTR_ALIGN_BASE > sizeof( LIST * ) ) ? sizeof( LIST * ) : LISTPTR_ALIGN_BASE ) + static void check_alignment( STACK * s ) { - assert( (size_t)s->data % sizeof( LIST * ) == 0 ); + assert( (size_t)s->data % LISTPTR_ALIGN == 0 ); } void * stack_allocate( STACK * s, int size ) diff --git a/tools/build/src/engine/jam.c b/tools/build/src/engine/jam.c index 1c80eec50..890d7672c 100644 --- a/tools/build/src/engine/jam.c +++ b/tools/build/src/engine/jam.c @@ -627,7 +627,8 @@ char *executable_path( char const * argv0 ) # include <stdlib.h> char * executable_path( char const * argv0 ) { - return strdup( getexecname() ); + const char * execname = getexecname(); + return execname ? strdup( execname ) : NULL; } #elif defined(__FreeBSD__) # include <sys/sysctl.h> diff --git a/tools/build/src/engine/jam.h b/tools/build/src/engine/jam.h index 497a5bfb1..2895906af 100644 --- a/tools/build/src/engine/jam.h +++ b/tools/build/src/engine/jam.h @@ -154,6 +154,11 @@ #define OSMINOR "OS=HPUX" #define OS_HPUX #endif +#ifdef __HAIKU__ + #define unix + #define OSMINOR "OS=HAIKU" + #define OS_HAIKU +#endif #ifdef __OPENNT #define unix #define OSMINOR "OS=INTERIX" @@ -370,7 +375,8 @@ #define OSPLAT "OSPLAT=MIPS" #endif -#ifdef __arm__ +#if defined( __arm__ ) || \ + defined( __aarch64__ ) #define OSPLAT "OSPLAT=ARM" #endif diff --git a/tools/build/src/engine/jambase.c b/tools/build/src/engine/jambase.c index b15282bc3..323ba1564 100644 --- a/tools/build/src/engine/jambase.c +++ b/tools/build/src/engine/jambase.c @@ -560,6 +560,18 @@ char *jambase[] = { "NOARSCAN ?= true ;\n", "STDHDRS ?= /boot/develop/headers/posix ;\n", "}\n", +"else if $(OS) = HAIKU\n", +"{\n", +"BINDIR ?= /boot/system/non-packaged/bin ;\n", +"CC ?= gcc ;\n", +"C++ ?= $(CC) ;\n", +"FORTRAN ?= \"\" ;\n", +"LIBDIR ?= /boot/system/non-packaged/lib ;\n", +"LINK ?= gcc ;\n", +"LINKLIBS ?= -lnetwork ;\n", +"NOARSCAN ?= true ;\n", +"STDHDRS ?= /boot/system/develop/headers/posix ;\n", +"}\n", "else if $(UNIX)\n", "{\n", "switch $(OS)\n", diff --git a/tools/build/src/engine/make1.c b/tools/build/src/engine/make1.c index 5a96dc4e5..390b4ccbe 100644 --- a/tools/build/src/engine/make1.c +++ b/tools/build/src/engine/make1.c @@ -593,8 +593,6 @@ static void make1c( state const * const pState ) TARGET * saved_includes; SETTINGS * s; - t->rescanned = 1; - /* Clean current includes. */ saved_includes = t->includes; t->includes = 0; diff --git a/tools/build/src/engine/modules/order.c b/tools/build/src/engine/modules/order.c index 3a83d3895..467322da0 100644 --- a/tools/build/src/engine/modules/order.c +++ b/tools/build/src/engine/modules/order.c @@ -77,7 +77,7 @@ void topological_sort( int * * graph, int num_vertices, int * result ) for ( i = 0; i < num_vertices; ++i ) colors[ i ] = white; - for ( i = 0; i < num_vertices; ++i ) + for ( i = num_vertices - 1; i >= 0; --i ) if ( colors[ i ] == white ) do_ts( graph, i, colors, &result ); diff --git a/tools/build/src/engine/rules.c b/tools/build/src/engine/rules.c index 7947c5507..eb35aa6df 100644 --- a/tools/build/src/engine/rules.c +++ b/tools/build/src/engine/rules.c @@ -63,7 +63,6 @@ static TARGET * get_target_includes( TARGET * const t ) i->name = object_copy( t->name ); i->boundname = object_copy( i->name ); i->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL; - i->original_target = t; t->includes = i; } return t->includes; diff --git a/tools/build/src/engine/rules.h b/tools/build/src/engine/rules.h index f3a020bb8..d118b3149 100644 --- a/tools/build/src/engine/rules.h +++ b/tools/build/src/engine/rules.h @@ -125,6 +125,16 @@ struct _target ACTIONS * actions; /* rules to execute, if any */ SETTINGS * settings; /* variables to define */ + TARGETS * depends; /* dependencies */ + TARGETS * dependants; /* the inverse of dependencies */ + TARGETS * rebuilds; /* targets that should be force-rebuilt + * whenever this one is + */ + TARGET * includes; /* internal includes node */ + + timestamp time; /* update time */ + timestamp leaf; /* update time of leaf sources */ + short flags; /* status info */ #define T_FLAG_TEMP 0x0001 /* TEMPORARY applied */ @@ -164,18 +174,6 @@ struct _target #define T_BIND_PARENTS 2 /* using parent's timestamp */ #define T_BIND_EXISTS 3 /* real file, timestamp valid */ - TARGETS * depends; /* dependencies */ - TARGETS * dependants; /* the inverse of dependencies */ - TARGETS * rebuilds; /* targets that should be force-rebuilt - * whenever this one is - */ - TARGET * includes; /* internal includes node */ - TARGET * original_target; /* original_target->includes = this */ - char rescanned; - - timestamp time; /* update time */ - timestamp leaf; /* update time of leaf sources */ - char fate; /* make0()'s diagnosis */ #define T_FATE_INIT 0 /* nothing done to target */ @@ -212,12 +210,12 @@ struct _target #define T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */ #endif + char status; /* exec_cmd() result */ + #ifdef OPT_SEMAPHORE TARGET * semaphore; /* used in serialization */ #endif - char status; /* exec_cmd() result */ - int asynccnt; /* child deps outstanding */ TARGETS * parents; /* used by make1() for completion */ TARGET * scc_root; /* used by make to resolve cyclic includes diff --git a/tools/build/src/tools/builtin.jam b/tools/build/src/tools/builtin.jam index d62680afd..92959afc0 100644 --- a/tools/build/src/tools/builtin.jam +++ b/tools/build/src/tools/builtin.jam @@ -35,13 +35,13 @@ import message ; import convert ; # FIXME: the following generate module import is not needed here but removing it -# too hastly will break using code (e.g. the main Boost library Jamroot file) +# too hastily will break using code (e.g. the main Boost library Jamroot file) # that forgot to import the generate module before calling the generate rule. import generate ; -.os-names = aix android bsd cygwin darwin freebsd hpux iphone linux netbsd openbsd osf - qnx qnxnto sgi solaris unix unixware windows +.os-names = aix android bsd cygwin darwin freebsd haiku hpux iphone linux netbsd + openbsd osf qnx qnxnto sgi solaris unix unixware windows elf # Not actually an OS -- used for targeting bare metal where object # format is ELF. This catches both -elf and -eabi gcc targets and well # as other compilers targeting ELF. It is not clear how often we need @@ -76,6 +76,7 @@ local rule default-host-os ( ) case COHERENT : host-os = unix ; case DRAGONFLYBSD : host-os = bsd ; case IRIX : host-os = sgi ; + case HAIKU : host-os = haiku ; case MACOSX : host-os = darwin ; case KFREEBSD : host-os = freebsd ; case LINUX : host-os = linux ; @@ -127,7 +128,7 @@ feature.feature debug-symbols : on off : propagated ; # everything not necessary to running removed. This option should # not be very often needed. Also, this feature will show up in # target paths of everything, not just binaries. Should fix that -# when impelementing feature relevance. +# when implementing feature relevance. feature.feature strip : off on : propagated ; feature.feature define : : free ; feature.feature undef : : free ; @@ -812,7 +813,7 @@ class linking-generator : generator local result = [ property-set.empty ] ; local extra ; - # Add appropricate <xdll-path> usage requirements. + # Add appropriate <xdll-path> usage requirements. local raw = [ $(property-set).raw ] ; if <link>shared in $(raw) { @@ -833,9 +834,9 @@ class linking-generator : generator # to other shared libraries this one depends on in order to be able to # find them all at runtime. - # Just pass all features in property-set, it is theorically possible + # Just pass all features in property-set, it is theoretically possible # that we will propagate <xdll-path> features explicitly specified by - # the user, but then the user is to blaim for using an internal feature. + # the user, but then the user is to blame for using an internal feature. local values = [ $(property-set).get <xdll-path> ] ; extra += $(values:G=<xdll-path>) ; diff --git a/tools/build/src/tools/builtin.py b/tools/build/src/tools/builtin.py index 68ddfed4b..14a883e1b 100644 --- a/tools/build/src/tools/builtin.py +++ b/tools/build/src/tools/builtin.py @@ -103,6 +103,7 @@ def default_host_os(): elif host_os == 'MACOSX': host_os = 'darwin' elif host_os == 'KFREEBSD': host_os = 'freebsd' elif host_os == 'LINUX': host_os = 'linux' + elif host_os == 'HAIKU': host_os = 'haiku' else: host_os = 'unix' return host_os.lower() diff --git a/tools/build/src/tools/clang-linux.jam b/tools/build/src/tools/clang-linux.jam index 0aa29d519..f6dcda9f3 100644 --- a/tools/build/src/tools/clang-linux.jam +++ b/tools/build/src/tools/clang-linux.jam @@ -75,8 +75,9 @@ toolset.flags clang-linux.compile OPTIONS <optimization>space : -Os ; # note: clang silently ignores some of these inlining options toolset.flags clang-linux.compile OPTIONS <inlining>off : -fno-inline ; +# For clang, 'on' and 'full' are identical. toolset.flags clang-linux.compile OPTIONS <inlining>on : -Wno-inline ; -toolset.flags clang-linux.compile OPTIONS <inlining>full : -finline-functions -Wno-inline ; +toolset.flags clang-linux.compile OPTIONS <inlining>full : -Wno-inline ; toolset.flags clang-linux.compile OPTIONS <warnings>off : -w ; toolset.flags clang-linux.compile OPTIONS <warnings>on : -Wall ; diff --git a/tools/build/src/tools/common.py b/tools/build/src/tools/common.py index 63c65e4c0..443b3e92d 100644 --- a/tools/build/src/tools/common.py +++ b/tools/build/src/tools/common.py @@ -66,7 +66,8 @@ def reset (): m = {"NT": __executable_path_variable, "CYGWIN": "PATH", "MACOSX": "DYLD_LIBRARY_PATH", - "AIX": "LIBPATH"} + "AIX": "LIBPATH", + "HAIKU": "LIBRARY_PATH"} global __shared_library_path_variable __shared_library_path_variable = m.get(OS, "LD_LIBRARY_PATH") diff --git a/tools/build/src/tools/gcc.jam b/tools/build/src/tools/gcc.jam index ce9be9d6d..db0453461 100644 --- a/tools/build/src/tools/gcc.jam +++ b/tools/build/src/tools/gcc.jam @@ -1034,6 +1034,7 @@ rule setup-threading ( targets * : sources * : properties * ) case cygwin : option = -mthreads ; case solaris : option = -pthreads ; libs = rt ; case beos : # No threading options. + case haiku : option = ; case *bsd : option = -pthread ; # There is no -lrt on BSD. case sgi : # gcc on IRIX does not support multi-threading. case darwin : # No threading options. diff --git a/tools/build/src/tools/gcc.py b/tools/build/src/tools/gcc.py index 97f1e79d4..a13ce7ad2 100644 --- a/tools/build/src/tools/gcc.py +++ b/tools/build/src/tools/gcc.py @@ -686,6 +686,9 @@ elif bjam.variable('UNIX'): elif host_os_name == 'BeOS': # BeOS has no threading options, don't set anything here. pass + elif host_os_name == 'Haiku': + flags('gcc', 'OPTIONS', ['<threading>multi'], ['-lroot']) + # there is no -lrt on Haiku, and -pthread is implicit elif host_os_name.endswith('BSD'): flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread']) # there is no -lrt on BSD diff --git a/tools/build/src/tools/link.jam b/tools/build/src/tools/link.jam index 4a7034b8a..944911b3e 100644 --- a/tools/build/src/tools/link.jam +++ b/tools/build/src/tools/link.jam @@ -94,6 +94,8 @@ rule can-junction ( project : ps ) else { +.can-junction = false ; + rule can-junction ( project : ps ) { } @@ -229,10 +231,20 @@ rule do-file-link { local target = [ path.native [ path.relative-to [ path.pwd ] $(<) ] ] ; local source = [ path.native [ path.relative-to [ path.pwd ] $(>) ] ] ; + local old-source = [ on $(target) return $(LINK-SOURCE) ] ; + if $(old-source) + { + import errors ; + errors.user-error + Cannot create link $(target) to $(source). : + Link previously defined to another file, $(old-source[1]). ; + } + LINK-SOURCE on $(target) = $(source) $(.current-target) ; LOCATE on $(target) = . ; DEPENDS $(.current-target) : $(target) ; if $(.can-symlink) = true { + DEPENDS $(target) : $(source) ; link.mklink $(target) : $(source) ; } else if $(.can-hardlink) = true @@ -279,6 +291,12 @@ rule do-link } } +rule force-update +{ + local target = [ path.native [ path.relative-to [ path.pwd ] $(<) ] ] ; + ALWAYS $(target) ; +} + rule do-split { local target = [ path.native [ path.relative-to [ path.pwd ] $(<) ] ] ; @@ -309,7 +327,7 @@ actions mklink-or-dir $(MKLINK_OR_DIR) } -rule link-entries ( target : files * : split ? ) +rule link-entries ( target : files * : split ? : deleted ? ) { for local s in $(files) { @@ -324,7 +342,7 @@ rule link-entries ( target : files * : split ? ) } if $(split) { - link-recursively $(t) : $(s) ; + link-recursively $(t) : $(s) : : $(deleted) ; } else { @@ -338,8 +356,12 @@ rule link-entries ( target : files * : split ? ) } } -rule link-recursively ( target : source : no-recurse ? ) +rule link-recursively ( target : source : no-recurse ? : deleted ? ) { + if $(deleted) { + force-update $(target) ; + } + local split ; if [ CHECK_IF_FILE [ path.native $(source) ] ] { @@ -350,30 +372,47 @@ rule link-recursively ( target : source : no-recurse ? ) split = true ; if ! $(.split-dirs.$(target)) { + if [ READLINK [ path.native $(target) ] ] + { + if ! $(deleted) { + do-rm $(target) ; + deleted = true ; + .deleted-dirs.$(target) = true ; + } + } local .current-target = $(.known-dirs.base.$(target)) ; for local s in $(.known-dirs.$(target)) { local t = [ path.join $(target) [ path.basename $(s) ] ] ; - link-recursively $(t) : $(s) : flat ; - } - if [ READLINK [ path.native $(target) ] ] - { - do-rm $(target) ; + link-recursively $(t) : $(s) : flat : $(deleted) ; } do-split $(target) ; - .split-dirs.$(target) = true ; + } + else if $(.deleted-dirs.$(target)) + { + deleted = true ; } } - else if [ path.exists [ path.native $(target) ] ] + else if [ path.exists [ path.native $(target) ] ] && ! $(deleted) { local link-target = [ READLINK [ path.native $(target) ] ] ; if $(link-target) { local full-path = [ path.root [ path.make $(link-target) ] [ path.parent $(target) ] ] ; - if $(full-path) != $(source) + # HACK: Take advantage of the fact that path.glob + # normalizes its arguments. If full-path and + # source are different, but both are empty, they + # will compare equal, but that's okay because + # for the purposes of this module, empty directories + # are equivalent. + if [ path.glob $(full-path) : * ] != [ path.glob $(source) : * ] { - do-rm $(target) ; + if ! $(deleted) { + do-rm $(target) ; + deleted = true ; + .deleted-dirs.$(target) = true ; + } do-split $(target) ; split = true ; } @@ -388,7 +427,11 @@ rule link-recursively ( target : source : no-recurse ? ) { if [ READLINK [ path.native $(target) ] ] { - do-rm $(target) ; + if ! $(deleted) { + do-rm $(target) ; + deleted = true ; + .deleted-dirs.$(target) = true ; + } } do-split $(target) ; split = true ; @@ -398,9 +441,14 @@ rule link-recursively ( target : source : no-recurse ? ) do-link $(target) : $(source) ; } + if $(split) + { + .split-dirs.$(target) = true ; + } + if ! $(no-recurse) { - link-entries $(target) : [ path.glob $(source) : * ] : $(split) ; + link-entries $(target) : [ path.glob $(source) : * ] : $(split) : $(deleted) ; } } @@ -433,7 +481,6 @@ rule mklink [ path.join [ path.root [ path.make $(source-path[1]) ] [ path.pwd ] ] [ path.make $(>:G=) ] ] ] ; PATH_TO_SOURCE on $(<) = [ path.native $(relative-path) ] ; - NOUPDATE $(<) ; } if [ os.name ] = NT diff --git a/tools/build/src/tools/python.jam b/tools/build/src/tools/python.jam index 783b9cee8..1a41a1e86 100644 --- a/tools/build/src/tools/python.jam +++ b/tools/build/src/tools/python.jam @@ -639,6 +639,7 @@ local rule system-library-dependencies ( target-os ) case qnx* : return ; case darwin : return ; case windows : return ; + case haiku : return ; case hpux : return <library>rt ; case *bsd : return <library>pthread <toolset>gcc:<library>util ; diff --git a/tools/build/src/tools/sun.jam b/tools/build/src/tools/sun.jam index 0ca927d3e..ea6f7e36a 100644 --- a/tools/build/src/tools/sun.jam +++ b/tools/build/src/tools/sun.jam @@ -18,10 +18,31 @@ generators.override sun.prebuilt : builtin.lib-generator ; generators.override sun.prebuilt : builtin.prebuilt ; generators.override sun.searched-lib-generator : searched-lib-generator ; +# +# There are no less than 5 standard library options: +# 1) The default, which uses an old version of the Rogue Wave std lib, +# also available via -std=sun03. +# 2) C++03 mode + STLport, selected via the -library option. +# 3) C++03 mode plus the Apache std lib, selected via the -library option. +# 4) C++03 or C++11 in g++ compatibility mode, and GNU libstdc++3, selected via -std=c++03/11. +# +# Note that the -std, -library and -compat compiler switches appear to be largely mutually +# incompatible, and that going forward the -std switch seems to be the prefered one. +# +# See http://docs.oracle.com/cd/E37069_01/html/E37075/bkamw.html#OSSCPgnaof +# feature.extend stdlib : sun-stlport ; feature.compose <stdlib>sun-stlport : <cxxflags>-library=stlport4 <linkflags>-library=stlport4 ; +feature.extend stdlib : apache ; +feature.compose <stdlib>apache + : <cxxflags>-library=stdcxx4 <linkflags>-library=stdcxx4 + ; +feature.extend stdlib : gnu ; +feature.compose <stdlib>gnu + : <cxxflags>-std=c++03 <linkflags>-std=c++03 + ; rule init ( version ? : command * : options * ) { diff --git a/tools/build/src/tools/testing-aux.jam b/tools/build/src/tools/testing-aux.jam index 64ba00387..5c7a267da 100644 --- a/tools/build/src/tools/testing-aux.jam +++ b/tools/build/src/tools/testing-aux.jam @@ -70,7 +70,7 @@ rule capture-output ( target : source : properties * : targets-to-remove * ) # OK if it cannot find the target or updating rule. NOCARE $(target:S=.output) ; - # This has two-fold effect. First it adds input files to the dependendency + # This has two-fold effect. First it adds input files to the dependency # graph, preventing a warning. Second, it causes input files to be bound # before target is created. Therefore, they are bound using SEARCH setting # on them and not LOCATE setting of $(target), as in other case (due to jam diff --git a/tools/build/src/tools/testing.jam b/tools/build/src/tools/testing.jam index e62c378ab..adb3d3e7e 100644 --- a/tools/build/src/tools/testing.jam +++ b/tools/build/src/tools/testing.jam @@ -1,6 +1,6 @@ # Copyright 2005 Dave Abrahams # Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus -# Copyright 2014 Rene Rivera +# Copyright 2014-2015 Rene Rivera # Copyright 2014 Microsoft Corporation # 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) @@ -433,7 +433,7 @@ rule capture-output ( target : source : properties * : targets-to-remove * ) # OK if it cannot find the target or updating rule. NOCARE $(target:S=.output) ; - # This has two-fold effect. First it adds input files to the dependendency + # This has two-fold effect. First it adds input files to the dependency # graph, preventing a warning. Second, it causes input files to be bound # before target is created. Therefore, they are bound using SEARCH setting # on them and not LOCATE setting of $(target), as in other case (due to jam @@ -537,6 +537,7 @@ if [ os.name ] = NT .SHELL_SET = "set " ; .CATENATE = type ; .CP = copy ; + .NULLIN = ; } else { @@ -550,6 +551,7 @@ else .SHELL_SET = "" ; .CATENATE = cat ; .CP = cp ; + .NULLIN = "<" "/dev/null" ; } @@ -571,7 +573,7 @@ actions capture-output bind INPUT_FILES output-file echo Skipping test execution due to testing.execute=off exit 0 $(.ENDIF) - $(LAUNCHER) "$(>)" $(ARGS) "$(INPUT_FILES)" > "$(output-file)" 2>&1 + $(LAUNCHER) "$(>)" $(ARGS) "$(INPUT_FILES)" > "$(output-file)" 2>&1 $(.NULLIN) $(.SET_STATUS) $(.RUN_OUTPUT_NL) >> "$(output-file)" echo EXIT STATUS: $(.STATUS) >> "$(output-file)" diff --git a/tools/build/src/util/__init__.py b/tools/build/src/util/__init__.py index f80fe70e9..e6a277af7 100644 --- a/tools/build/src/util/__init__.py +++ b/tools/build/src/util/__init__.py @@ -3,6 +3,9 @@ import bjam import re import types +from itertools import groupby + + # Decorator the specifies bjam-side prototype for a Python function def bjam_signature(s): @@ -134,3 +137,46 @@ def stem(filename): return filename[0:i] else: return filename + + +def abbreviate_dashed(s): + """Abbreviates each part of string that is delimited by a '-'.""" + r = [] + for part in s.split('-'): + r.append(abbreviate(part)) + return '-'.join(r) + + +def abbreviate(s): + """Apply a set of standard transformations to string to produce an + abbreviation no more than 4 characters long. + """ + if not s: + return '' + # check the cache + if s in abbreviate.abbreviations: + return abbreviate.abbreviations[s] + # anything less than 4 characters doesn't need + # an abbreviation + if len(s) < 4: + # update cache + abbreviate.abbreviations[s] = s + return s + # save the first character in case it's a vowel + s1 = s[0] + s2 = s[1:] + if s.endswith('ing'): + # strip off the 'ing' + s2 = s2[:-3] + # reduce all doubled characters to one + s2 = ''.join(c for c, _ in groupby(s2)) + # remove all vowels + s2 = s2.translate(None, "AEIOUaeiou") + # shorten remaining consonants to 4 characters + # and add the first char back to the front + s2 = s1 + s2[:4] + # update cache + abbreviate.abbreviations[s] = s2 + return s2 +# maps key to its abbreviated form +abbreviate.abbreviations = {} diff --git a/tools/build/src/util/doc.jam b/tools/build/src/util/doc.jam index 702cab4b5..733fa7c97 100644 --- a/tools/build/src/util/doc.jam +++ b/tools/build/src/util/doc.jam @@ -264,7 +264,7 @@ local rule print-help-top ( ) print.list-item "-a Rebuild everything" ; print.list-item "-n Don't execute the commands, only print them" ; print.list-item "-d+2 Show commands as they are executed" ; - print.list-item "-d0 Supress all informational messages" ; + print.list-item "-d0 Suppress all informational messages" ; print.list-item "-q Stop at first error" ; print.list-item "--reconfigure Rerun all configuration checks" ; print.list-item "--debug-configuration Diagnose configuration" ; diff --git a/tools/build/src/util/order.jam b/tools/build/src/util/order.jam index a74fc8c84..793c96130 100644 --- a/tools/build/src/util/order.jam +++ b/tools/build/src/util/order.jam @@ -166,4 +166,8 @@ rule __test__ ( ) $(c1).add-pair x l2 ; assert.result l1 l2 : $(c1).order l2 l1 ; assert.result l1 l2 l3 : $(c1).order l2 l3 l1 ; + + # The output should be stable for unconstrained + # elements. + assert.result l4 l5 : $(c1).order l4 l5 ; } diff --git a/tools/build/src/util/os.jam b/tools/build/src/util/os.jam index daef27f77..818b0b423 100644 --- a/tools/build/src/util/os.jam +++ b/tools/build/src/util/os.jam @@ -75,6 +75,8 @@ if $(.name) = NT .shared-library-path-variable-AIX = LIBPATH ; +.shared-library-path-variable-HAIKU = LIBRARY_PATH ; + # Default constants .shared-library-path-variable = LD_LIBRARY_PATH ; .path-separator = ":" ; |