Options can be accessed from scripts.

pull/15/head
Jussi Pakkanen 11 years ago
parent 4e522ef215
commit 309a5c1510
  1. 20
      build.py
  2. 11
      interpreter.py
  3. 7
      meson.py
  4. 25
      optinterpreter.py
  5. 9
      test cases/common/47 options/meson.build
  6. 2
      test cases/common/47 options/meson_options.txt

@ -40,6 +40,16 @@ class Build:
self.static_cross_linker = None self.static_cross_linker = None
self.configure_files = [] self.configure_files = []
self.pot = [] self.pot = []
self.user_options = {}
def merge_options(self, options):
for (name, value) in options.items():
if name not in self.user_options:
self.user_options[name] = value
else:
oldval = self.user_options[name]
if type(oldval) != type(value):
self.user_options[name] = value
def add_compiler(self, compiler): def add_compiler(self, compiler):
if len(self.compilers) == 0: if len(self.compilers) == 0:
@ -82,7 +92,7 @@ class IncludeDirs():
# Fixme: check that the directories actually exist. # Fixme: check that the directories actually exist.
# Also that they don't contain ".." or somesuch. # Also that they don't contain ".." or somesuch.
if len(kwargs) > 0: if len(kwargs) > 0:
raise InvalidCode('Includedirs function does not take keyword arguments.') raise InvalidArguments('Includedirs function does not take keyword arguments.')
def get_curdir(self): def get_curdir(self):
return self.curdir return self.curdir
@ -268,15 +278,15 @@ class BuildTarget():
if len(pchlist) == 2: if len(pchlist) == 2:
if environment.is_header(pchlist[0]): if environment.is_header(pchlist[0]):
if not environment.is_source(pchlist[1]): if not environment.is_source(pchlist[1]):
raise InterpreterException('PCH definition must contain one header and at most one source.') raise InvalidArguments('PCH definition must contain one header and at most one source.')
elif environment.is_source(pchlist[0]): elif environment.is_source(pchlist[0]):
if not environment.is_header(pchlist[1]): if not environment.is_header(pchlist[1]):
raise InterpreterException('PCH definition must contain one header and at most one source.') raise InvalidArguments('PCH definition must contain one header and at most one source.')
pchlist = [pchlist[1], pchlist[0]] pchlist = [pchlist[1], pchlist[0]]
else: else:
raise InterpreterException('PCH argument %s is of unknown type.' % pchlist[0]) raise InvalidArguments('PCH argument %s is of unknown type.' % pchlist[0])
elif len(pchlist) > 2: elif len(pchlist) > 2:
raise InterpreterException('PCH definition may have a maximum of 2 files.') raise InvalidArguments('PCH definition may have a maximum of 2 files.')
self.pch[language] = pchlist self.pch[language] = pchlist
def add_include_dirs(self, args): def add_include_dirs(self, args):

@ -580,6 +580,7 @@ class Interpreter():
'run_command' : self.func_run_command, 'run_command' : self.func_run_command,
'gettext' : self.func_gettext, 'gettext' : self.func_gettext,
'option' : self.func_option, 'option' : self.func_option,
'get_option' : self.func_get_option,
} }
def get_build_def_files(self): def get_build_def_files(self):
@ -696,6 +697,16 @@ class Interpreter():
def func_option(self, nodes, args, kwargs): def func_option(self, nodes, args, kwargs):
raise InterpreterException('Tried to call option() in build description file. All options must be in the option file.') raise InterpreterException('Tried to call option() in build description file. All options must be in the option file.')
def func_get_option(self, nodes, args, kwargs):
if len(args) != 1:
raise InterpreterException('Argument required for get_option.')
optname = args[0]
if not isinstance(optname, str):
raise InterpreterException('Argument of get_option must be a string.')
if optname not in self.build.user_options:
raise InterpreterException('Tried to access unknown option "%s".' % optname)
return self.build.user_options[optname].value
def func_configuration_data(self, node, args, kwargs): def func_configuration_data(self, node, args, kwargs):
if len(args) != 0: if len(args) != 0:
raise InterpreterException('configuration_data takes no arguments') raise InterpreterException('configuration_data takes no arguments')

