Boost logo

Boost-Build :

From: Jonathan Biggar (jon_at_[hidden])
Date: 2008-07-26 12:28:20


Jurko Gospodnetić wrote:
> Hi Andrej.
>
>> Is it possible to create an empty directory in the
>> install command?
>
> I do not think so.
>
> I played with this a bit and the only way I managed to add an empty
> folder was to add the following raw Boost Jam target:
>
> import common ;
> DEPENDS all : my_folder ;
> common.MkDir my_folder ;
>
> If anyone has any interface suggestions for 'installing an empty
> folder' I'd be glad to hear them. It should not be difficult to implement.
>
> I added a trac ticket for this under:
>
> http://zigzag.cs.msu.su/boost.build/ticket/191

I found I had a need for this too, so I modified stage.jam to export an
install-dir rule that you can use like this:

install-dir foo : <location>/path/to/parent/directory ;

I've attached a patch.

-- 
Jon Biggar
Floorboard Software
jon_at_[hidden]
jon_at_[hidden]

==== //depot/orb_main/corba/tools/build/v2/tools/stage.jam#1 - /home/corvette/jon/work/corba/tools/build/v2/tools/stage.jam ====
@@ -320,7 +320,126 @@
     return $(targets) ;
 }
 
+class install-dir-target-class : basic-target
+{
+ import feature ;
+ import project ;
+ import type ;
+ import errors ;
+ import generators ;
+ import path ;
+ import stage ;
+ import "class" : new ;
+ import property ;
+ import property-set ;
+
+ rule __init__ ( name-and-dir : project : requirements * : default-build * )
+ {
+ basic-target.__init__ $(name-and-dir) : $(project) : : $(requirements)
+ : $(default-build) ;
+ }
+
+ # If <location> is not set, sets it based on the project data.
+ rule update-location ( property-set )
+ {
+ local loc = [ $(property-set).get <location> ] ;
+ if ! $(loc)
+ {
+ loc = [ path.root $(self.name) [ $(self.project).get location ] ] ;
+
+ property-set = [ $(property-set).add-raw $(loc:G=<location>) ] ;
+ }
+
+ return $(property-set) ;
+ }
+
+ rule construct ( name : source-targets * : property-set )
+ {
+ source-targets = [
+ targets-to-stage $(source-targets) : $(property-set) ] ;
+
+ property-set = [ update-location $(property-set) ] ;
+
+ local ename = [ $(property-set).get <name> ] ;
+
+ if $(ename) && $(source-targets[2])
+ {
+ errors.error
+ "When <name> property is used in 'install', only one source is allowed" ;
+ }
+
+ local result ;
 
+ staged-targets = [ stage.make-dir $(self.project) $(name)
+ : $(i) : $(property-set) ] ;
+
+ if ! $(staged-targets)
+ {
+ errors.error "Unable to generate staged version of " [ $(source).str ] ;
+ }
+ for t in $(staged-targets)
+ {
+ result += [ virtual-target.register $(t) ] ;
+ }
+
+ return [ property-set.empty ] $(result) ;
+ }
+
+ # Given the list of source targets explicitly passed to 'stage',
+ # returns the list of targets which must be staged.
+ rule targets-to-stage ( source-targets * : property-set )
+ {
+ # Traverse the dependencies, if needed.
+ if [ $(property-set).get <install-dependencies> ] = "on"
+ {
+ source-targets = [ collect-targets $(source-targets) ] ;
+ }
+
+ return $(source-targets) ;
+ }
+
+ # CONSIDER: figure out why we can't use virtual-target.traverse here.
+ rule collect-targets ( targets * )
+ {
+ # Find subvariants
+ local s ;
+ for local t in $(targets)
+ {
+ s += [ $(t).creating-subvariant ] ;
+ }
+ s = [ sequence.unique $(s) ] ;
+
+ local result = $(targets) ;
+ for local i in $(s)
+ {
+ result += [ $(i).all-referenced-targets ] ;
+ }
+ local result2 ;
+ for local r in $(result)
+ {
+ if $(r:G) != <use>
+ {
+ result2 += $(r:G=) ;
+ }
+ }
+ result = [ sequence.unique $(result2) ] ;
+ }
+}
+
+# Creates a directory at the specified <location>.
+rule make-dir ( project name ? : source * : properties * )
+{
+ local targets ;
+
+ new-a = [
+ new non-scanning-action : common.MkDir : $(properties) ] ;
+
+ targets = [ new file-target $(name:D=) exact : DIR
+ : $(project) : $(new-a) ] ;
+
+ return $(targets) ;
+}
+
 rule symlink ( name : project : source : properties )
 {
     local a = [ new action $(source) : symlink.ln :
@@ -476,7 +595,6 @@
 
 generators.register [ new installed-shared-lib-generator ] ;
 
-
 # Main target rule for 'install'.
 rule install ( name : sources * : requirements * : default-build * )
 {
@@ -504,5 +622,24 @@
       ] ;
 }
 
+# Main target rule for 'install-dir'.
+rule install-dir ( name : requirements * : default-build * )
+{
+ local project = [ project.current ] ;
+
+ if <tag> in $(requirements:G)
+ {
+ errors.user-error
+ "The <tag> property is not allowed for the 'install-dir' rule" ;
+ }
+
+ targets.main-target-alternative
+ [ new install-dir-target-class $(name) : $(project)
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
+ : [ targets.main-target-default-build $(default-build) : $(project) ]
+ ] ;
+}
+
 IMPORT $(__name__) : install : : install ;
+IMPORT $(__name__) : install-dir : : install-dir ;
 IMPORT $(__name__) : install : : stage ;


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