Boost logo

Boost-Build :

From: Thomas Witt (witt_at_[hidden])
Date: 2002-02-26 10:22:48


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Dave,

On Tuesday 26 February 2002 15:34, David Abrahams wrote:
> Hi Thomas,
>
> your diffs don't appear to correspond to the current CVS state, so I can't
> apply your patch.

It seems I mixed up the names. Swapping the names in the header should make
the problem go away. Anyway I made a new patch that should work, though I use
diff/patch seldomly so I may still miss a point. Sorry for the inconvenience.

> I am wondering a bit why the "template" solution is superior to using
> global variables which contain the dependencies.

The main reason is, it never came to my mind using global variables for this.
One advantage of templates is that they can be located anywhere in the project
tree. The other advantage is they are not global variables :-). Seriously I
think template is more expressive compared to global variables.

> Also, have you considered
> how this would interact with the proposed "project/subproject-as-target"
> feature?

Nope, the intent was to have a temporary solution as long as v2 is not
available. My understanding was that development of v1 with regard to new
features stopped some time ago. I badly needed to manage global settings
and I did not think about global variables.

The template "feature" was designed so that current behaviour does not change.
Anybody not using templates will not notice any change in behaviour or
runtime. So those who think they benefit from the fix can use it and fix
their Jamfiles when moving to v2. All others are not affected.

> I certainly would like to have documentation before committing
> something of this magnitude.

This was not intended as a "come'on apply this patch fast" message.
I will write the documentation if we/you decide it/something like this should
go in. And it's ok for me to commit after documentation work is finished.

There is only minimal change to the existing code with regard to template.
Nearly the whole functionality is realised in new code. The only "old" rule
affected is declare-local-target. If template is dropped I would like to add
hooks to declare-local-target to implement it locally.

This is not true for the with-command-file change. This is mostly existing
code that is modified, but still the changes should not affect current
behaviour. This change is not directly related to template. I think it is
needed with or without template.

Thomas

>
> Thanks for your work,
> Dave
>
>
> ----- Original Message -----
> From: "Thomas Witt" <witt_at_[hidden]>
> To: <jamboost_at_[hidden]>
> Sent: Tuesday, February 26, 2002 6:08 AM
> Subject: [jamboost] patch boost-base.jam project wide settings
>
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> >
> > Hi,
> >
> > The attached patch introduces a new rule template that can be used to
> > conveniently define project wide requirements. Furthermore
> > a change to the with-command-file rule is made to allow for
> > additional prefix string that contains non-sources. I need this to
>
> circumvent
>
> > cmdline restrictions with long libpathes on windows.
> >
> > Here is an example of template usage.
> >
> > #
> > # Defining requirements template
> > #
> > template TplBase
> >
> >
> > # requirements
> > <include>../myinclude
> > <define>TEMPLATE
> > # build not covered so far.
> > ;
> >
> > #
> > # Defining another requirements template
> > # that inherits requirements
> > #
> > template TplDerived
> >
> > # only <template> dependencies go here
> > <template>TplBase
> >
> > <include>../anotherinclude
> > <define>DERIVED_TEMPLATE
> > ;
> >
> > #
> > # Exe that uses requirements from TplDerived
> > #
> > exe MyExe
> >
> > main.cpp
> > <template>TplDerived
> >
> >
> > debug
> > ;
> >
> > I am using template in two projects and it reduces the maintenance work
> > by at least an order of magnitude. Currently template covers only
> > requirements but I think it can be extended to cover build settings to.
>
> The
>
> > need for requirements was just more pressing :-). If this goes in I will
> > happily update the documentation.
> >
> > Thomas
> >
> > - --
> > Dipl.-Ing. Thomas Witt
> > Institut fuer Verkehrswesen, Eisenbahnbau und -betrieb, Universitaet
>
> Hannover
>
> > voice: +49(0) 511 762 - 4273, fax: +49(0) 511 762-3001
> > http://www.ive.uni-hannover.de
> > -----BEGIN PGP SIGNATURE-----
> > Version: GnuPG v1.0.6 (GNU/Linux)
> > Comment: For info see http://www.gnupg.org
> >
> > iD8DBQE8e2yg0ds/gS3XsBoRAlOtAKCGvE3yuhgpMiGQZf4voYt/YQr2CwCfWEoa
> > fv8flr9IuLiXrrp6vlELgX0=
> > =4NKn
> > -----END PGP SIGNATURE-----
> >
> >
> > To unsubscribe from this group, send an email to:
> > jamboost-unsubscribe_at_[hidden]
> >
> >
> >
> > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
> To unsubscribe from this group, send an email to:
> jamboost-unsubscribe_at_[hidden]
>
>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
- --
Dipl.-Ing. Thomas Witt
Institut fuer Verkehrswesen, Eisenbahnbau und -betrieb, Universitaet Hannover
voice: +49(0) 511 762 - 4273, fax: +49(0) 511 762-3001
http://www.ive.uni-hannover.de
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE8e6hO0ds/gS3XsBoRAhiiAJ9YzHrlNfOD1FKPCiBhW+1qVYKJhwCdEfGe
snJv4THFdkEvCggVPhoFb0A=
=m4ai
-----END PGP SIGNATURE-----
 --------------Boundary-00=_02C5RNIPHQ4R1EULRDNJ Content-Type: text/x-diff;
