From 4f0eaeede09bf8eb208ee984dfcf74852a64b514 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Apr 2007 17:10:53 +0000 Subject: [PATCH] Bringing forward BBv2/Python support and a few other things that were obviously more up-to-date on the RC branch. Removed the Boost.Python v1 zip archive. [SVN r37346] --- v2/build-system.jam | 1 + v2/build/feature.jam | 21 ++- v2/build/generators.jam | 9 + v2/build/property-set.jam | 5 + v2/build/virtual-target.jam | 13 +- v2/tools/acc.jam | 9 +- v2/tools/builtin.jam | 30 ++-- v2/tools/common.jam | 10 +- v2/tools/darwin.jam | 13 +- v2/tools/doxproc.py | 340 ++++++------------------------------ v2/tools/gcc.jam | 39 ++++- v2/tools/msvc.jam | 17 +- 12 files changed, 171 insertions(+), 336 deletions(-) diff --git a/v2/build-system.jam b/v2/build-system.jam index 1f36fbf67..76c242610 100755 --- a/v2/build-system.jam +++ b/v2/build-system.jam @@ -83,6 +83,7 @@ local rule load-config ( basename : path + ) { if $(debug-config) { + ECHO searching \"$(path)\" for \"$(basename).jam\" ; local where = [ GLOB $(path) : $(basename).jam ] ; if $(where) { diff --git a/v2/build/feature.jam b/v2/build/feature.jam index 83d928cdc..6c4544ca9 100644 --- a/v2/build/feature.jam +++ b/v2/build/feature.jam @@ -165,13 +165,14 @@ rule defaults ( features * ) local result ; for local f in $(features) { - local a = $($(f).attributes) ; + local gf = $(:E=:G=$(f)) ; + local a = $($(gf).attributes) ; if ( free in $(a) ) || ( optional in $(a) ) { } else { - result += $(f)$($(f).default) ; + result += $(gf)$($(gf).default) ; } } return $(result) ; @@ -189,13 +190,13 @@ rule valid ( names + ) # return the attibutes of the given feature rule attributes ( feature ) { - return $($(feature).attributes) ; + return $($(:E=:G=$(feature)).attributes) ; } # return the values of the given feature rule values ( feature ) { - return $($(feature).values) ; + return $($(:E=:G=$(feature)).values) ; } # returns true iff 'value-string' is a value-string of an implicit feature @@ -640,6 +641,8 @@ local rule expand-composite ( property ) rule get-values ( feature : properties * ) { local result ; + + feature = $(:E=:G=$(feature)) ; # add <> if necessary. for local p in $(properties) { if $(p:G) = $(feature) @@ -1050,6 +1053,8 @@ local rule __test__ ( ) compose debug : _DEBUG off ; compose release : NDEBUG on ; + assert.result dynamic static : values ; + assert.result dynamic static : values runtime-link ; try ; { @@ -1128,12 +1133,20 @@ local rule __test__ ( ) : defaults ; + # make sure defaults is resilient to missing grist. + assert.result dynamic on + : defaults runtime-link define optimization + ; + feature dummy : dummy1 dummy2 ; subfeature dummy : subdummy : x y z : optional ; feature fu : fu1 fu2 : optional ; subfeature fu : subfu : x y z : optional ; subfeature fu : subfu2 : q r s ; + + assert.result optional : attributes ; + assert.result optional : attributes fu ; assert.result static foobar on gcc:FOO gcc debug native dummy1 2.95.2 diff --git a/v2/build/generators.jam b/v2/build/generators.jam index b4fd63758..75e1dd4e6 100644 --- a/v2/build/generators.jam +++ b/v2/build/generators.jam @@ -842,6 +842,9 @@ local rule try-one-generator-really ( project name ? : generator : local usage-requirements ; local success ; + + generators.dout [ indent ] returned $(targets) ; + if $(targets) { success = true ; @@ -859,6 +862,12 @@ local rule try-one-generator-really ( project name ? : generator : generators.dout [ indent ] " generator" [ $(generator).id ] " spawned " ; generators.dout [ indent ] " " $(targets) ; + if $(usage-requirements) + { + generators.dout [ indent ] " with usage requirements:" $(x) ; + } + + if $(success) { return $(usage-requirements) $(targets) ; diff --git a/v2/build/property-set.jam b/v2/build/property-set.jam index 0dd7d958c..9ccf8677f 100644 --- a/v2/build/property-set.jam +++ b/v2/build/property-set.jam @@ -101,6 +101,11 @@ class property-set return $(self.raw) ; } + rule str ( ) + { + return "[" $(self.raw) "]" ; + } + # Returns properties that are neither incidental nor free rule base ( ) { diff --git a/v2/build/virtual-target.jam b/v2/build/virtual-target.jam index 34ca0475f..c05ca5029 100644 --- a/v2/build/virtual-target.jam +++ b/v2/build/virtual-target.jam @@ -476,7 +476,18 @@ class abstract-file-target : virtual-target rule add-prefix-and-suffix ( specified-name : type ? : property-set ) { local suffix = [ type.generated-target-suffix $(type) : $(property-set) ] ; - suffix = .$(suffix) ; + + # Handle suffixes for which no leading dot is desired. Those are + # specified by enclosing them in <...>. Needed by python so it + # can create "_d.so" extensions, for example. + if $(suffix:G) + { + suffix = [ utility.ungrist $(suffix) ] ; + } + else + { + suffix = .$(suffix) ; + } local prefix = [ type.generated-target-prefix $(type) : $(property-set) ] ; diff --git a/v2/tools/acc.jam b/v2/tools/acc.jam index ed12c8714..bad17d13a 100644 --- a/v2/tools/acc.jam +++ b/v2/tools/acc.jam @@ -1,5 +1,6 @@ # Copyright Vladimir Prus 2004. # Copyright Toon Knapen 2004. +# Copyright Boris Gubenko 2007. # 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) @@ -75,22 +76,22 @@ flags acc LINKFLAGS multi : -mt ; actions acc.link bind NEEDLIBS { - aCC $(LINKFLAGS) +DD64 -mt -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) + aCC $(LINKFLAGS) +DD64 -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) } actions acc.link.dll bind NEEDLIBS { - aCC -b $(LINKFLAGS) +DD64 -mt -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) + aCC -b $(LINKFLAGS) +DD64 -o "$(<[1])" -L$(LIBPATH) -L$(STDLIBPATH) "$(>)" "$(NEEDLIBS)" "$(NEEDLIBS)" -l$(FINDLIBS) } actions acc.compile.c { - aCC -Ae -mt +DD64 -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" + aCC -Ae +DD64 -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" } actions acc.compile.c++ { - aCC -AA -mt +DD64 -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" + aCC -AA +DD64 -c -I$(BOOST_ROOT) -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o "$(<)" "$(>)" } actions updated together piecemeal acc.archive diff --git a/v2/tools/builtin.jam b/v2/tools/builtin.jam index d919482ec..d5fa1d2c9 100644 --- a/v2/tools/builtin.jam +++ b/v2/tools/builtin.jam @@ -33,14 +33,17 @@ import generate ; local os = [ modules.peek : OS ] ; feature os : $(os) : propagated link-incompatible ; +.os-names = amiga aix bsd cygwin darwin dos emx freebsd hpux + linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos + svr4 sysv ultrix unix unixware vms windows ; + # Translates from bjam current OS to the os tags used # in host-os and target-os. I.e. it returns the # running host-os. local rule default-host-os ( ) { local host-os ; - local os-list = [ feature.values host-os ] ; - if [ os.name ] in $(os-list:U) + if [ os.name ] in $(.os-names:U) { host-os = [ os.name ] ; } @@ -70,18 +73,13 @@ local rule default-host-os ( ) # to list all the values to prevent unkown value errors. # Both set the default value to the current OS to account for # the default use case of building on the target OS. -feature host-os - : amiga aix bsd cygwin darwin dos emx freebsd hpux - linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos - svr4 sysv ultrix unix unixware vms windows - : optional ; - feature.set-default host-os : [ default-host-os ] ; +feature host-os : $(.os-names) ; +feature.set-default host-os : [ default-host-os ] ; + feature target-os - : amiga aix bsd cygwin darwin dos emx freebsd hpux - linux netbsd openbsd osf qnx qnxnto sgi solaris sun sunos - svr4 sysv ultrix unix unixware vms windows + : $(.os-names) : propagated link-incompatible ; - feature.set-default target-os : [ default-host-os ] ; +feature.set-default target-os : [ default-host-os ] ; feature toolset : : implicit propagated symmetric ; @@ -169,15 +167,17 @@ feature dll-path : : free path ; feature hardcode-dll-paths : true false : incidental ; -# This is internal feature which holds the paths of all dependency +# An internal feature that holds the paths of all dependency # dynamic libraries. On Windows, it's needed so that we can all -# those paths to PATH, when running applications. +# those paths to PATH when running applications. # On Linux, it's needed to add proper -rpath-link command line options. feature xdll-path : : free path ; #provides means to specify def-file for windows dlls. feature def-file : : free dependency ; +feature.feature suppress-import-lib : false true : incidental ; + # This is internal feature which is used to store the name of # bjam action to call when building a target. feature.feature action : : free ; @@ -726,7 +726,7 @@ class linking-generator : generator } # Hardcode dll paths only when linking executables. - # Pros: don't need to relinking libraries when installing. + # Pros: don't need to relink libraries when installing. # Cons: "standalone" libraries (plugins, python extensions) # can't hardcode paths to dependent libraries. if [ $(property-set).get ] = true diff --git a/v2/tools/common.jam b/v2/tools/common.jam index e737a907a..0ac715791 100644 --- a/v2/tools/common.jam +++ b/v2/tools/common.jam @@ -338,6 +338,10 @@ rule check-tool-aux ( command ) if $(command:D) { if [ path.exists $(command) ] + # Both NT and Cygwin will run .exe files by their unqualified names + || [ os.on-windows ] && [ path.exists $(command).exe ] + # Only NT will run .bat files by their unqualified names + || [ os.name ] = NT && [ path.exists $(command).bat ] { return $(command) ; } @@ -601,11 +605,11 @@ actions hard-link # :: The abbreviated toolset tag being used to build the target. # [joiner] # :: Indication of a multi-threaded build. -# [joiner] +# [joiner] # :: Collective tag of the build runtime. # [joiner] # :: Short version tag taken from the given "version-feature" -# in the build properties. Or if not present the literal +# in the build properties. Or if not present, the literal # value as the version number. # [joiner] # :: Direct lookup of the given property-name value in the @@ -786,7 +790,7 @@ local rule runtime-tag ( name : type ? : property-set ) if on in $(properties) { tag += g ; } } - if debug-python in $(properties) { tag += y ; } + if on in $(properties) { tag += y ; } if debug in $(properties) { tag += d ; } if stlport in $(properties) { tag += p ; } if hostios in $(properties) { tag += n ; } diff --git a/v2/tools/darwin.jam b/v2/tools/darwin.jam index b14ff5407..e3def2490 100644 --- a/v2/tools/darwin.jam +++ b/v2/tools/darwin.jam @@ -65,14 +65,7 @@ local rule prepare-framework-path ( target + ) { local framework-path = [ on $(target) return $(FRAMEWORK:D) ] ; - if $(framework-path) - { - FRAMEWORK_PATH on $(target) += -F$(framework-path) ; - } - else - { - FRAMEWORK_PATH on $(target) = ; - } + FRAMEWORK_PATH on $(target) += -F$(framework-path) ; } rule link @@ -82,7 +75,7 @@ rule link actions link bind LIBRARIES { - $(CONFIG_COMMAND) -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=) $(OPTIONS) $(USER_OPTIONS) + $(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)"$(<)" } @@ -93,7 +86,7 @@ rule link.dll actions link.dll bind LIBRARIES { - $(CONFIG_COMMAND) -dynamiclib -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=) $(OPTIONS) $(USER_OPTIONS) + $(CONFIG_COMMAND) -dynamiclib -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS) } actions piecemeal archive diff --git a/v2/tools/doxproc.py b/v2/tools/doxproc.py index b2df94c24..edff1fe3d 100644 --- a/v2/tools/doxproc.py +++ b/v2/tools/doxproc.py @@ -70,7 +70,11 @@ def if_attribute(node, attribute, true_value, false_value=None): class Doxygen2BoostBook: - def __init__( self, **kwargs ): + def __init__( self, + #~ id=None, + #~ title='', + #~ last_revision=None, + **kwargs ): ## self.args = kwargs self.args.setdefault('id','') @@ -79,7 +83,6 @@ class Doxygen2BoostBook: self.args.setdefault('index', False) self.id = '%(id)s.reference' % self.args self.args['id'] = self.id - #~ This is our template BoostBook document we insert the generated content into. self.boostbook = xml.dom.minidom.parseString('''
%(title)s @@ -99,7 +102,6 @@ class Doxygen2BoostBook: 'classes' : self._getChild('index',id='%(id)s.classes' % self.args), 'index' : self._getChild('index',id='%(id)s.index' % self.args) } - #~ Remove the index sections if we aren't generating it. if not self.args['index']: self.section['classes'].parentNode.removeChild(self.section['classes']) self.section['classes'].unlink() @@ -107,31 +109,24 @@ class Doxygen2BoostBook: self.section['index'].parentNode.removeChild(self.section['index']) self.section['index'].unlink() del self.section['index'] - #~ The symbols, per Doxygen notion, that we translated. self.symbols = {} - #~ Map of Doxygen IDs and BoostBook IDs, so we can translate as needed. - self.idmap = {} - #~ Marks generation, to prevent redoing it. self.generated = False + self.idmap = {} - #~ Add an Doxygen generated XML document to the content we are translating. def addDox( self, document ): + ## self._translateNode(document.documentElement) - #~ Turns the internal XML tree into an output UTF-8 string. def tostring( self ): self._generate() #~ return self.boostbook.toprettyxml(' ') return self.boostbook.toxml('utf-8') - #~ Does post-processing on the partial generated content to generate additional info - #~ now that we have the complete source documents. def _generate( self ): if not self.generated: self.generated = True symbols = self.symbols.keys() symbols.sort() - #~ Populate the header section. for symbol in symbols: if self.symbols[symbol]['kind'] in ('header'): self.section['headers'].appendChild(self.symbols[symbol]['dom']) @@ -147,21 +142,14 @@ class Doxygen2BoostBook: container.appendChild(self.symbols[symbol]['dom']) self._rewriteIDs(self.boostbook.documentElement) - #~ Rewrite the various IDs from Doxygen references to the newly created - #~ BoostBook references. def _rewriteIDs( self, node ): if node.nodeName in ('link'): if (self.idmap.has_key(node.getAttribute('linkend'))): - #~ A link, and we have someplace to repoint it at. node.setAttribute('linkend',self.idmap[node.getAttribute('linkend')]) else: - #~ A link, but we don't have a generated target for it. node.removeAttribute('linkend') elif hasattr(node,'hasAttribute') and node.hasAttribute('id') and self.idmap.has_key(node.getAttribute('id')): - #~ Simple ID, and we have a translation. node.setAttribute('id',self.idmap[node.getAttribute('id')]) - #~ Recurse, and iterate, depth-first traversal which turns out to be - #~ left-to-right and top-to-bottom for the document. if node.firstChild: self._rewriteIDs(node.firstChild) if node.nextSibling: @@ -186,33 +174,23 @@ class Doxygen2BoostBook: self.idmap[id] = name.replace('::','.').replace('/','.') #~ print '--| setID:',id,'::',self.idmap[id] - #~ Translate a given node within a given context. - #~ The translation dispatches to a local method of the form - #~ "_translate[_context0,...,_contextN]", and the keyword args are - #~ passed along. If there is no translation handling method we - #~ return None. def _translateNode( self, *context, **kwargs ): node = None - names = [ ] + name = '_translate' for c in context: if c: if not isinstance(c,xml.dom.Node): - suffix = '_'+c.replace('-','_') + name += '_'+c else: - suffix = '_'+c.nodeName.replace('-','_') + name += '_'+c.nodeName node = c - names.append('_translate') - names = map(lambda x: x+suffix,names) - if node: - for name in names: - if hasattr(self,name): - return getattr(self,name)(node,**kwargs) - return None + name = name.replace('-','_') + #~ print '_translateNode:', name + if node and hasattr(self,name): + return getattr(self,name)(node,**kwargs) + else: + return None - #~ Translates the children of the given parent node, appending the results - #~ to the indicated target. For nodes not translated by the translation method - #~ it copies the child over and recurses on that child to translate any - #~ possible interior nodes. Hence this will translate the entire subtree. def _translateChildren( self, parent, **kwargs ): target = kwargs['target'] for n in parent.childNodes: @@ -222,13 +200,10 @@ class Doxygen2BoostBook: else: child = n.cloneNode(False) if hasattr(child,'data'): - child.data = re.sub(r'\s+',' ',child.data) + child.data = child.data.strip() target.appendChild(child) self._translateChildren(n,target=child) - #~ Translate the given node as a description, into the description subnode - #~ of the target. If no description subnode is present in the target it - #~ is created. def _translateDescription( self, node, target=None, tag='description', **kwargs ): description = self._getChild(tag,root=target) if not description: @@ -236,8 +211,6 @@ class Doxygen2BoostBook: self._translateChildren(node,target=description) return description - #~ Top level translation of: ..., - #~ translates the children. def _translate_doxygen( self, node ): #~ print '_translate_doxygen:', node.nodeName result = [] @@ -247,23 +220,11 @@ class Doxygen2BoostBook: result.append(newNode) return result - #~ Top level translation of: - #~ - #~ - #~ - #~ ... - #~ - #~ ... - #~ - #~ ... - #~ - #~ builds the class and symbol sections, if requested. def _translate_doxygenindex( self, node ): #~ print '_translate_doxygenindex:', node.nodeName if self.args['index']: entries = [] classes = [] - #~ Accumulate all the index entries we care about. for n in node.childNodes: if n.nodeName == 'compound': if n.getAttribute('kind') not in ('file','dir','define'): @@ -287,16 +248,12 @@ class Doxygen2BoostBook: if hasattr(m,'getAttribute') and m.getAttribute('kind') in ('class','struct'): classes.append(entry) entries.append(entry) - #~ Put them in a sensible order. entries.sort(lambda x,y: cmp(x['name'].lower(),y['name'].lower())) classes.sort(lambda x,y: cmp(x['name'].lower(),y['name'].lower())) - #~ And generate the BoostBook for them. self._translate_index_(entries,target=self.section['index']) self._translate_index_(classes,target=self.section['classes']) return None - #~ Translate a set of index entries in the BoostBook output. The output - #~ is grouped into groups of the first letter of the entry names. def _translate_index_(self, entries, target=None, **kwargs ): i = 0 targetID = target.getAttribute('id') @@ -315,16 +272,11 @@ class Doxygen2BoostBook: ie.appendChild(self.boostbook.createTextNode(')')) i += 1 - #~ Translate a ..., - #~ by retranslating with the "kind" of compounddef. def _translate_compounddef( self, node, target=None, **kwargs ): return self._translateNode(node,node.getAttribute('kind')) - #~ Translate a .... For - #~ namespaces we just collect the information for later use as there is no - #~ currently namespaces are not included in the BoostBook format. In the future - #~ it might be good to generate a namespace index. def _translate_compounddef_namespace( self, node, target=None, **kwargs ): + #~ print '--| _translate_compounddef_namespace:', node.getAttribute('id') namespace = { 'id' : node.getAttribute('id'), 'kind' : 'namespace', @@ -344,18 +296,11 @@ class Doxygen2BoostBook: #~ self._setID(namespace['id'],namespace['name']) return None - #~ Translate a ..., which - #~ forwards to the kind=struct as they are the same. def _translate_compounddef_class( self, node, target=None, **kwargs ): return self._translate_compounddef_struct(node,tag='class',target=target,**kwargs) - #~ Translate a ... into: - #~
- #~ - #~ ... - #~ - #~
def _translate_compounddef_struct( self, node, tag='struct', target=None, **kwargs ): + #~ print '--| _translate_compounddef_struct:', node.getAttribute('id') result = None includes = self._getChild('includes',root=node) if includes: @@ -376,13 +321,11 @@ class Doxygen2BoostBook: 'name' : compoundname['name'], 'dom' : struct } - ## Add the children which will be the members of the struct. for n in node.childNodes: self._translateNode(n,target=struct,scope=compoundname['compoundname']) result = struct return result - #~ Translate a ..., def _translate_compounddef_includes_( self, node, target=None, **kwargs ): name = node.firstChild.data if not self.symbols.has_key(name): @@ -396,104 +339,47 @@ class Doxygen2BoostBook: } return None - #~ Translate a ... into: - #~ - #~ ... - #~ def _translate_basecompoundref( self, ref, target=None, **kwargs ): inherit = target.appendChild(self._createNode('inherit', access=ref.getAttribute('prot'))) self._translateChildren(ref,target=inherit) return - #~ Translate: - #~ - #~ - #~ ... - #~ ... - #~ ... - #~ ... - #~ - #~ ... - #~ - #~ Into: - #~ def _translate_templateparamlist( self, templateparamlist, target=None, **kwargs ): template = target.appendChild(self._createNode('template')) for param in templateparamlist.childNodes: if param.nodeName == 'param': - type = self._getChildData('type',root=param) - defval = self._getChild('defval',root=param) paramKind = None - if type in ('class','typename'): + if self._getChildData('type',root=param) in ( + 'class','typename'): paramKind = 'template-type-parameter' else: paramKind = 'template-nontype-parameter' templateParam = template.appendChild( self._createNode(paramKind, name=self._getChildData('declname',root=param))) - if paramKind == 'template-nontype-parameter': - template_type = templateParam.appendChild(self._createNode('type')) - self._translate_type( - self._getChild('type',root=param),target=template_type) + defval = self._getChild('defval',root=param) if defval: - value = self._getChildData('ref',root=defval.firstChild) - if not value: - value = self._getData(defval) - templateParam.appendChild(self._createText('default',value)) + templateParam.appendChild(self._createText('default', + self._getChildData('ref',root=defval.firstChild))) return template - #~ Translate: - #~ ... - #~ Into: - #~ ... def _translate_briefdescription( self, brief, target=None, **kwargs ): self._translateDescription(brief,target=target,**kwargs) return self._translateDescription(brief,target=target,tag='purpose',**kwargs) - #~ Translate: - #~ ... - #~ Into: - #~ ... def _translate_detaileddescription( self, detailed, target=None, **kwargs ): return self._translateDescription(detailed,target=target,**kwargs) - #~ Translate: - #~ ... - #~ With kind specific translation. def _translate_sectiondef( self, sectiondef, target=None, **kwargs ): self._translateNode(sectiondef,sectiondef.getAttribute('kind'),target=target,**kwargs) - #~ Translate non-function sections. def _translate_sectiondef_x_( self, sectiondef, target=None, **kwargs ): for n in sectiondef.childNodes: if hasattr(n,'getAttribute'): self._translateNode(n,n.getAttribute('kind'),target=target,**kwargs) return None - #~ Translate: - #~ ... - def _translate_sectiondef_public_type( self, sectiondef, target=None, **kwargs ): - return self._translate_sectiondef_x_(sectiondef,target=target,**kwargs) - - #~ Translate: - #~ ... - def _translate_sectiondef_public_attrib( self, sectiondef, target=None, **kwargs): - return self._translate_sectiondef_x_(sectiondef,target=target,**kwargs) - - #~ Translate: - #~ ... - #~ All the various function group translations end up here for which - #~ they are translated into: - #~ - #~ ... - #~ def _translate_sectiondef_func_( self, sectiondef, name='functions', target=None, **kwargs ): members = target.appendChild(self._createNode('method-group',name=name)) for n in sectiondef.childNodes: @@ -501,44 +387,28 @@ class Doxygen2BoostBook: self._translateNode(n,n.getAttribute('kind'),target=members,**kwargs) return members - #~ Translate: - #~ ... + def _translate_sectiondef_public_type( self, sectiondef, target=None, **kwargs ): + return self._translate_sectiondef_x_(sectiondef,target=target,**kwargs) + + def _translate_sectiondef_public_attrib( self, sectiondef, target=None, **kwargs): + return self._translate_sectiondef_x_(sectiondef,target=target,**kwargs) + def _translate_sectiondef_public_func( self, sectiondef, target=None, **kwargs ): return self._translate_sectiondef_func_(sectiondef, name='public member functions',target=target,**kwargs) - #~ Translate: - #~ ... def _translate_sectiondef_public_static_func( self, sectiondef, target=None, **kwargs): return self._translate_sectiondef_func_(sectiondef, name='public static functions',target=target,**kwargs) - #~ Translate: - #~ ... def _translate_sectiondef_protected_func( self, sectiondef, target=None, **kwargs ): return self._translate_sectiondef_func_(sectiondef, name='protected member functions',target=target,**kwargs) - #~ Translate: - #~ ... def _translate_sectiondef_private_static_func( self, sectiondef, target=None, **kwargs): return self._translate_sectiondef_func_(sectiondef, name='private static functions',target=target,**kwargs) - #~ Translate: - #~ ... - def _translate_sectiondef_private_func( self, sectiondef, target=None, **kwargs ): - return self._translate_sectiondef_func_(sectiondef, - name='private member functions',target=target,**kwargs) - - #~ Translate: - #~ - #~ ... - #~ - #~ To: - #~ - #~ ... - #~ def _translate_memberdef_typedef( self, memberdef, target=None, scope=None, **kwargs ): self._setID(memberdef.getAttribute('id'), scope+'::'+self._getChildData('name',root=memberdef)) @@ -546,35 +416,20 @@ class Doxygen2BoostBook: id=memberdef.getAttribute('id'), name=self._getChildData('name',root=memberdef))) typedef_type = typedef.appendChild(self._createNode('type')) - self._translate_type(self._getChild('type',root=memberdef),target=typedef_type) + self._translateChildren(self._getChild('type',root=memberdef),target=typedef_type) return typedef - #~ Translate: - #~ - #~ ... - #~ - #~ To: - #~ - #~ ... - #~ def _translate_memberdef_function( self, memberdef, target=None, scope=None, **kwargs ): - name = self._getChildData('name',root=memberdef) - self._setID(memberdef.getAttribute('id'),scope+'::'+name) - ## Check if we have some specific kind of method. - if name == scope.split('::')[-1]: - kind = 'constructor' - target = target.parentNode - elif name == '~'+scope.split('::')[-1]: - kind = 'destructor' - target = target.parentNode - elif name == 'operator=': - kind = 'copy-assignment' - target = target.parentNode - else: - kind = 'method' - method = target.appendChild(self._createNode(kind, + ## The current BoostBook to Docbook translator doesn't respect method + ## Ids. Nor does it assign any useable IDs to the individial methods. + # self._setID(memberdef.getAttribute('id'), + # scope+'::'+self._getChildData('name',root=memberdef)) + ## Hence instead of registering an ID for the method we point it at the + ## containing class. + self._setID(memberdef.getAttribute('id'),scope) + method = target.appendChild(self._createNode('method', # id=memberdef.getAttribute('id'), - name=name, + name=self._getChildData('name',root=memberdef), cv=' '.join([ if_attribute(memberdef,'const','const','').strip() ]), @@ -584,62 +439,32 @@ class Doxygen2BoostBook: if_attribute(memberdef,'inline','inline','') ]).strip() )) - ## We iterate the children to translate each part of the function. for n in memberdef.childNodes: self._translateNode(memberdef,'function',n,target=method) return method - #~ Translate: - #~ ... def _translate_memberdef_function_templateparamlist( self, templateparamlist, target=None, **kwargs ): return self._translate_templateparamlist(templateparamlist,target=target,**kwargs) - #~ Translate: - #~ ... - #~ To: - #~ ...? def _translate_memberdef_function_type( self, resultType, target=None, **kwargs ): - methodType = self._createNode('type') - self._translate_type(resultType,target=methodType) - if methodType.hasChildNodes(): - target.appendChild(methodType) + methodType = target.appendChild(self._createNode('type')) + self._translateChildren(resultType,target=methodType) return methodType - #~ Translate: - #~ ... def _translate_memberdef_function_briefdescription( self, description, target=None, **kwargs ): - result = self._translateDescription(description,target=target,**kwargs) - ## For functions if we translate the brief docs to the purpose they end up - ## right above the regular description. And since we just added the brief to that - ## on the previous line, don't bother with the repetition. - # result = self._translateDescription(description,target=target,tag='purpose',**kwargs) - return result + self._translateDescription(description,target=target,**kwargs) + return self._translateDescription(description,target=target,tag='purpose',**kwargs) - #~ Translate: - #~ ... def _translate_memberdef_function_detaileddescription( self, description, target=None, **kwargs ): return self._translateDescription(description,target=target,**kwargs) - #~ Translate: - #~ ... def _translate_memberdef_function_inbodydescription( self, description, target=None, **kwargs ): return self._translateDescription(description,target=target,**kwargs) - #~ Translate: - #~ ... def _translate_memberdef_function_param( self, param, target=None, **kwargs ): return self._translate_param(param,target=target,**kwargs) - #~ Translate: - #~ - #~ ... - #~ ... - #~ - #~ To: - #~ - #~ ... - #~ def _translate_memberdef_variable( self, memberdef, target=None, scope=None, **kwargs ): self._setID(memberdef.getAttribute('id'), scope+'::'+self._getChildData('name',root=memberdef)) @@ -647,17 +472,8 @@ class Doxygen2BoostBook: id=memberdef.getAttribute('id'), name=self._getChildData('name',root=memberdef))) data_member_type = data_member.appendChild(self._createNode('type')) - self._translate_type(self._getChild('type',root=memberdef),target=data_member_type) + self._translateChildren(self._getChild('type',root=memberdef),target=data_member_type) - #~ Translate: - #~ - #~ ... - #~ ... - #~ - #~ To: - #~ - #~ ... - #~ def _translate_memberdef_enum( self, memberdef, target=None, scope=None, **kwargs ): self._setID(memberdef.getAttribute('id'), scope+'::'+self._getChildData('name',root=memberdef)) @@ -668,17 +484,6 @@ class Doxygen2BoostBook: self._translateNode(memberdef,'enum',n,target=enum,scope=scope,**kwargs) return enum - #~ Translate: - #~ - #~ - #~ ... - #~ ... - #~ - #~ - #~ To: - #~ - #~ ... - #~ def _translate_memberdef_enum_enumvalue( self, enumvalue, target=None, scope=None, **kwargs ): self._setID(enumvalue.getAttribute('id'), scope+'::'+self._getChildData('name',root=enumvalue)) @@ -691,68 +496,30 @@ class Doxygen2BoostBook: target=target.appendChild(self._createNode('default'))) return value - #~ Translate: - #~ - #~ ... - #~ ... - #~ ... - #~ - #~ To: - #~ - #~ ... - #~ ... - #~ def _translate_param( self, param, target=None, **kwargs): parameter = target.appendChild(self._createNode('parameter', name=self._getChildData('declname',root=param))) paramtype = parameter.appendChild(self._createNode('paramtype')) - self._translate_type(self._getChild('type',root=param),target=paramtype) + self._translateChildren(self._getChild('type',root=param),target=paramtype) defval = self._getChild('defval',root=param) if defval: self._translateChildren(self._getChild('defval',root=param),target=parameter) return parameter - #~ Translate: - #~ ... def _translate_ref( self, ref, **kwargs ): return self._translateNode(ref,ref.getAttribute('kindref')) - #~ Translate: - #~ ... - #~ To: - #~ ... def _translate_ref_compound( self, ref, **kwargs ): result = self._createNode('link',linkend=ref.getAttribute('refid')) classname = result.appendChild(self._createNode('classname')) self._translateChildren(ref,target=classname) return result - #~ Translate: - #~ ... - #~ To: - #~ ... def _translate_ref_member( self, ref, **kwargs ): result = self._createNode('link',linkend=ref.getAttribute('refid')) self._translateChildren(ref,target=result) return result - #~ Translate: - #~ ... - def _translate_type( self, type, target=None, **kwargs ): - result = self._translateChildren(type,target=target,**kwargs) - #~ Filter types to clean up various readability problems, most notably - #~ with really long types. - xml = target.toxml('utf-8'); - if ( - xml.startswith('boost::mpl::') or - xml.startswith('BOOST_PP_') or - re.match('boost::(lazy_)?(enable|disable)_if',xml) - ): - while target.firstChild: - target.removeChild(target.firstChild) - target.appendChild(self._createText('emphasis','unspecified')) - return result - def _getChild( self, tag = None, id = None, name = None, root = None ): if not root: root = self.boostbook.documentElement @@ -773,11 +540,9 @@ class Doxygen2BoostBook: return None def _getChildData( self, tag, **kwargs ): - return self._getData(self._getChild(tag,**kwargs),**kwargs) - - def _getData( self, node, **kwargs ): - if node: - text = self._getChild('#text',root=node) + child = self._getChild(tag,**kwargs) + if child: + text = self._getChild('#text',root=child) if text: return text.data.strip() return '' @@ -804,10 +569,9 @@ class Doxygen2BoostBook: def _createNode( self, tag, **kwargs ): result = self.boostbook.createElement(tag) for k in kwargs.keys(): - if kwargs[k] != '': - if k == 'id': - result.setAttribute('id',kwargs[k]) - else: + if k == 'id': + result.setAttribute('id',kwargs[k]) + else: result.setAttribute(k,kwargs[k]) return result diff --git a/v2/tools/gcc.jam b/v2/tools/gcc.jam index 8b8d86352..efe907827 100644 --- a/v2/tools/gcc.jam +++ b/v2/tools/gcc.jam @@ -44,6 +44,9 @@ generators.override gcc.searched-lib-generator : searched-lib-generator ; type.set-generated-target-suffix OBJ : gcc : o ; type.set-generated-target-suffix STATIC_LIB : gcc : a ; +type.set-generated-target-suffix IMPORT_LIB : gcc cygwin : dll.a ; +type.set-generated-target-suffix IMPORT_LIB : gcc windows : a ; + import rc ; # Initializes the gcc toolset for the given version. @@ -75,7 +78,7 @@ rule init ( version ? : command * : options * ) # Autodetect the version and flavor if not given. if $(command) { - # The 'command' variable can have multiple-element. When calling + # The 'command' variable can have multiple elements. When calling # the SHELL builtin we need a single string. local command-string = $(command:J=" ") ; local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ ]+)[^(]*[(]?([^)]*)" @@ -427,8 +430,26 @@ class gcc-linking-generator : unix-linking-generator } else { - return [ unix-linking-generator.run $(project) $(name) + local generated-targets = [ unix-linking-generator.run $(project) $(name) : $(property-set) : $(sources) ] ; + + # If more than one target was generated, throw out the + # last one, which on windows just leaves the import + # library. Most generators on windows simply don't accept + # shared libraries as input, but being able to link + # directly to a shared library without an import library + # is an important capability of GCC. Therefore, we remove + # the target after the action sees it so that dependent + # targets don't try to link to both the import library and + # the DLL. + if [ $(property-set).get ] = true + { + return $(generated-targets[0]) $(generated-targets[-1]) ; + } + else + { + return $(generated-targets[1-2]) ; + } } } } @@ -436,9 +457,17 @@ class gcc-linking-generator : unix-linking-generator generators.register [ new gcc-linking-generator gcc.link : LIB OBJ : EXE : gcc ] ; -generators.register [ new gcc-linking-generator gcc.link.dll : LIB OBJ : SHARED_LIB - : gcc ] ; +.IMPLIB-COMMAND = ; +.IMPLIB-TYPE = ; +if [ os.on-windows ] +{ + .IMPLIB-COMMAND = "-Wl,--out-implib," ; + .IMPLIB-TYPE = IMPORT_LIB ; +} +generators.register + [ new gcc-linking-generator gcc.link.dll : LIB OBJ : $(.IMPLIB-TYPE) SHARED_LIB + : gcc ] ; # Declare flags for linking # First, the common flags @@ -601,7 +630,7 @@ rule link.dll ( targets * : sources * : properties * ) # Differ from 'link' above only by -shared. actions link.dll bind LIBRARIES { - "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" -o "$(<)" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) + "$(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)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) } # Set up threading support. It's somewhat contrived, so perform it at the end, diff --git a/v2/tools/msvc.jam b/v2/tools/msvc.jam index c87ce540a..4c161c041 100644 --- a/v2/tools/msvc.jam +++ b/v2/tools/msvc.jam @@ -301,7 +301,7 @@ local rule configure-really ( setup-option = x86 x86_amd64 x86_iPF ; # Use a native x64 compiler if possible - if [ os.environ PROCESSOR_ARCHITECTURE ] = AMD64 + if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_IDENTIFIER ] ] { setup-option = x86 amd64 x86_IPF ; } @@ -855,7 +855,7 @@ else # Windows Manifests is a new way to specify dependencies # on managed DotNet assemblies and Windows native DLLs. The -# manifests are embedded as resourses and are useful in +# manifests are embedded as resources and are useful in # any PE targets (both DLL and EXE) if [ os.name ] in NT @@ -968,14 +968,19 @@ if [ os.name ] in NT CYGWIN { if $(.version-$(i)-reg) { - local vc-path = [ W32_GETREG - "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"$(.version-$(i)-reg) + local vc-path ; + for local x in "" "Wow6432Node\\" + { + vc-path += [ W32_GETREG + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"$(x)$(.version-$(i)-reg) : "ProductDir" ] ; + } + if $(vc-path) { - vc-path = [ path.native [ path.join [ path.make-NT $(vc-path) ] "bin" ] ] ; - register-configuration $(i) : $(vc-path) ; + vc-path = [ path.native [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ] ; + register-configuration $(i) : $(vc-path[1]) ; } } }