From 6c50253645dad81afbfd2e1bca2c5d9e08f42e05 Mon Sep 17 00:00:00 2001 From: Emanuele Aina Date: Tue, 27 Sep 2016 15:31:38 +0200 Subject: Use argv[0] to internally relaunch meson.py When installing Meson, distutils may choose to put shim scripts in the `PATH` that only set up the egg requirements before launching the real `meson.py` contained in the egg. This means that `__file__` points to the real `meson.py` file, but launching it directly is doomed to fail as it's missing the metadata contained in the shim to set up the path egg, resulting in errors when trying to import the `mesonbuild` module. A similar issue affects Meson when installed as a zipapp, with the current code going great lengths to figure out how to relaunch itself. Using `argv[0]` avoids these issues as it gives us the way the current executable has been launched, so we are pretty much guaranteed that using it will create another instance of the same executable. We only need to resolve relative paths as the current working directory may get changed before re-launching the script, and using `realpath()` for that saves us the trouble of manually resolving links and getting caught in endless loops. This also mean that `meson_script_file` no longer necessarily point to a absolute file, so rename it to `_launcher` which hopefully would be less prone to inducing false assumptions. --- authors.txt | 1 + meson.py | 14 ++++++-------- mesonbuild/environment.py | 10 ++++------ mesonbuild/mesonmain.py | 12 +++--------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/authors.txt b/authors.txt index f0c2006e2..229a2ff5f 100644 --- a/authors.txt +++ b/authors.txt @@ -46,3 +46,4 @@ Patrick Griffis Iain Lane Daniel Brendle Franz Zapata +Emanuele Aina diff --git a/meson.py b/meson.py index 7e21c784b..492f70dca 100755 --- a/meson.py +++ b/meson.py @@ -15,13 +15,11 @@ # limitations under the License. from mesonbuild import mesonmain -import sys, os +import sys, os, os.path -thisfile = __file__ -if not os.path.isabs(thisfile): - thisfile = os.path.normpath(os.path.join(os.getcwd(), thisfile)) +launcher = sys.argv[0] +# resolve the command path if not launched from $PATH +if os.path.split(launcher)[0]: + launcher = os.path.realpath(launcher) -# The first argument *must* be an absolute path because -# the user may have launched the program from a dir -# that is not in path. -sys.exit(mesonmain.run(thisfile, sys.argv[1:])) +sys.exit(mesonmain.run(launcher, sys.argv[1:])) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index e411687f9..86c23aed9 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -179,12 +179,10 @@ class Environment(): coredata_file = os.path.join(private_dir, 'coredata.dat') version_regex = '\d+(\.\d+)+(-[a-zA-Z0-9]+)?' - def __init__(self, source_dir, build_dir, main_script_file, options, original_cmd_line_args): - assert(os.path.isabs(main_script_file)) - assert(not os.path.islink(main_script_file)) + def __init__(self, source_dir, build_dir, main_script_launcher, options, original_cmd_line_args): self.source_dir = source_dir self.build_dir = build_dir - self.meson_script_file = main_script_file + self.meson_script_launcher = main_script_launcher self.scratch_dir = os.path.join(build_dir, Environment.private_dir) self.log_dir = os.path.join(build_dir, Environment.log_dir) os.makedirs(self.scratch_dir, exist_ok=True) @@ -198,7 +196,7 @@ class Environment(): # re-initialized with project options by the interpreter during # build file parsing. self.coredata = coredata.CoreData(options) - self.coredata.meson_script_file = self.meson_script_file + self.coredata.meson_script_launcher = self.meson_script_launcher self.first_invocation = True if self.coredata.cross_file: self.cross_info = CrossBuildInfo(self.coredata.cross_file) @@ -253,7 +251,7 @@ class Environment(): return self.coredata def get_build_command(self): - return self.meson_script_file + return self.meson_script_launcher def is_header(self, fname): return is_header(fname) diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py index f7da1e069..7574c2761 100644 --- a/mesonbuild/mesonmain.py +++ b/mesonbuild/mesonmain.py @@ -65,7 +65,7 @@ parser.add_argument('directories', nargs='*') class MesonApp(): - def __init__(self, dir1, dir2, script_file, handshake, options, original_cmd_line_args): + def __init__(self, dir1, dir2, script_launcher, handshake, options, original_cmd_line_args): (self.source_dir, self.build_dir) = self.validate_dirs(dir1, dir2, handshake) if not os.path.isabs(options.prefix): raise RuntimeError('--prefix value \'{0}\' must be an absolute path: '.format(options.prefix)) @@ -76,7 +76,7 @@ class MesonApp(): pass else: options.prefix = options.prefix[:-1] - self.meson_script_file = script_file + self.meson_script_launcher = script_launcher self.options = options self.original_cmd_line_args = original_cmd_line_args @@ -124,7 +124,7 @@ itself as required.''' env.coredata.pkgconf_envvar = curvar def generate(self): - env = environment.Environment(self.source_dir, self.build_dir, self.meson_script_file, self.options, self.original_cmd_line_args) + env = environment.Environment(self.source_dir, self.build_dir, self.meson_script_launcher, self.options, self.original_cmd_line_args) mlog.initialize(env.get_log_dir()) mlog.debug('Build started at', datetime.datetime.now().isoformat()) mlog.debug('Python binary:', sys.executable) @@ -262,12 +262,6 @@ def run(mainfile, args): dir2 = args[1] else: dir2 = '.' - while os.path.islink(mainfile): - resolved = os.readlink(mainfile) - if resolved[0] != '/': - mainfile = os.path.join(os.path.dirname(mainfile), resolved) - else: - mainfile = resolved try: app = MesonApp(dir1, dir2, mainfile, handshake, options, sys.argv) except Exception as e: -- cgit v1.2.3