charset="windows-1252";
name="boost-base.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="boost-base.patch"

*** boost-base.jam Tue Feb 26 15:35:17 2002
--- boost-base-new.jam Tue Feb 26 11:31:48 2002
***************
*** 1153,1159 ****
local x-target = [ expand-target-names $(target) : $(target-type) ] ;
local x-sources = [ expand-source-names $(sources) ] ;

! # We add SOURCE_GRIST the base target name here because we're referring the
# abstract target which generates all of the actual builds. We need a way to
# distinguish targets of the same name from different subprojects.
local target-id = [ FGristFiles $(x-target) ] ;
--- 1153,1159 ----
local x-target = [ expand-target-names $(target) : $(target-type) ] ;
local x-sources = [ expand-source-names $(sources) ] ;

! # We add SOURCE_GRIST to the base target name here because we're referring the
# abstract target which generates all of the actual builds. We need a way to
# distinguish targets of the same name from different subprojects.
local target-id = [ FGristFiles $(x-target) ] ;
***************
*** 1174,1179 ****
--- 1174,1180 ----
= $(requirements) $(gTARGET_TYPE_REQUIREMENTS($(target-type))) <target-type>$(target-type) ;
local libs ;
local dlls ;
+ local templates ;
for local source in [ select-gristed $(x-sources) ]
{
local grist = [ SUBST $(source:G) (<)(.*)(>) $2 ] ;
***************
*** 1185,1197 ****
{
dlls += $(source:G=) ;
}
}
! gTARGET_LIBS($(target-id)) = $(libs) ;
! gTARGET_DLLS($(target-id)) = $(dlls) ;

gTARGET_SOURCES($(target-id))
= [ FGristFiles
! [ difference $(x-sources:G=) : $(gTARGET_LIBS($(target-id))) $(gTARGET_DLLS($(target-id))) ] ] ;

}
else if $(gTARGET_TYPE($(target-id))) != $(target-type)
--- 1186,1203 ----
{
dlls += $(source:G=) ;
}
+ if $(gTARGET_TYPE_ID($(grist))) = TEMPLATE
+ {
+ templates += $(source:G=) ;
+ }
}
! gTARGET_LIBS($(target-id)) = $(libs) ;
! gTARGET_DLLS($(target-id)) = $(dlls) ;
! gTARGET_TEMPLATES($(target-id)) = $(templates) ;

gTARGET_SOURCES($(target-id))
= [ FGristFiles
! [ difference $(x-sources:G=) : $(gTARGET_LIBS($(target-id))) $(gTARGET_DLLS($(target-id))) $(gTARGET_TEMPLATES($(target-id))) ] ] ;

}
else if $(gTARGET_TYPE($(target-id))) != $(target-type)
***************
*** 1206,1211 ****
--- 1212,1219 ----

