aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/scripts/meson_install.py62
-rw-r--r--mesonbuild/scripts/uninstall.py5
2 files changed, 50 insertions, 17 deletions
diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py
index 35904ea..f61cbab 100644
--- a/mesonbuild/scripts/meson_install.py
+++ b/mesonbuild/scripts/meson_install.py
@@ -21,6 +21,35 @@ from ..mesonlib import is_windows, Popen_safe
install_log_file = None
use_selinux = True
+class DirMaker:
+ def __init__(self):
+ self.dirs = []
+
+ def makedirs(self, path, exist_ok=False):
+ dirname = os.path.normpath(path)
+ dirs = []
+ while dirname != os.path.dirname(dirname):
+ if not os.path.exists(dirname):
+ dirs.append(dirname)
+ dirname = os.path.dirname(dirname)
+ os.makedirs(path, exist_ok=exist_ok)
+
+ # store the directories in creation order, with the parent directory
+ # before the child directories. Future calls of makedir() will not
+ # create the parent directories, so the last element in the list is
+ # the last one to be created. That is the first one to be removed on
+ # __exit__
+ dirs.reverse()
+ self.dirs += dirs
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.dirs.reverse()
+ for d in self.dirs:
+ append_to_log(d)
+
def set_mode(path, mode):
if mode is None:
# Keep mode unchanged
@@ -99,7 +128,7 @@ def do_copyfile(from_file, to_file):
restore_selinux_context(to_file)
append_to_log(to_file)
-def do_copydir(src_prefix, src_dir, dst_dir):
+def do_copydir(data, src_prefix, src_dir, dst_dir):
'''
Copies the directory @src_prefix (full path) into @dst_dir
@@ -115,7 +144,7 @@ def do_copydir(src_prefix, src_dir, dst_dir):
if os.path.exists(abs_dst):
print('Tried to copy directory %s but a file of that name already exists.' % abs_dst)
sys.exit(1)
- os.makedirs(abs_dst)
+ data.dirmaker.makedirs(abs_dst)
shutil.copystat(abs_src, abs_dst)
for f in files:
abs_src = os.path.join(src_dir, root, f)
@@ -145,12 +174,14 @@ def do_install(datafilename):
d.destdir = os.environ.get('DESTDIR', '')
d.fullprefix = destdir_join(d.destdir, d.prefix)
- install_subdirs(d) # Must be first, because it needs to delete the old subtree.
- install_targets(d)
- install_headers(d)
- install_man(d)
- install_data(d)
- run_install_script(d)
+ d.dirmaker = DirMaker()
+ with d.dirmaker:
+ install_subdirs(d) # Must be first, because it needs to delete the old subtree.
+ install_targets(d)
+ install_headers(d)
+ install_man(d)
+ install_data(d)
+ run_install_script(d)
def install_subdirs(d):
for (src_dir, inst_dir, dst_dir, mode) in d.install_subdirs:
@@ -159,9 +190,8 @@ def install_subdirs(d):
src_prefix = os.path.join(src_dir, inst_dir)
print('Installing subdir %s to %s' % (src_prefix, dst_dir))
dst_dir = get_destdir_path(d, dst_dir)
- if not os.path.exists(dst_dir):
- os.makedirs(dst_dir)
- do_copydir(src_prefix, src_dir, dst_dir)
+ d.dirmaker.makedirs(dst_dir, exist_ok=True)
+ do_copydir(d, src_prefix, src_dir, dst_dir)
dst_prefix = os.path.join(dst_dir, inst_dir)
set_mode(dst_prefix, mode)
@@ -171,7 +201,7 @@ def install_data(d):
outfilename = get_destdir_path(d, i[1])
mode = i[2]
outdir = os.path.split(outfilename)[0]
- os.makedirs(outdir, exist_ok=True)
+ d.dirmaker.makedirs(outdir, exist_ok=True)
print('Installing %s to %s' % (fullfilename, outdir))
do_copyfile(fullfilename, outfilename)
set_mode(outfilename, mode)
@@ -181,7 +211,7 @@ def install_man(d):
full_source_filename = m[0]
outfilename = get_destdir_path(d, m[1])
outdir = os.path.split(outfilename)[0]
- os.makedirs(outdir, exist_ok=True)
+ d.dirmaker.makedirs(outdir, exist_ok=True)
print('Installing %s to %s' % (full_source_filename, outdir))
if outfilename.endswith('.gz') and not full_source_filename.endswith('.gz'):
with open(outfilename, 'wb') as of:
@@ -199,7 +229,7 @@ def install_headers(d):
outdir = get_destdir_path(d, t[1])
outfilename = os.path.join(outdir, fname)
print('Installing %s to %s' % (fname, outdir))
- os.makedirs(outdir, exist_ok=True)
+ d.dirmaker.makedirs(outdir, exist_ok=True)
do_copyfile(fullfilename, outfilename)
def run_install_script(d):
@@ -264,7 +294,7 @@ def install_targets(d):
should_strip = t[3]
install_rpath = t[4]
print('Installing %s to %s' % (fname, outname))
- os.makedirs(outdir, exist_ok=True)
+ d.dirmaker.makedirs(outdir, exist_ok=True)
if not os.path.exists(fname):
raise RuntimeError('File {!r} could not be found'.format(fname))
elif os.path.isfile(fname):
@@ -287,7 +317,7 @@ def install_targets(d):
do_copyfile(pdb_filename, pdb_outname)
elif os.path.isdir(fname):
fname = os.path.join(d.build_dir, fname.rstrip('/'))
- do_copydir(fname, os.path.dirname(fname), outdir)
+ do_copydir(d, fname, os.path.dirname(fname), outdir)
else:
raise RuntimeError('Unknown file type for {!r}'.format(fname))
printed_symlink_error = False
diff --git a/mesonbuild/scripts/uninstall.py b/mesonbuild/scripts/uninstall.py
index 1480921..bdc036b 100644
--- a/mesonbuild/scripts/uninstall.py
+++ b/mesonbuild/scripts/uninstall.py
@@ -24,7 +24,10 @@ def do_uninstall(log):
continue
fname = line.strip()
try:
- os.unlink(fname)
+ if os.path.isdir(fname) and not os.path.islink(fname):
+ os.rmdir(fname)
+ else:
+ os.unlink(fname)
print('Deleted:', fname)
successes += 1
except Exception as e: