aboutsummaryrefslogtreecommitdiff
path: root/meson/meson_install.py
diff options
context:
space:
mode:
Diffstat (limited to 'meson/meson_install.py')
-rwxr-xr-xmeson/meson_install.py227
1 files changed, 227 insertions, 0 deletions
diff --git a/meson/meson_install.py b/meson/meson_install.py
new file mode 100755
index 0000000..c5c17ba
--- /dev/null
+++ b/meson/meson_install.py
@@ -0,0 +1,227 @@
+#!/usr/bin/env python3
+
+# Copyright 2013-2014 The Meson development team
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys, pickle, os, shutil, subprocess, gzip, platform
+from glob import glob
+
+class InstallData():
+ def __init__(self, source_dir, build_dir, prefix, depfixer):
+ self.source_dir = source_dir
+ self.build_dir= build_dir
+ self.prefix = prefix
+ self.targets = []
+ self.depfixer = depfixer
+ self.headers = []
+ self.man = []
+ self.data = []
+ self.po_package_name = ''
+ self.po = []
+ self.install_scripts = []
+ self.install_subdirs = []
+
+def do_install(datafilename):
+ ifile = open(datafilename, 'rb')
+ d = pickle.load(ifile)
+ destdir_var = 'DESTDIR'
+ if destdir_var in os.environ:
+ d.destdir = os.environ[destdir_var]
+ else:
+ d.destdir = ''
+ d.fullprefix = 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)
+ install_po(d)
+ run_install_script(d)
+
+def install_subdirs(d):
+ for (src_dir, dst_dir) in d.install_subdirs:
+ if os.path.isabs(dst_dir):
+ dst_dir = d.destdir + dst_dir
+ else:
+ dst_dir = d.fullprefix + dst_dir
+ # Python's copytree works in strange ways.
+ last_level = os.path.split(src_dir)[-1]
+ final_dst = os.path.join(dst_dir, last_level)
+# Don't do rmtree because final_dst might point to e.g. /var/www
+# We might need to revert to walking the directory tree by hand.
+# shutil.rmtree(final_dst, ignore_errors=True)
+ shutil.copytree(src_dir, final_dst, symlinks=True)
+ print('Installing subdir %s to %s.' % (src_dir, dst_dir))
+
+def install_po(d):
+ packagename = d.po_package_name
+ for f in d.po:
+ srcfile = f[0]
+ localedir = f[1]
+ languagename = f[2]
+ outfile = os.path.join(d.fullprefix, localedir, languagename, 'LC_MESSAGES',
+ packagename + '.mo')
+ os.makedirs(os.path.split(outfile)[0], exist_ok=True)
+ shutil.copyfile(srcfile, outfile)
+ shutil.copystat(srcfile, outfile)
+ print('Installing %s to %s.' % (srcfile, outfile))
+
+def install_data(d):
+ for i in d.data:
+ fullfilename = i[0]
+ outfilename = i[1]
+ if os.path.isabs(outfilename):
+ outdir = d.destdir + os.path.split(outfilename)[0]
+ outfilename = d.destdir + outfilename
+ else:
+ outdir = os.path.join(d.fullprefix, os.path.split(outfilename)[0])
+ outfilename = os.path.join(outdir, os.path.split(outfilename)[1])
+ os.makedirs(outdir, exist_ok=True)
+ print('Installing %s to %s.' % (fullfilename, outdir))
+ shutil.copyfile(fullfilename, outfilename)
+ shutil.copystat(fullfilename, outfilename)
+
+def install_man(d):
+ for m in d.man:
+ outfileroot = m[1]
+ outfilename = os.path.join(d.fullprefix, outfileroot)
+ full_source_filename = m[0]
+ outdir = os.path.split(outfilename)[0]
+ os.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'):
+ open(outfilename, 'wb').write(gzip.compress(open(full_source_filename, 'rb').read()))
+ else:
+ shutil.copyfile(full_source_filename, outfilename)
+ shutil.copystat(full_source_filename, outfilename)
+
+def install_headers(d):
+ for t in d.headers:
+ fullfilename = t[0]
+ outdir = os.path.join(d.fullprefix, t[1])
+ fname = os.path.split(fullfilename)[1]
+ outfilename = os.path.join(outdir, fname)
+ print('Installing %s to %s' % (fname, outdir))
+ os.makedirs(outdir, exist_ok=True)
+ shutil.copyfile(fullfilename, outfilename)
+ shutil.copystat(fullfilename, outfilename)
+
+def run_install_script(d):
+ env = {'MESON_SOURCE_ROOT' : d.source_dir,
+ 'MESON_BUILD_ROOT' : d.build_dir,
+ 'MESON_INSTALL_PREFIX' : d.prefix
+ }
+ child_env = os.environ.copy()
+ child_env.update(env)
+
+ for i in d.install_scripts:
+ script = i.cmd_arr[0]
+ print('Running custom install script %s' % script)
+ suffix = os.path.splitext(script)[1].lower()
+ if platform.system().lower() == 'windows' and suffix != '.bat':
+ first_line = open(script).readline().strip()
+ if first_line.startswith('#!'):
+ commands = first_line[2:].split('#')[0].strip().split()
+ commands[0] = shutil.which(commands[0].split('/')[-1])
+ if commands[0] is None:
+ raise RuntimeError("Don't know how to run script %s." % script)
+ final_command = commands + [script] + i.cmd_arr[1:]
+ else:
+ final_command = i.cmd_arr
+ subprocess.check_call(final_command, env=child_env)
+
+def is_elf_platform():
+ platname = platform.system().lower()
+ if platname == 'darwin' or platname == 'windows':
+ return False
+ return True
+
+def check_for_stampfile(fname):
+ '''Some languages e.g. Rust have output files
+ whose names are not known at configure time.
+ Check if this is the case and return the real
+ file instead.'''
+ if fname.endswith('.so') or fname.endswith('.dll'):
+ if os.stat(fname).st_size == 0:
+ (base, suffix) = os.path.splitext(fname)
+ files = glob(base + '-*' + suffix)
+ if len(files) > 1:
+ print("Stale dynamic library files in build dir. Can't install.")
+ sys.exit(1)
+ if len(files) == 1:
+ return files[0]
+ elif fname.endswith('.a') or fname.endswith('.lib'):
+ if os.stat(fname).st_size == 0:
+ (base, suffix) = os.path.splitext(fname)
+ files = glob(base + '-*' + '.rlib')
+ if len(files) > 1:
+ print("Stale static library files in build dir. Can't install.")
+ sys.exit(1)
+ if len(files) == 1:
+ return files[0]
+ return fname
+
+def install_targets(d):
+ for t in d.targets:
+ fname = check_for_stampfile(t[0])
+ outdir = os.path.join(d.fullprefix, t[1])
+ aliases = t[2]
+ outname = os.path.join(outdir, os.path.split(fname)[-1])
+ should_strip = t[3]
+ install_rpath = t[4]
+ print('Installing %s to %s' % (fname, outname))
+ os.makedirs(outdir, exist_ok=True)
+ shutil.copyfile(fname, outname)
+ shutil.copystat(fname, outname)
+ if should_strip:
+ print('Stripping target')
+ ps = subprocess.Popen(['strip', outname], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (stdo, stde) = ps.communicate()
+ if ps.returncode != 0:
+ print('Could not strip file.\n')
+ print('Stdout:\n%s\n' % stdo.decode())
+ print('Stderr:\n%s\n' % stde.decode())
+ sys.exit(1)
+ printed_symlink_error = False
+ for alias in aliases:
+ try:
+ symlinkfilename = os.path.join(outdir, alias)
+ try:
+ os.unlink(symlinkfilename)
+ except FileNotFoundError:
+ pass
+ os.symlink(os.path.split(fname)[-1], symlinkfilename)
+ except NotImplementedError:
+ if not printed_symlink_error:
+ print("Symlink creation does not work on this platform.")
+ printed_symlink_error = True
+ if is_elf_platform():
+ p = subprocess.Popen([d.depfixer, outname, install_rpath],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ (stdo, stde) = p.communicate()
+ if p.returncode != 0:
+ print('Could not fix dependency info.\n')
+ print('Stdout:\n%s\n' % stdo.decode())
+ print('Stderr:\n%s\n' % stde.decode())
+ sys.exit(1)
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print('Installer script for Meson. Do not run on your own, mmm\'kay?')
+ print('%s [install info file]' % sys.argv[0])
+ datafilename = sys.argv[1]
+ do_install(datafilename)
+