declare-fake-targets $(target) : $(target-id) ;

+ evaluate-templates $(target-id) ;
+
# Just gather information if we are including a library's Jamfile for a
# dependent target. Don't generate build instructions here.
if ! $(gIN_LIB_INCLUDE)
***************
*** 1215,1220 ****
--- 1223,1276 ----
return $(gTARGET_FILES($(target-id))) ;
}

+ # declare-local-template name : sources : requirements
+ #
+ # declares a subproject-local template target of the given name.
+ rule declare-local-template ( target : sources * : requirements * )
+ {
+ # We expand out the name of the target and sources
+ local x-target = [ expand-target-names $(target) : TEMPLATE ] ;
+
+ # We add SOURCE_GRIST the base target name here because we're referring the
+ # abstract target which generates all of the actual builds. We need a way to
+ # distinguish targets of the same name from different subprojects.
+ local target-id = [ FGristFiles $(x-target) ] ;
+
+ if ! $(gTARGET_TYPE($(target-id)))
+ {
+ gTARGET_TYPE($(target-id)) = TEMPLATE ;
+ gTARGET_NAME($(target-id)) = $(target) ;
+
+ # Add the specified requirements to any requirements given by the target.
+ gTARGET_REQUIREMENTS($(target-id))
+ = $(requirements) ;
+ local templates ;
+ for local source in $(sources)
+ {
+ local grist = [ SUBST $(source:G) (<)(.*)(>) $2 ] ;
+ if $(gTARGET_TYPE_ID($(grist))) = TEMPLATE
+ {
+ templates += $(source:G=) ;
+ }
+ else
+ {
+ EXIT Only <template> sources allowed for template "$(x-target)" ;
+ }
+ }
+ gTARGET_TEMPLATES($(target-id)) = $(templates) ;
+
+ }
+ else if $(gTARGET_TYPE($(target-id))) != $(target-type)
+ {
+ EXIT conflicting target types for "$(x-target)":
+ "$(gTARGET_TYPE($(target-id)))" "$(target-type)" ;
+ }
+
+ evaluate-templates $(target-id) ;
+
+ return "" ;
+ }
+
# directory-of files...
#
# Returns a list of the directories containing each element of files
***************
*** 1392,1397 ****
--- 1448,1479 ----
return $(result) ;
}

+ # rule grist-templates templates ...
+ #
+ # Returns a list of target-ids for the given template
+ # pathes.
+ #
+ rule grist-templates ( templates + )
+ {
+ local result ;
+
+ for local lib-path in $(templates)
+ {
+ local new-subdir = TOP [ top-relative-tokens [ directory-of $(lib-path) ] ] ;
+
+ # protect global variables from being permanently set by SubDir
+ local [ protect-subdir ] ;
+
+ # Enter the dependee subproject
+ SubDir $(new-subdir) ;
+
+ result += [ FGristFiles $(lib-path:D=) ] ;
+ }
+
+ return $(result) ;
+ }
+
+
# Which configuration(s) to build if nothing is explicitly specified
DEFAULT_BUILD ?= debug ;

***************
*** 1579,1584 ****
--- 1661,1695 ----
return $(gTARGET_FILES($(subvariant))) ;
}

+ # template-target target
+ #
+ # Accumulates requirements from templates for the given targets.
+ #
+ rule evaluate-templates ( target-id-list + )
+ {
+ for local target-id in $(target-id-list)
+ {
+ if ! $(gTEMPLATES_EVALUATED($(target-id)))
+ {
+ # include each jamfile describing a dependee target.
+ dependent-include $(gTARGET_TEMPLATES($(target-id))) ;
+
+ local template-requirements = ;
+
+ if $(gTARGET_TEMPLATES($(target-id)))
+ {
+ local template-ids = [ grist-templates $(gTARGET_TEMPLATES($(target-id))) ] ;
+
+ template-requirements = $(gTARGET_REQUIREMENTS($(template-ids))) ;
+ }
+
+ gTARGET_REQUIREMENTS($(target-id)) = $(template-requirements) $(gTARGET_REQUIREMENTS($(target-id))) ;
+
+ gTEMPLATES_EVALUATED($(target-id)) = true ;
+ }
+ }
+ }
+
# main-target target : local-build
#
# Generates requested subvariant build instructions for the given main target
***************
*** 1649,1654 ****
--- 1760,1777 ----
declare-local-target $(target) : $(sources) : $(requirements) : $(default-build) : LIB ;
}

