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.configure_files = []
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):
if len(self.compilers) == 0:
@ -82,7 +92,7 @@ class IncludeDirs():
# Fixme: check that the directories actually exist.
# Also that they don't contain ".." or somesuch.
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):
return self.curdir
@ -268,15 +278,15 @@ class BuildTarget():
if len(pchlist) == 2:
if environment.is_header(pchlist[0]):
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]):
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]]
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:
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
def add_include_dirs(self, args):

@ -580,6 +580,7 @@ class Interpreter():
'run_command' : self.func_run_command,
'gettext' : self.func_gettext,
'option' : self.func_option,
'get_option' : self.func_get_option,
}
def get_build_def_files(self):
@ -696,6 +697,16 @@ class Interpreter():
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.')
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):
if len(args) != 0:
raise InterpreterException('configuration_data takes no arguments')

@ -17,7 +17,7 @@
from optparse import OptionParser
import sys, stat, traceback, pickle
import os.path
import environment, interpreter
import environment, interpreter, optinterpreter
import backends, build
import mlog, coredata
@ -121,6 +121,11 @@ itself as required.'''
else:
mlog.log('Build type:', mlog.bold('native build'))
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.run()
if options.backend == 'ninja':

@ -29,9 +29,17 @@ class UserStringOption(UserOption):
super().__init__(kwargs)
self.value = kwargs.get('value', '')
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,
'boolean' : UserBooleanOption,
}
class OptionInterpreter:
@ -49,17 +57,13 @@ class OptionInterpreter:
e.lineno = ast.lineno()
raise e
statements = ast.get_statements()
i = 0
while i < len(statements):
cur = statements[i]
for cur in statements:
try:
self.evaluate_statement(cur)
except Exception as e:
e.lineno = cur.lineno()
e.file = os.path.join('options.txt')
e.file = os.path.join('meson_options.txt')
raise e
i += 1 # In THE FUTURE jump over blocks and stuff.
print(self.options)
def reduce_single(self, arg):
if isinstance(arg, nodes.AtomExpression) or isinstance(arg, nodes.AtomStatement):
@ -103,13 +107,8 @@ class OptionInterpreter:
if not opt_type in option_types:
raise OptionException('Unknown type %s.' % opt_type)
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]
if not isinstance(opt_name, str):
raise OptionException('Positional argument must be a string.')
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