2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-15 00:52:16 +00:00

Add support for junctions on Windows

This commit is contained in:
Steven Watanabe
2014-02-06 14:50:20 -08:00
parent 8dd176f683
commit 7f8aac5d5e
2 changed files with 87 additions and 4 deletions

View File

@@ -1893,6 +1893,28 @@ LIST *builtin_readlink( FRAME * frame, int flags )
cbuf[numchars] = '\0';
return list_new( object_new( cbuf ) );
}
else if( okay && buf.reparse.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT )
{
int index = buf.reparse.MountPointReparseBuffer.SubstituteNameOffset / 2;
int length = buf.reparse.MountPointReparseBuffer.SubstituteNameLength / 2;
char cbuf[MAX_PATH + 1];
const char * result;
int numchars = WideCharToMultiByte( CP_ACP, 0, buf.reparse.MountPointReparseBuffer.PathBuffer + index, length, cbuf, sizeof(cbuf), NULL, NULL );
if( numchars >= sizeof(cbuf) )
{
return 0;
}
cbuf[numchars] = '\0';
/* strip off the leading "\??\" */
result = cbuf;
if ( cbuf[ 0 ] == '\\' && cbuf[ 1 ] == '?' &&
cbuf[ 2 ] == '?' && cbuf[ 3 ] == '\\' &&
cbuf[ 4 ] != '\0' && cbuf[ 5 ] == ':' )
{
result += 4;
}
return list_new( object_new( result ) );
}
return 0;
#else
char static_buf[256];

View File

@@ -60,6 +60,45 @@ rule can-symlink ( project : ps )
}
}
if [ os.name ] = NT
{
# Test for Windows junctions (mklink /J)
rule can-junction ( project : ps )
{
if ! $(.can-junction)
{
local root-project = [ get-root-project $(project) ] ;
local source-target = [ new file-target test-junction-source : :
$(project) : [ new action : common.mkdir ] ] ;
local target = [ new file-target test-junction : :
$(project) : [ new action $(source-target) : link.junction ] ] ;
if [ configure.try-build $(target) : $(ps) : "junctions supported" ]
{
.can-junction = true ;
}
else
{
.can-junction = false ;
}
}
if $(.can-junction) = true
{
return true ;
}
}
}
else
{
rule can-junction ( project : ps )
{
}
}
rule can-hardlink ( project : ps )
{
@@ -149,8 +188,13 @@ class symlink-target-class : basic-target
local files = [ path.glob-tree $(location) : * ] ;
local targets ;
link.can-symlink $(self.project) : $(property-set) ;
link.can-hardlink $(self.project) : $(property-set) ;
# If we have symlinks, don't bother checking
# for hardlinks and junctions.
if ! [ link.can-symlink $(self.project) : $(property-set) ]
{
link.can-junction $(self.project) : $(property-set) ;
link.can-hardlink $(self.project) : $(property-set) ;
}
if [ $(property-set).get <location> ]
{
@@ -216,7 +260,18 @@ rule do-link
}
if [ os.name ] = NT
{
MKLINK_OR_DIR on $(target) = mklink /D \"$(target)\" \"$(relative)\" ;
if $(.can-symlink) = true
{
MKLINK_OR_DIR on $(target) = mklink /D \"$(target)\" \"$(relative)\" ;
}
else
{
# This function should only be called
# if either symlinks or junctions are supported.
# To get here $(.can-junction) must be true.
mklink-opt = /J ;
MKLINK_OR_DIR on $(target) = mklink /J \"$(target)\" \"$(source)\" ;
}
}
else
{
@@ -329,7 +384,7 @@ rule link-recursively ( target : source : no-recurse ? )
split = true ;
}
}
else if $(.can-symlink) = false
else if $(.can-symlink) = false && $(.can-junction) = false
{
if [ READLINK [ path.native $(target) ] ]
{
@@ -384,6 +439,12 @@ rule mklink
if [ os.name ] = NT
{
actions junction
{
if exist "$(<)" del "$(<)"
mklink /J "$(<)" "$(>)"
}
actions mklink
{
if exist "$(<)" del "$(<)"