+ gTARGET_TYPE_ID(template) = TEMPLATE ;
+ gGENERATOR_FUNCTION(TEMPLATE) = ;
+ # template target : sources : requirements : local-build
+ #
+ # Declare a template target.
+ # Template targets can be used to globally define
+ # requirements and builds
+ rule template ( target : sources * : requirements * )
+ {
+ declare-local-template $(target) : $(sources) : $(requirements) ;
+ }
+
# unit-test target : sources : requirements : local-build
#
# Declare an executable target, to be run by tests.
***************
*** 1666,1676 ****
}
}

! # Used to build command files from a list of sources.
! rule build-command-file ( command : sources * )
{
DEPENDS $(command) : $(sources) ;
!
# Check whether there's anything to dump, so that we don't end up
# executing a line of the form:
#
--- 1789,1806 ----
}
}

! # Used to build command files from a list of sources
! # and an optional prefix. The prefix typically contains
! # additional link options like LIBPATH and so on.
! rule build-command-file ( command : prefix * : sources * )
{
+ NOTFILE $(prefix) ;
DEPENDS $(command) : $(sources) ;
! DEPENDS $(command) : $(prefix) ;
! ALWAYS $(prefix) ;
!
! local x-sources = $(prefix) $(sources) ;
!
# Check whether there's anything to dump, so that we don't end up
# executing a line of the form:
#
***************
*** 1679,1695 ****
# on Windows this writes "echo is on." into the command-file,
# which then breaks the link.

! if $(sources[1])
{
# Handle the first target specially, so that the first source file
# will clear the command file
! command-file-dump-1st $(command) : $(sources[1]) ;
}

! if $(sources[2])
{
# Then fill the rest up piecemeal
! command-file-dump-rest $(command) : $(sources[2-]) ;
}
}

--- 1809,1825 ----
# on Windows this writes "echo is on." into the command-file,
# which then breaks the link.

! if $(x-sources[1])
{
# Handle the first target specially, so that the first source file
# will clear the command file
! command-file-dump-1st $(command) : $(x-sources[1]) ;
}

! if $(x-sources[2])
{
# Then fill the rest up piecemeal
! command-file-dump-rest $(command) : $(x-sources[2-]) ;
}
}

***************
*** 1719,1731 ****
# build TARGETS from SOURCES using a command-file, where RULE-NAME is
# used to generate the build instructions from the command-file to
# TARGETS
! rule with-command-file ( rule-name targets * : sources * )
{
# create a command-file target and place it where the first target
# will be built
local command-file = $(targets[1]:S=.CMD) ;
LOCATE on $(command-file) = $(gLOCATE($(targets[1]))) ;
! build-command-file $(command-file) : $(sources) ;

# Build the targets from the command-file instead of the sources
DEPENDS $(targets) : $(command-file) ;
--- 1849,1861 ----
# build TARGETS from SOURCES using a command-file, where RULE-NAME is
# used to generate the build instructions from the command-file to
# TARGETS
! rule with-command-file ( rule-name targets * : sources * : prefix * )
{
# create a command-file target and place it where the first target
# will be built
local command-file = $(targets[1]:S=.CMD) ;
LOCATE on $(command-file) = $(gLOCATE($(targets[1]))) ;
! build-command-file $(command-file) : $(prefix) : $(sources) ;

# Build the targets from the command-file instead of the sources
DEPENDS $(targets) : $(command-file) ;
 --------------Boundary-00=_02C5RNIPHQ4R1EULRDNJ--


Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk