mirror of
https://git.rtems.org/rtems-source-builder
synced 2024-10-09 07:15:10 +08:00
sb: Fix long path support in the copy_tree and removeall path support.
This change lets the LM32 target build on Windows which has temporary install paths greated than the Win32 API max size. The buildroot path compression is still needed as the GNU assembler does not like paths that exceed the max Windows limit. Closes #2992.
This commit is contained in:
parent
2433c4bd5f
commit
78c152453b
@ -34,6 +34,7 @@ import string
|
|||||||
import error
|
import error
|
||||||
|
|
||||||
windows = os.name == 'nt'
|
windows = os.name == 'nt'
|
||||||
|
win_maxpath = 254
|
||||||
|
|
||||||
def host(path):
|
def host(path):
|
||||||
if path is not None:
|
if path is not None:
|
||||||
@ -46,13 +47,16 @@ def host(path):
|
|||||||
path[1] in string.ascii_uppercase):
|
path[1] in string.ascii_uppercase):
|
||||||
path = '%s:%s' % (path[1], path[2:])
|
path = '%s:%s' % (path[1], path[2:])
|
||||||
path = path.replace('/', '\\')
|
path = path.replace('/', '\\')
|
||||||
if not path.startswith('\\\\?\\') and len(path) > 254:
|
if len(path) > win_maxpath:
|
||||||
path = '\\\\?\\' + path
|
if path.startswith('\\\\?\\'):
|
||||||
|
path = path[4:]
|
||||||
|
path = u'\\'.join([u'\\\\?', path])
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def shell(path):
|
def shell(path):
|
||||||
if path is not None:
|
if path is not None:
|
||||||
if windows:
|
if windows:
|
||||||
|
path = path.encode('ascii', 'ignore')
|
||||||
if path.startswith('\\\\?\\'):
|
if path.startswith('\\\\?\\'):
|
||||||
path = path[4:]
|
path = path[4:]
|
||||||
if len(path) > 1 and path[1] == ':':
|
if len(path) > 1 and path[1] == ':':
|
||||||
@ -84,13 +88,22 @@ def splitext(path):
|
|||||||
root, ext = os.path.splitext(host(path))
|
root, ext = os.path.splitext(host(path))
|
||||||
return shell(root), ext
|
return shell(root), ext
|
||||||
|
|
||||||
|
def listdir(path):
|
||||||
|
hp = host(path)
|
||||||
|
if not os.path.exists(hp):
|
||||||
|
return []
|
||||||
|
return os.listdir(hp)
|
||||||
|
|
||||||
def exists(paths):
|
def exists(paths):
|
||||||
|
def _exists(p):
|
||||||
|
return os.path.basename(p) in listdir(dirname(p))
|
||||||
|
|
||||||
if type(paths) == list:
|
if type(paths) == list:
|
||||||
results = []
|
results = []
|
||||||
for p in paths:
|
for p in paths:
|
||||||
results += [os.path.exists(host(p))]
|
results += [_exists(p)]
|
||||||
return results
|
return results
|
||||||
return os.path.exists(host(paths))
|
return _exists(paths)
|
||||||
|
|
||||||
def isdir(path):
|
def isdir(path):
|
||||||
return os.path.isdir(host(path))
|
return os.path.isdir(host(path))
|
||||||
@ -107,7 +120,7 @@ def iswritable(path):
|
|||||||
def ispathwritable(path):
|
def ispathwritable(path):
|
||||||
path = host(path)
|
path = host(path)
|
||||||
while len(path) != 0:
|
while len(path) != 0:
|
||||||
if os.path.exists(path):
|
if exists(path):
|
||||||
return iswritable(path)
|
return iswritable(path)
|
||||||
path = os.path.dirname(path)
|
path = os.path.dirname(path)
|
||||||
return False
|
return False
|
||||||
@ -135,33 +148,48 @@ def mkdir(path):
|
|||||||
except OSError as err:
|
except OSError as err:
|
||||||
raise error.general('cannot make directory: %s' % (path))
|
raise error.general('cannot make directory: %s' % (path))
|
||||||
|
|
||||||
|
def chdir(path):
|
||||||
|
os.chdir(host(path))
|
||||||
|
|
||||||
def removeall(path):
|
def removeall(path):
|
||||||
#
|
#
|
||||||
# Perform the removal of the directory tree manually so we can
|
# Perform the removal of the directory tree manually so we can
|
||||||
# make sure on Windows the files and correctly encoded to avoid
|
# make sure on Windows the files are correctly encoded to avoid
|
||||||
# the size limit.
|
# the file name size limit. On Windows the os.walk fails once we
|
||||||
|
# get to the max path length on Windows.
|
||||||
#
|
#
|
||||||
path = host(path)
|
def _isdir(path):
|
||||||
for root, dirs, files in os.walk(path, topdown = False):
|
hpath = host(path)
|
||||||
for name in files:
|
return os.path.isdir(hpath) and not os.path.islink(hpath)
|
||||||
file = host(os.path.join(root, name))
|
|
||||||
if not os.path.islink(file) and not os.access(file, os.W_OK):
|
def _remove_node(path):
|
||||||
os.chmod(file, stat.S_IWUSR)
|
hpath = host(path)
|
||||||
os.unlink(file)
|
if not os.path.islink(hpath) and not os.access(hpath, os.W_OK):
|
||||||
for name in dirs:
|
os.chmod(hpath, stat.S_IWUSR)
|
||||||
dir = host(os.path.join(root, name))
|
if _isdir(path):
|
||||||
if os.path.islink(dir):
|
os.rmdir(hpath)
|
||||||
os.unlink(dir)
|
else:
|
||||||
|
os.unlink(hpath)
|
||||||
|
|
||||||
|
def _remove(path):
|
||||||
|
dirs = []
|
||||||
|
for name in listdir(path):
|
||||||
|
path_ = join(path, name)
|
||||||
|
hname = host(path_)
|
||||||
|
if _isdir(path_):
|
||||||
|
dirs += [name]
|
||||||
else:
|
else:
|
||||||
if not os.access(dir, os.W_OK):
|
_remove_node(path_)
|
||||||
os.chmod(dir, stat.S_IWUSR)
|
for name in dirs:
|
||||||
os.rmdir(dir)
|
dir = join(path, name)
|
||||||
if not os.path.islink(path) and not os.access(path, os.W_OK):
|
_remove(dir)
|
||||||
os.chmod(path, stat.S_IWUSR)
|
_remove_node(dir)
|
||||||
if os.path.islink(path):
|
|
||||||
os.unlink(path)
|
hpath = host(path)
|
||||||
else:
|
|
||||||
os.rmdir(path)
|
if os.path.exists(hpath):
|
||||||
|
_remove(path)
|
||||||
|
_remove_node(path)
|
||||||
|
|
||||||
def expand(name, paths):
|
def expand(name, paths):
|
||||||
l = []
|
l = []
|
||||||
@ -187,17 +215,17 @@ def copy_tree(src, dst):
|
|||||||
hsrc = host(src)
|
hsrc = host(src)
|
||||||
hdst = host(dst)
|
hdst = host(dst)
|
||||||
|
|
||||||
if os.path.exists(hsrc):
|
if exists(hsrc):
|
||||||
names = os.listdir(hsrc)
|
names = listdir(hsrc)
|
||||||
else:
|
else:
|
||||||
names = []
|
names = []
|
||||||
|
|
||||||
if trace:
|
if trace:
|
||||||
print('path.copy_tree:')
|
print('path.copy_tree:')
|
||||||
print(' src: %s' % (src))
|
print(' src: "%s"' % (src))
|
||||||
print(' hsrc: %s' % (hsrc))
|
print(' hsrc: "%s"' % (hsrc))
|
||||||
print(' dst: %s' % (dst))
|
print(' dst: "%s"' % (dst))
|
||||||
print(' hdst: %s' % (hdst))
|
print(' hdst: "%s"' % (hdst))
|
||||||
print(' names: %r' % (names))
|
print(' names: %r' % (names))
|
||||||
|
|
||||||
if not os.path.isdir(hdst):
|
if not os.path.isdir(hdst):
|
||||||
@ -215,7 +243,7 @@ def copy_tree(src, dst):
|
|||||||
try:
|
try:
|
||||||
if os.path.islink(srcname):
|
if os.path.islink(srcname):
|
||||||
linkto = os.readlink(srcname)
|
linkto = os.readlink(srcname)
|
||||||
if os.path.exists(dstname):
|
if exists(dstname):
|
||||||
if os.path.islink(dstname):
|
if os.path.islink(dstname):
|
||||||
dstlinkto = os.readlink(dstname)
|
dstlinkto = os.readlink(dstname)
|
||||||
if linkto != dstlinkto:
|
if linkto != dstlinkto:
|
||||||
@ -231,7 +259,8 @@ def copy_tree(src, dst):
|
|||||||
elif os.path.isdir(srcname):
|
elif os.path.isdir(srcname):
|
||||||
copy_tree(srcname, dstname)
|
copy_tree(srcname, dstname)
|
||||||
else:
|
else:
|
||||||
shutil.copy2(host(srcname), host(dstname))
|
shutil.copyfile(host(srcname), host(dstname))
|
||||||
|
shutil.copystat(host(srcname), host(dstname))
|
||||||
except shutil.Error as err:
|
except shutil.Error as err:
|
||||||
raise error.general('copying tree: %s -> %s: %s' % \
|
raise error.general('copying tree: %s -> %s: %s' % \
|
||||||
(hsrc, hdst, str(err)))
|
(hsrc, hdst, str(err)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user