Skip to content

Commit

Permalink
allow setting directory locations in a native file
Browse files Browse the repository at this point in the history
This allows the person running configure (either a developer, user, or
distro maintainer) to keep a configuration of where various kinds of
files should end up.
  • Loading branch information
dcbaker committed Jan 8, 2019
1 parent eec3267 commit ed917e3
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 11 deletions.
15 changes: 15 additions & 0 deletions docs/markdown/Native-environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ rust = '/usr/local/bin/rust'
llvm-config = '/usr/local/llvm-svn/bin/llvm-config'
```

### Paths and Directories

As of 0.50.0 paths and directories such as libdir can be defined in the native
file in a paths section

```ini
[paths]
libdir = 'mylibdir'
prefix = '/my prefix'
```

These will override default paths for native targets (executables, libraries,
etc), but not for cross targets. These values will be overwritten by command
line arguments, such as --libdir.

## Loading multiple native files

Unlike cross file, native files allow layering. More than one native file can be
Expand Down
4 changes: 4 additions & 0 deletions docs/markdown/snippets/native-file-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Native File Paths and Directories

A new `[paths]` section has been added to the native file. This can be used to
set paths such a prefix and libdir in a persistent way.
32 changes: 25 additions & 7 deletions mesonbuild/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,17 +350,24 @@ def __init__(self, source_dir, build_dir, options):
# Similar to coredata.compilers and build.compilers, but lower level in
# that there is no meta data, only names/paths.
self.binaries = PerMachineDefaultable()

# Just uses hard-coded defaults and environment variables. Might be
# overwritten by a native file.
self.binaries.build = BinaryTable({})

# Misc other properties about each machine.
self.properties = PerMachine(Properties(), Properties(), Properties())

# Store paths for native and cross build files. There is no target
# machine information here because nothing is installed for the target
# architecture, just the build and host architectures
self.paths = PerMachine(Directories(), None, None)

if self.coredata.config_files is not None:
config = MesonConfigFile.from_config_parser(
coredata.load_configs(self.coredata.config_files))
self.binaries.build = BinaryTable(config.get('binaries', {}))
self.paths.build.update(config.get('paths', {}))

if self.coredata.cross_file is not None:
config = MesonConfigFile.parse_datafile(self.coredata.cross_file)
Expand Down Expand Up @@ -1072,6 +1079,17 @@ def detect_static_linker(self, compiler):
self._handle_exceptions(popen_exceptions, linkers, 'linker')
raise EnvironmentException('Unknown static linker "%s"' % ' '.join(linkers))

def get_install_path(self, name: str) -> str:
"""Helper that checks the native file as well as command line options,
and defaults and resolve precidence.
"""
cd = self.coredata.builtins[name]
if cd.value_is_default:
conf = getattr(self.paths[MachineChoice.BUILD], name)
if conf:
return conf
return cd.value

def get_source_dir(self):
return self.source_dir

Expand Down Expand Up @@ -1103,25 +1121,25 @@ def get_object_suffix(self):
return self.object_suffix

def get_prefix(self):
return self.coredata.get_builtin_option('prefix')
return self.get_install_path('prefix')

def get_libdir(self):
return self.coredata.get_builtin_option('libdir')
return self.get_install_path('libdir')

def get_libexecdir(self):
return self.coredata.get_builtin_option('libexecdir')
return self.get_install_path('libexecdir')

def get_bindir(self):
return self.coredata.get_builtin_option('bindir')
return self.get_install_path('bindir')

def get_includedir(self):
return self.coredata.get_builtin_option('includedir')
return self.get_install_path('includedir')

def get_mandir(self):
return self.coredata.get_builtin_option('mandir')
return self.get_install_path('mandir')

def get_datadir(self):
return self.coredata.get_builtin_option('datadir')
return self.get_install_path('datadir')

def get_compiler_system_dirs(self):
for comp in self.coredata.compilers.values():
Expand Down
28 changes: 28 additions & 0 deletions mesonbuild/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@
'sources'},
}

# Set of options that are valid to get from a native file
NATIVE_OPTIONS = {
'bindir',
'datadir',
'includedir',
'infodir',
'libdir',
'libexecdir',
'localedir',
'localstatedir',
'mandir',
'prefix',
'sbindir',
'sharedstatedir',
'sysconfdir',
}

def stringifyUserArguments(args):
if isinstance(args, list):
return '[%s]' % ', '.join([stringifyUserArguments(x) for x in args])
Expand Down Expand Up @@ -2439,6 +2456,17 @@ def do_subproject(self, dirname, kwargs):
def get_option_internal(self, optname):
# Some base options are not defined in some environments, return the
# default value from compilers.base_options in that case.
if optname in NATIVE_OPTIONS:
core = self.coredata.builtins[optname]
conf = getattr(self.environment.paths[MachineChoice.BUILD], optname)

if conf is not None and core.value_is_default:
# If there is a definition in a native file and the option
# wasn't passed on the command line, return the native file
# value
return conf
return core

for d in [self.coredata.base_options, compilers.base_options,
self.coredata.builtins, self.coredata.compiler_options]:
try:
Expand Down
19 changes: 15 additions & 4 deletions mesonbuild/mconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,25 @@ def print_options(self, title, options):
if not options:
print(' No {}\n'.format(title.lower()))
arr = []
for k in sorted(options):
o = options[k]
for k, o in sorted(options.items()):
d = o.description
v = o.printable_value()
c = o.choices
arr.append({'name': k, 'descr': d, 'value': v, 'choices': c})
self.print_aligned(arr)

def print_list_options(self, title, olist):
print('\n{}:'.format(title))
if not olist:
print(' No {}\n'.format(title.lower()))
arr = []
for k, v in sorted(olist):
o = self.coredata.builtins[k]
d = o.description
c = o.choices
arr.append({'name': k, 'descr': d, 'value': v, 'choices': c})
self.print_aligned(arr)

def print_conf(self):
print('Core properties:')
print(' Source dir', self.build.environment.source_dir)
Expand All @@ -132,15 +143,15 @@ def print_conf(self):
'stdsplit']
core_option_names = [k for k in self.coredata.builtins if k not in dir_option_names + test_option_names]

dir_options = {k: o for k, o in self.coredata.builtins.items() if k in dir_option_names}
dir_options = [(k, self.build.environment.get_install_path(k)) for k in dir_option_names]
test_options = {k: o for k, o in self.coredata.builtins.items() if k in test_option_names}
core_options = {k: o for k, o in self.coredata.builtins.items() if k in core_option_names}

self.print_options('Core options', core_options)
self.print_options('Backend options', self.coredata.backend_options)
self.print_options('Base options', self.coredata.base_options)
self.print_options('Compiler options', self.coredata.compiler_options)
self.print_options('Directories', dir_options)
self.print_list_options('Directories', dir_options)
self.print_options('Project options', self.coredata.user_options)
self.print_options('Testing options', test_options)

Expand Down
11 changes: 11 additions & 0 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5240,6 +5240,17 @@ def test_swift_compiler(self):
compiler = env.detect_swift_compiler()
self.assertEqual(compiler.version, '1.2345')

def test_native_file_dirs(self):
testcase = os.path.join(self.unit_test_dir, '52 native file override')
self.init(testcase, default_args=False,
extra_args=['--native-file', os.path.join(testcase, 'nativefile')])

def test_native_file_dirs_overriden(self):
testcase = os.path.join(self.unit_test_dir, '52 native file override')
self.init(testcase, default_args=False,
extra_args=['--native-file', os.path.join(testcase, 'nativefile'),
'-Ddef_libdir=liblib', '-Dlibdir=liblib'])


def unset_envs():
# For unit tests we must fully control all command lines
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
usr/custom_bindir/main
5 changes: 5 additions & 0 deletions test cases/common/211 native file path override/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <iostream>

int main() {
std::cout << "Hello world!" << std::endl;
}
3 changes: 3 additions & 0 deletions test cases/common/211 native file path override/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
project('native file install dir override', 'cpp')

executable('main', 'main.cpp', install : true)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[paths]
bindir = 'custom_bindir'
10 changes: 10 additions & 0 deletions test cases/unit/52 native file override/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
project('native file overrides')

foreach o : ['bindir', 'datadir', 'includedir', 'infodir', 'libdir',
'libexecdir', 'localedir', 'localstatedir', 'mandir', 'prefix',
'sbindir', 'sharedstatedir', 'sysconfdir']
expected = get_option('def_' + o)
actual = get_option(o)
assert(expected == actual,
'@0@ should have been @1@, but was @2@!'.format(o, expected, actual))
endforeach
13 changes: 13 additions & 0 deletions test cases/unit/52 native file override/meson_options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
option('def_bindir', type: 'string', value : 'binfoo',)
option('def_datadir', type: 'string', value : 'datafoo',)
option('def_includedir', type: 'string', value : 'includefoo',)
option('def_infodir', type: 'string', value : 'infofoo',)
option('def_libdir', type: 'string', value : 'libfoo',)
option('def_libexecdir', type: 'string', value : 'libexecfoo',)
option('def_localedir', type: 'string', value : 'localefoo',)
option('def_localstatedir', type: 'string', value : 'localstatefoo',)
option('def_mandir', type: 'string', value : 'manfoo',)
option('def_prefix', type: 'string', value : '/prefix',)
option('def_sbindir', type: 'string', value : 'sbinfoo',)
option('def_sharedstatedir', type: 'string', value : 'sharedstatefoo',)
option('def_sysconfdir', type: 'string', value : 'sysconffoo',)
16 changes: 16 additions & 0 deletions test cases/unit/52 native file override/nativefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[paths]
bindir = 'binfoo'
datadir = 'datafoo'
includedir = 'includefoo'
infodir = 'infofoo'
libdir = 'libfoo'
libexecdir = 'libexecfoo'
localedir = 'localefoo'
localstatedir = 'localstatefoo'
mandir = 'manfoo'
prefix = '/prefix'
sbindir = 'sbinfoo'
sharedstatedir = 'sharedstatefoo'
sysconfdir = 'sysconffoo'

; vim: ft=dosini

0 comments on commit ed917e3

Please sign in to comment.