bfgroup / b2

B2 makes it easy to build C++ projects, everywhere.
https://www.bfgroup.xyz/b2/
Boost Software License 1.0
80 stars 228 forks source link

:D vs :P vs dirname difference #232

Open Kojoley opened 1 year ago

Kojoley commented 1 year ago

The documentation is unclear about what :D and :P are, and what are the differences between them and compared to dirname.

:D
Select directory path.

:P
Select parent directory.

Comparison:

local dot = "." ;
ECHO ".:D =" $(dot:D) ;
ECHO ".:P =" $(dot:P) ;
ECHO "dirname . =" [ SHELL "dirname ." ] ;

local doubledot = "." ;
ECHO "..:D =" $(doubledot:D) ;
ECHO "..:P =" $(doubledot:P) ;
ECHO "dirname .. =" [ SHELL "dirname .." ] ;

local abc = "a/b/c" ;
ECHO "a/b/c:D =" $(abc:D) ;
ECHO "a/b/c:P =" $(abc:P) ;
ECHO "dirname a/b/c =" [ SHELL "dirname a/b/c" ] ;

local ab = "a/b/" ;
ECHO "a/b/:D =" $(ab:D) ;
ECHO "a/b/:P =" $(ab:P) ;
ECHO "dirname a/b/ =" [ SHELL "dirname a/b/" ] ;

local rootabc = "/a/b/c" ;
ECHO "/a/b/c:D =" $(rootabc:D) ;
ECHO "/a/b/c:P =" $(rootabc:P) ;
ECHO "dirname /a/b/c =" [ SHELL "dirname /a/b/c" ] ;

local rootab = "/a/b/" ;
ECHO "/a/b/:D =" $(rootab:D) ;
ECHO "/a/b/:P =" $(rootab:P) ;
ECHO "dirname /a/b/ =" [ SHELL "dirname /a/b/" ] ;
func\path . .. a/b/c /a/b/c a/b/ /a/b/
:D a/b /a/b a/b /a/b
:P a/b /a/b a/b /a/b
dirname . . a/b /a/b a /a

So there is no difference between :D and :P? I would expect that at least one of them provide the dirname functionality.

grafikrobot commented 1 year ago

IIRC the difference was only applicable to VMS system. But I truly don't know if that's relevant any longer. For a long time I've treated D and P as the same.

Kojoley commented 1 year ago

There is definitely a broken code because :D could return an empty string:

./src/tools/asciidoctor.jam:    "$(ASCIIDOCTOR)" -o$(_)"$(<:D=)" -D$(_)"$(<:D)" -b$(_)"$(BACKEND)" -a$(_)"$(ATTRIBUTE)" -d$(_)"$(DOCTYPE)" $(FLAGS) "$(>)"
./src/tools/doxygen.jam:        .doxproc = $(.doxproc:D)/doxproc.py ;
./src/tools/doxygen.jam:        TOPDF on $(target) = $(target:D)/$(directory) ;
./src/tools/mc.jam:    mc $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
./src/tools/python.jam:                $(libraries:D)/Lib ] ;
./src/tools/xsltproc.jam:    $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --path$(_)"$(XSL-PATH:W)" --xinclude -o "$(<:D)/" "$(STYLESHEET:W)" "$(>:W)"
./src/tools/xsltproc.jam:    $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --path$(_)"$(XSL-PATH:T)" --xinclude -o "$(<:D)/" "$(STYLESHEET:T)" "$(>:T)"
./src/tools/whale.jam:    $(.whale) -d $(<[1]:D) $(>)
./src/tools/whale.jam:    $(.dolphin) -d $(<[1]:D) $(>)
./src/tools/whale.jam:    $(.wd) -d $(<[1]:D) -g $(>)

But there is also a code that relies on such behavior:

./src/build/project.jam:        if $(wildcards:D) || $(excludes:D)
./src/tools/docutils.jam:            if $(RST2XXX_PY:D)
./src/tools/vmsdecc.jam:
    for local d in $(sources:D) $(includes)
    {
        if $(d)
        {

grep --color -E '\$\([^:\)]+:D[^=\)]*\)' -R .