From 122209a3de68d7748a30c32a90c3d282cc2b2cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Tue, 15 Mar 2005 18:28:16 +0000 Subject: [PATCH] simplified toolset for better maintainability. o removed get-quickbook-command mammoth o 'using quickbook ;' is no longer required (import suffices) [SVN r27675] --- v2/tools/quickbook.jam | 297 +++++++++++++---------------------------- 1 file changed, 91 insertions(+), 206 deletions(-) diff --git a/v2/tools/quickbook.jam b/v2/tools/quickbook.jam index 77f1969a8..e5c507690 100644 --- a/v2/tools/quickbook.jam +++ b/v2/tools/quickbook.jam @@ -11,16 +11,16 @@ # be used to generate nice (!) user documentation in different formats # (pdf/html/...), from a single text file with simple markup. # -# The toolset defines the QUICKBOOK type (file extension 'qbk') and the -# quickbook-to-boostbook rule. +# The toolset defines the QUICKBOOK type (file extension 'qbk') and +# a QUICKBOOK to XML (BOOSTBOOK) generator. # # # =========================================================================== # Q & A # =========================================================================== # -# If you don't know what this is all about, some Q&A below will hopefully get -# you up to speed with QuickBook and the toolset. +# If you don't know what this is all about, some Q & A will hopefully get you +# up to speed with QuickBook and this toolset. # # # What is QuickBook ? @@ -52,7 +52,7 @@ # The minimal example is: # # using boostbook ; -# using quickbook ; +# import quickbook ; # # boostbook my_docs : my_docs_source.qbk ; # @@ -68,22 +68,26 @@ # boostbook.jam and the BoostBook documentation for information on how to # do this. # -# A QuickBook executable is also needed. By default the toolset will -# automatically generate this, by looking for the QuickBook sources in the -# following directories: +# A QuickBook executable is also needed. The toolset will generate this +# executable if it can find the QuickBook sources. The following +# directories will be searched: # # BOOST_ROOT/tools/quickbook/ # BOOST_BUILD_PATH/../../quickbook/ # -# If QuickBook sources are not found the toolset will still try to find -# the 'quickbook' command using the PATH environment variable. +# (BOOST_ROOT and BOOST_BUILD_PATH are environment variables) +# +# If QuickBook sources are not found the toolset will then try to use +# the shell command 'quickbook'. # # -# How do I provide a custom 'quickbook' executable ? +# How do I provide a custom QuickBook executable ? +# +# You may put the following in your user-config.jam or site-config.jam: # # using quickbook : /path/to/quickbook ; # -# or, if quickbook can be found in your PATH, +# or, if 'quickbook' can be found in your PATH, # # using quickbook : quickbook ; # @@ -91,150 +95,120 @@ # For convenience three alternatives are tried to get a QuickBook executable: # # 1. If the user points us to the a QuickBook executable, that is used. -# Some tweaks still have to be done because we need a proper path to -# mark the executable as a dependency for the project executable: -# - search the path for command -# - (on Windows) add .exe .com .bat .cmd ... %PATHEXT% # -# 2. Look for QuickBook source directory and compile QuickBook using the -# default toolset, in release mode (gcc-generated quickbook is some -# tens of MB large in debug mode). -# Search takes place in the following directories: -# - BOOST_ROOT/tools/quickbook -# - BOOST_BUILD_PATH/../../quickbook +# 2. Otherwise, we search for the QuickBook sources and compile QuickBook +# using the default toolset. # -# 3. As a last resort, search the environment's PATH for 'quickbook'... and pray ;) +# 3. As a last resort, we rely on the shell for finding 'quickbook'. # import boostbook ; import "class" : new ; import feature ; import generators ; -import os ; -import path ; -import regex ; import toolset ; import type ; # The one and only QUICKBOOK type! type.register QUICKBOOK : qbk ; -# The feature is used to mark QuickBook executable as a -# dependency for QuickBook to BoostBook translation. -feature.feature : : free dependency ; +# shell command to run QuickBook +# targets to build QuickBook from sources. +feature.feature : : free ; +feature.feature : : free dependency ; # quickbook-binary-generator handles generation of the QuickBook executable, by -# marking it as a dependency for QuickBook sources. +# marking it as a dependency for QuickBook docs. # -# If the user supplied the invocation command for the executable that will be -# used. -# Otherwise we search some sensible places for the QuickBook source and -# compile it from scratch using the default toolset. -# As a last resort we will search the PATH environment variable for 'quickbook'. +# If the user supplied the QuickBook command that will be used. +# +# Otherwise we search some sensible places for the QuickBook sources and +# compile from scratch using the default toolset. +# +# As a last resort we rely on the shell to find 'quickbook'. class quickbook-binary-generator : generator { - import modules path property-set quickbook targets virtual-target ; - - rule __init__ ( command ? : * : * ) - { - quickbook-command = $(command) ; - - generator.__init__ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; - } + import common modules path property-set targets ; rule run ( project name ? : property-set : sources * : multiple ? ) { - # Targets to be built as dependencies for current project. - local quickbook-binary-target ; + # QuickBook invocation command and dependencies. + local quickbook-binary = [ modules.peek quickbook : .command ] ; + local quickbook-binary-dependencies ; - # Actual invocation command for QuickBook. - local quickbook-binary ; - - if $(quickbook-command) + if $(quickbook-binary) { - # The user provided us with the invocation command. We still need to - # make sure it is a complete path, so that we can tag it as a - # virtual target. - - # Get actual fully-qualified quickbook-command - local command = [ quickbook.get-quickbook-command $(quickbook-command) ] ; - - # Mark $(quickbook-command) as a virtual-target so bjam will not - # generate it. - quickbook-binary-target = [ virtual-target.from-file $(command) : $(project) ] ; - - quickbook-binary = $(quickbook-binary-target) ; + # Use user-supplied command. + quickbook-binary = [ common.get-invocation-command quickbook : $(quickbook-binary) ] ; } else { - # We're on our own. - - # Search for QuickBook sources in sensible places + # Search for QuickBook sources in sensible places, like # $(BOOST_ROOT)/tools/quickbook # $(BOOST_BUILD_PATH)/../../quickbook + # And build quickbook executable from sources. + local boost-root = [ modules.peek : BOOST_ROOT ] ; local boost-build-path = [ modules.peek : BOOST_BUILD_PATH ] ; - local search-dirs ; + local quickbook-dir ; if $(boost-root) { - search-dirs += [ path.join $(boost-root) tools ] ; + quickbook-dir += [ path.join $(boost-root) tools ] ; } if $(boost-build-path) { - search-dirs += $(boost-build-path)/../.. ; + quickbook-dir += $(boost-build-path)/../.. ; } - local quickbook-dir = [ path.glob $(search-dirs) : quickbook ] ; + quickbook-dir = [ path.glob $(quickbook-dir) : quickbook ] ; # If the QuickBook source directory was found, mark its main target # as a dependency for the current project. Otherwise, try to find # 'quickbook' in user's PATH if $(quickbook-dir) { - # QuickBook found! quickbook-dir = [ path.make $(quickbook-dir[1]) ] ; # Get the main-target in QuickBook directory. local quickbook-main-target = [ targets.resolve-reference $(quickbook-dir) : $(project) ] ; - # The first element are the actual targets, the second are - # properties found in target-id, which we don't care about - # since we've passed the id ourselves. + # The first element are actual targets, the second are + # properties found in target-id. We don't care about these since + # we've passed the id ourselves. quickbook-main-target = $(quickbook-main-target[1]) ; # Request an empty property set to build the QuickBook with default - # toolset, independently of what's specified in 'property-set'. + # toolset. local quickbook-property-set = [ property-set.empty ] ; # Add release to the quickbook-property-set: compiling # with gcc in the default 'debug' mode generates an executable - # several tens of megabytes large. This may also be true for - # other compilers. + # several tens of megabytes large. This may be true for + # other compilers as well. # (In general, Boost.Spirit-based parsers ask for "aggressive # inlining" although this is not strictly necessary) quickbook-property-set = [ $(quickbook-property-set).add-raw release ] ; - # Mark the quickbook-main-target for generation, this will be - # the quickbook executable. - quickbook-binary-target = [ $(quickbook-main-target).generate $(quickbook-property-set) ] ; + # Generate dependencies + quickbook-binary-dependencies = [ $(quickbook-main-target).generate $(quickbook-property-set) ] ; - # Ignore usage-requirements returned as the first element - # of the list. - quickbook-binary-target = $(quickbook-binary-target[2-]) ; + # Ignore usage-requirements returned as first element. + quickbook-binary-dependencies = $(quickbook-binary-dependencies[2-]) ; - # Some toolsets generate extra targets (e.g. RSP). While we must mark - # all of them as dependencies for the current project, we can only use - # the EXE target for actual execution of the quickbook-to-boostbook - # rule. - for local target in $(quickbook-binary-target) + # Some toolsets generate extra targets (e.g. RSP). + # We must mark all targets as dependencies for the project, but + # we'll only use the EXE target for quickbook-to-boostbook + # translation. + for local target in $(quickbook-binary-dependencies) { if [ $(target).type ] = EXE { - quickbook-binary += $(target) ; + quickbook-binary = + [ path.join [ $(target).path ] [ $(target).name ] ] ; } } } @@ -255,150 +229,61 @@ class quickbook-binary-generator : generator # As a last resort, search for 'quickbook' command in path. # Note that even if the 'quickbook' command is not found, - # get-quickbook-command will still return 'quickbook' and might + # get-invocation-command will still return 'quickbook' and might # generate an error while generating the virtual-target. - # Marking the QuickBook executable as virtual-target lets bjam pretend - # it has been built. - quickbook-binary-target = [ virtual-target.from-file [ quickbook.get-quickbook-command ] : $(project) ] ; - quickbook-binary = $(quickbook-binary-target) ; + quickbook-binary = [ common.get-invocation-command quickbook : quickbook ] ; } } - # Add $(quickbook-binary-target) as a dependency of the current project + # Add $(quickbook-binary-dependencies) as a dependency of the current project # and set it as the feature for the # quickbook-to-boostbook rule, below. property-set = [ $(property-set).add-raw - $(quickbook-binary-target) - $(quickbook-binary) ] ; + $(quickbook-binary-dependencies) + $(quickbook-binary) + $(quickbook-binary-dependencies) + ] ; return [ generator.run $(project) $(name) : $(property-set) : $(sources) : $(multiple) ] ; } - } -# Initialize toolset. The optional command argument supplies a path to the -# QuickBook executable. -rule init ( command ? ) +# Initialization of toolset. +# +# Parameters: +# command ? -> path to QuickBook executable. +# +# When command is not supplied toolset will search for QuickBook directory and +# compile the executable from source. If that fails we still search the path for +# 'quickbook'. +rule init ( + command ? # path to QuickBook executable. + ) { - # Initialization of module registers QUICKBOOK to XML generator. - # Registering the generator here requires the call 'using quickbook ;' to - # appear in "user" code but provides an easy way to override the 'quickbook' - # command. - if ! $(.initialized) { .initialized = true ; - - generators.register [ new quickbook-binary-generator - $(command) : quickbook.quickbook-to-boostbook : QUICKBOOK : XML ] ; + .command = $(command) ; } } -# The feature holds the command to run QuickBook -# (which translates quickbook to boostbook) -toolset.flags quickbook.quickbook-to-boostbook COMMAND ; +generators.register [ new quickbook-binary-generator quickbook.quickbook-to-boostbook : QUICKBOOK : XML ] ; + +# shell command to run QuickBook +# targets to build QuickBook from sources. +toolset.flags quickbook.quickbook-to-boostbook QB-COMMAND ; +toolset.flags quickbook.quickbook-to-boostbook QB-DEPENDENCIES ; -# Mark dependency of quickbook sources on upon direct -# invocation of quickbook-to-boostbook rule. rule quickbook-to-boostbook ( target : source : properties * ) { - DEPENDS $(target) : [ on $(target) return $(COMMAND) ] ; + # Signal dependency of quickbook sources on + # upon invocation of quickbook-to-boostbook. + DEPENDS $(target) : [ on $(target) return $(QB-DEPENDENCIES) ] ; } -# $(1) target -# $(2) source -actions quickbook-to-boostbook bind COMMAND +actions quickbook-to-boostbook { - $(COMMAND) $(2) $(1) ; -} - -# get-quickbook-command will try to find 'quickbook' on the user's path and -# return the full path to a user supplied command. -# -# When pointing to a precompiled 'quickbook' executable, it seems intuitive -# that a command found in PATH does not require full path qualification. -# However, because we are tagging the executable as a virtual-target, we still -# need the full path internally... -# -# Putting some extra work here for everyone's benefit hopefully won't break -# anything. -# -# common.get-invocation-command doesn't return the full path we need here. -rule get-quickbook-command ( user-supplied-command ? ) -{ - # Default value for quickbook binary. - user-supplied-command ?= quickbook ; - - # On windows executables come in different formats and shapes ;) - # The empty string gives precedence to user-supplied-command, before - # looking for things like quickbook.exe.exe - local path-ext = "" [ programs-extensions ] ; - - # If user-supplied-command contains directory elements, assume we have an - # absolute path and don't search the environment's PATH. - local search-path = $(user-supplied-command:D) ; - - if ! $(search-path) - { - search-path = [ path.programs-path ] ; - } - - # Search the path for the command (exclude directories from result) - local possible-commands = [ exclude-directories - [ path.glob $(search-path) : $(user-supplied-command:D=)$(path-ext) ] - ] ; - - if $(possible-commands) - { - # We have a match. - return [ path.make $(possible-commands[1]) ] ; - } - else - { - # Giving up :( - ECHO "QuickBook warning: Failed to find QuickBook." ; - ECHO " (Tried searching PATH using:" $(user-supplied-command) ")" ; - ECHO " Giving up!" ; - # Back to square one :( - return [ path.make $(user-supplied-command) ] ; - } -} - -# On windows systems searching the path for a command must take into account the -# executable's file extensions. For those systems programs-extensions gets the -# environment's executable extensions (PATHEXT) or sets up a default set if the -# none are found. -local rule programs-extensions ( ) -{ - local path-ext ; - - if [ os.name ] in NT - { - path-ext = [ regex.split [ modules.peek : PATHEXT ] ";" ] ; - # Set up a default set of executable extensions if none are available. - if ! $(path-ext) - { - path-ext = .COM .EXE .BAT .CMD ; - } - } - - return $(path-ext) ; -} - -# Goes through an array of paths returning only those which are NOT directories. -local rule exclude-directories ( paths * ) -{ - local return-paths ; - - for local path in $(paths) - { - if ! [ path.exists $(path)/. ] - { - return-paths += $(path) ; - } - } - - return $(return-paths) ; + $(QB-COMMAND) $(2) $(1) ; }