@ -17,7 +17,7 @@
from optparse import OptionParser from optparse import OptionParser
import sys, stat, traceback, pickle import sys, stat, traceback, pickle
import os.path import os.path
import environment, interpreter import environment, interpreter, optinterpreter
import backends, build import backends, build
import mlog, coredata import mlog, coredata
@ -121,6 +121,11 @@ itself as required.'''
else: else:
mlog.log('Build type:', mlog.bold('native build')) mlog.log('Build type:', mlog.bold('native build'))
b = build.Build(env) b = build.Build(env)
option_file = os.path.join(self.source_dir, 'meson_options.txt')
if os.path.exists(option_file):
oi = optinterpreter.OptionInterpreter()
oi.process(option_file)
b.merge_options(oi.options)
intr = interpreter.Interpreter(b) intr = interpreter.Interpreter(b)
intr.run() intr.run()
if options.backend == 'ninja': if options.backend == 'ninja':

@ -29,9 +29,17 @@ class UserStringOption(UserOption):
super().__init__(kwargs) super().__init__(kwargs)
self.value = kwargs.get('value', '') self.value = kwargs.get('value', '')
if not isinstance(self.value, str): if not isinstance(self.value, str):
raise OptionException('Value of string option is not a string') raise OptionException('Value of string option is not a string.')
class UserBooleanOption(UserOption):
def __init__(self, kwargs):
super().__init__(kwargs)
self.value = kwargs.get('value', 'true')
if not isinstance(self.value, bool):
raise OptionException('Value of boolean option is not boolean.')
option_types = {'string' : UserStringOption, option_types = {'string' : UserStringOption,
'boolean' : UserBooleanOption,
} }
class OptionInterpreter: class OptionInterpreter:
@ -49,17 +57,13 @@ class OptionInterpreter:
e.lineno = ast.lineno() e.lineno = ast.lineno()
raise e raise e
statements = ast.get_statements() statements = ast.get_statements()
i = 0 for cur in statements:
while i < len(statements):
cur = statements[i]
try: try:
self.evaluate_statement(cur) self.evaluate_statement(cur)
except Exception as e: except Exception as e:
e.lineno = cur.lineno() e.lineno = cur.lineno()
e.file = os.path.join('options.txt') e.file = os.path.join('meson_options.txt')
raise e raise e
i += 1 # In THE FUTURE jump over blocks and stuff.
print(self.options)
def reduce_single(self, arg): def reduce_single(self, arg):
if isinstance(arg, nodes.AtomExpression) or isinstance(arg, nodes.AtomStatement): if isinstance(arg, nodes.AtomExpression) or isinstance(arg, nodes.AtomStatement):
@ -103,13 +107,8 @@ class OptionInterpreter:
if not opt_type in option_types: if not opt_type in option_types:
raise OptionException('Unknown type %s.' % opt_type) raise OptionException('Unknown type %s.' % opt_type)
if len(posargs) != 1: if len(posargs) != 1:
raise OptionException('Option all must have one (and only one) positional argument') raise OptionException('Option() must have one (and only one) positional argument')
opt_name = posargs[0] opt_name = posargs[0]
if not isinstance(opt_name, str): if not isinstance(opt_name, str):
raise OptionException('Positional argument must be a string.') raise OptionException('Positional argument must be a string.')
self.options[opt_name] = option_types[opt_type](kwargs) self.options[opt_name] = option_types[opt_type](kwargs)
if __name__ == '__main__':
import sys
oi = OptionInterpreter()
oi.process(sys.argv[1])

@ -0,0 +1,9 @@
project('options', 'c')
if get_option('testoption') != 'optval'
error('Incorrect value to test option')
endif
if get_option('other_one') != false
error('Incorrect value to boolean option.')
endif

@ -0,0 +1,2 @@
option('testoption', type : 'string', value : 'optval')
option('other_one', type : 'boolean', value : false)
Loading…
Cancel
Save