Windows: Symlink support

To provide Windows-compatible functionality, spack code should use
llnl.util.symlink instead of os.symlink. On non-Windows platforms
and on Windows where supported, os.symlink will still be used.

Use junctions when symlinks aren't supported on Windows (#22583)

Support islink for junctions (#24182)

Windows: Update llnl/util/filesystem

* Use '/' as path separator on Windows.
* Recognizing that Windows paths start with '<Letter>:/' instead of '/'

Co-authored-by: lou.lawrence@kitware.com <lou.lawrence@kitware.com>
Co-authored-by: John Parent <john.parent@kitware.com>
This commit is contained in:
Betsy McPhail
2021-10-22 12:16:11 -04:00
committed by Peter Scheibel
parent a7de2fa380
commit fb0e91c534
20 changed files with 224 additions and 44 deletions

View File

@@ -6,6 +6,8 @@
from macholib import mach_o
from llnl.util.symlink import symlink
MAGIC = [
struct.pack("!L", getattr(mach_o, "MH_" + _))
for _ in ["MAGIC", "CIGAM", "MAGIC_64", "CIGAM_64"]
@@ -140,7 +142,7 @@ def mergetree(src, dst, condition=None, copyfn=mergecopy, srcbase=None):
try:
if os.path.islink(srcname):
realsrc = os.readlink(srcname)
os.symlink(realsrc, dstname)
symlink(realsrc, dstname)
elif os.path.isdir(srcname):
mergetree(
srcname,

View File

@@ -12,6 +12,8 @@
from os.path import abspath, normpath, isabs, exists, isdir, isfile, islink, dirname
from llnl.util.symlink import symlink
if sys.version_info > (3,0):
def map_as_list(func, iter):
return list(map(func, iter))
@@ -79,7 +81,7 @@ def mklinkto(self, oldname):
def mksymlinkto(self, value, absolute=1):
""" create a symbolic link with the given value (pointing to another name). """
if absolute:
py.error.checked_call(os.symlink, str(value), self.strpath)
py.error.checked_call(symlink, str(value), self.strpath)
else:
base = self.common(value)
# with posix local paths '/' is always a common base
@@ -87,7 +89,7 @@ def mksymlinkto(self, value, absolute=1):
reldest = self.relto(base)
n = reldest.count(self.sep)
target = self.sep.join(('..', )*n + (relsource, ))
py.error.checked_call(os.symlink, target, self.strpath)
py.error.checked_call(symlink, target, self.strpath)
def getuserid(user):
import pwd
@@ -892,7 +894,7 @@ def try_remove_lockfile():
except OSError:
pass
try:
os.symlink(src, dest)
symlink(src, dest)
except (OSError, AttributeError, NotImplementedError):
pass