aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2013-10-16 22:33:33 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2013-10-16 22:33:33 +0300
commit309a5c1510810d3676dcec9962894a3353ce218c (patch)
tree60bff326cf68f7eb5c1422b5800bdbd30727bb4d
parent4e522ef2158c8ba4bac3f13b31ecd2f746696a84 (diff)
downloadmeson-309a5c1510810d3676dcec9962894a3353ce218c.zip
meson-309a5c1510810d3676dcec9962894a3353ce218c.tar.gz
meson-309a5c1510810d3676dcec9962894a3353ce218c.tar.bz2
Options can be accessed from scripts.
-rw-r--r--build.py20
-rw-r--r--interpreter.py11
-rwxr-xr-xmeson.py7
-rw-r--r--optinterpreter.py25
-rw-r--r--test cases/common/47 options/meson.build9
-rw-r--r--test cases/common/47 options/meson_options.txt2
6 files changed, 55 insertions, 19 deletions
diff --git a/build.py b/build.py
index 64125a8..64ea6ac 100644
--- a/build.py
+++ b/build.py
@@ -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):
diff --git a/interpreter.py b/interpreter.py
index 4b35234..5c3a317 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -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')
diff --git a/meson.py b/meson.py
index d96dffc..9731d1d 100755
--- a/meson.py
+++ b/meson.py
@@ -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':
diff --git a/optinterpreter.py b/optinterpreter.py
index 01ae441..e2f72d0 100644
--- a/optinterpreter.py
+++ b/optinterpreter.py
@@ -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])
diff --git a/test cases/common/47 options/meson.build b/test cases/common/47 options/meson.build
new file mode 100644
index 0000000..5d6f3d0
--- /dev/null
+++ b/test cases/common/47 options/meson.build
@@ -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
diff --git a/test cases/common/47 options/meson_options.txt b/test cases/common/47 options/meson_options.txt
new file mode 100644
index 0000000..3dcb62d
--- /dev/null
+++ b/test cases/common/47 options/meson_options.txt
@@ -0,0 +1,2 @@
+option('testoption', type : 'string', value : 'optval')
+option('other_one', type : 'boolean', value : false)