| # Copyright 2003 Dave Abrahams |
| # Copyright 2002, 2003 Rene Rivera |
| # Copyright 2002, 2003, 2004, 2005 Vladimir Prus |
| # 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) |
| |
| # Defines the "symlink" special target. 'symlink' targets make symbolic links |
| # to the sources. |
| |
| import targets modules path class os feature project property-set ; |
| |
| .count = 0 ; |
| |
| feature.feature symlink-location : project-relative build-relative : incidental ; |
| |
| # The class representing "symlink" targets. |
| # |
| class symlink-targets : basic-target |
| { |
| import numbers modules class property project path ; |
| |
| rule __init__ ( |
| project |
| : targets * |
| : sources * |
| ) |
| { |
| # Generate a fake name for now. Need unnamed targets eventually. |
| local c = [ modules.peek symlink : .count ] ; |
| modules.poke symlink : .count : [ numbers.increment $(c) ] ; |
| local fake-name = symlink#$(c) ; |
| |
| basic-target.__init__ $(fake-name) : $(project) : $(sources) ; |
| |
| # Remember the targets to map the sources onto. Pad or truncate |
| # to fit the sources given. |
| self.targets = ; |
| for local source in $(sources) |
| { |
| if $(targets) |
| { |
| self.targets += $(targets[1]) ; |
| targets = $(targets[2-]) ; |
| } |
| else |
| { |
| self.targets += $(source) ; |
| } |
| } |
| |
| # The virtual targets corresponding to the given targets. |
| self.virtual-targets = ; |
| } |
| |
| rule construct ( name : source-targets * : property-set ) |
| { |
| local i = 1 ; |
| for local t in $(source-targets) |
| { |
| local s = $(self.targets[$(i)]) ; |
| local a = [ class.new action $(t) : symlink.ln : $(property-set) ] ; |
| local vt = [ class.new file-target $(s:D=) |
| : [ $(t).type ] : $(self.project) : $(a) ] ; |
| |
| # Place the symlink in the directory relative to the project |
| # location, instead of placing it in the build directory. |
| if [ property.select <symlink-location> : [ $(property-set).raw ] ] = <symlink-location>project-relative |
| { |
| $(vt).set-path [ path.root $(s:D) [ $(self.project).get location ] ] ; |
| } |
| |
| self.virtual-targets += $(vt) ; |
| i = [ numbers.increment $(i) ] ; |
| } |
| return [ property-set.empty ] $(self.virtual-targets) ; |
| } |
| } |
| |
| # Creates a symbolic link from a set of targets to a set of sources. |
| # The targets and sources map one to one. The symlinks generated are |
| # limited to be the ones given as the sources. That is, the targets |
| # are either padded or trimmed to equate to the sources. The padding |
| # is done with the name of the corresponding source. For example:: |
| # |
| # symlink : one two ; |
| # |
| # Is equal to:: |
| # |
| # symlink one two : one two ; |
| # |
| # Names for symlink are relative to the project location. They cannot |
| # include ".." path components. |
| rule symlink ( |
| targets * |
| : sources * |
| ) |
| { |
| local project = [ project.current ] ; |
| |
| return [ targets.main-target-alternative |
| [ class.new symlink-targets $(project) : $(targets) : |
| # Note: inline targets are not supported for symlink, intentionally, |
| # since it's used to linking existing non-local targets. |
| $(sources) ] ] ; |
| } |
| |
| rule ln |
| { |
| local os ; |
| if [ modules.peek : UNIX ] { os = UNIX ; } |
| else { os ?= [ os.name ] ; } |
| # Remember the path to make the link relative to where the symlink is located. |
| local path-to-source = [ path.relative-to |
| [ path.make [ on $(<) return $(LOCATE) ] ] |
| [ path.make [ on $(>) return $(LOCATE) ] ] ] ; |
| if $(path-to-source) = . |
| { |
| PATH_TO_SOURCE on $(<) = "" ; |
| } |
| else |
| { |
| PATH_TO_SOURCE on $(<) = [ path.native $(path-to-source) ] ; |
| } |
| ln-$(os) $(<) : $(>) ; |
| } |
| |
| actions ln-UNIX |
| { |
| ln -f -s '$(>:D=:R=$(PATH_TO_SOURCE))' '$(<)' |
| } |
| |
| # there is a way to do this; we fall back to a copy for now |
| actions ln-NT |
| { |
| echo "NT symlinks not supported yet, making copy" |
| del /f /q "$(<)" 2>nul >nul |
| copy "$(>)" "$(<)" $(NULL_OUT) |
| } |
| |
| IMPORT $(__name__) : symlink : : symlink ; |