aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/coredata.py55
-rw-r--r--mesonbuild/mesonmain.py9
2 files changed, 53 insertions, 11 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index a7be91f..60bb10b 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -131,10 +131,54 @@ class CoreData:
# Only to print a warning if it changes between Meson invocations.
self.pkgconf_envvar = os.environ.get('PKG_CONFIG_PATH', '')
+ def sanitize_prefix(self, prefix):
+ if not os.path.isabs(prefix):
+ raise MesonException('prefix value {!r} must be an absolute path'
+ ''.format(prefix))
+ if prefix.endswith('/') or prefix.endswith('\\'):
+ # On Windows we need to preserve the trailing slash if the
+ # string is of type 'C:\' because 'C:' is not an absolute path.
+ if len(prefix) == 3 and prefix[1] == ':':
+ pass
+ else:
+ prefix = prefix[:-1]
+ return prefix
+
+ def sanitize_dir_option_value(self, prefix, option, value):
+ '''
+ If the option is an installation directory option and the value is an
+ absolute path, check that it resides within prefix and return the value
+ as a path relative to the prefix.
+
+ This way everyone can do f.ex, get_option('libdir') and be sure to get
+ the library directory relative to prefix.
+ '''
+ if option.endswith('dir') and os.path.isabs(value) and \
+ option not in builtin_dir_noprefix_options:
+ # Value must be a subdir of the prefix
+ if os.path.commonpath([value, prefix]) != prefix:
+ m = 'The value of the {!r} option is {!r} which must be a ' \
+ 'subdir of the prefix {!r}.\nNote that if you pass a ' \
+ 'relative path, it is assumed to be a subdir of prefix.'
+ raise MesonException(m.format(option, value, prefix))
+ # Convert path to be relative to prefix
+ skip = len(prefix) + 1
+ value = value[skip:]
+ return value
+
def init_builtins(self, options):
self.builtins = {}
+ # Sanitize prefix
+ options.prefix = self.sanitize_prefix(options.prefix)
+ # Initialize other builtin options
for key in get_builtin_options():
- args = [key] + builtin_options[key][1:-1] + [getattr(options, key, get_builtin_option_default(key))]
+ if hasattr(options, key):
+ value = getattr(options, key)
+ value = self.sanitize_dir_option_value(options.prefix, key, value)
+ setattr(options, key, value)
+ else:
+ value = get_builtin_option_default(key)
+ args = [key] + builtin_options[key][1:-1] + [value]
self.builtins[key] = builtin_options[key][0](*args)
def get_builtin_option(self, optname):
@@ -143,7 +187,11 @@ class CoreData:
raise RuntimeError('Tried to get unknown builtin option %s.' % optname)
def set_builtin_option(self, optname, value):
- if optname in self.builtins:
+ if optname == 'prefix':
+ value = self.sanitize_prefix(value)
+ elif optname in self.builtins:
+ prefix = self.builtins['prefix'].value
+ value = self.sanitize_dir_option_value(prefix, optname, value)
self.builtins[optname].set_value(value)
else:
raise RuntimeError('Tried to set unknown builtin option %s.' % optname)
@@ -235,6 +283,9 @@ builtin_options = {
'errorlogs': [UserBooleanOption, "Whether to print the logs from failing tests.", True],
}
+# Installation directories that can reside in a path outside of the prefix
+builtin_dir_noprefix_options = {'sysconfdir', 'localstatedir', 'sharedstatedir'}
+
forbidden_target_names = {'clean': None,
'clean-ctlist': None,
'clean-gcno': None,
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 37b8055..031486c 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -73,15 +73,6 @@ class MesonApp:
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 must be an absolute path: {!r}'.format(options.prefix))
- if options.prefix.endswith('/') or options.prefix.endswith('\\'):
- # On Windows we need to preserve the trailing slash if the
- # string is of type 'C:\' because 'C:' is not an absolute path.
- if len(options.prefix) == 3 and options.prefix[1] == ':':
- pass
- else:
- options.prefix = options.prefix[:-1]
self.meson_script_launcher = script_launcher
self.options = options
self.original_cmd_line_args = original_cmd_line_args