aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2015-03-27 23:41:28 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2015-03-27 23:41:28 +0200
commit2e93295c2e2ed52abd036687d8a6a947b94f213a (patch)
tree6b4d5394c16c7ea52e438a08a94a6d08d1851291
parent00ecf811e67d7ed5372fbddbf19366b6ee61d10b (diff)
downloadmeson-2e93295c2e2ed52abd036687d8a6a947b94f213a.zip
meson-2e93295c2e2ed52abd036687d8a6a947b94f213a.tar.gz
meson-2e93295c2e2ed52abd036687d8a6a947b94f213a.tar.bz2
Generate configure files immediately when they are declared. Closes #88.
-rw-r--r--backends.py86
-rw-r--r--build.py1
-rw-r--r--interpreter.py6
-rw-r--r--mesonlib.py73
-rw-r--r--ninjabackend.py1
-rw-r--r--test cases/common/16 configure file/meson.build8
-rw-r--r--vs2010backend.py1
-rw-r--r--xcodebackend.py1
8 files changed, 85 insertions, 92 deletions
diff --git a/backends.py b/backends.py
index 47df757..83f291a 100644
--- a/backends.py
+++ b/backends.py
@@ -12,80 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import mparser
-import os, re, pickle
+import os, pickle
import build
import dependencies
+import mesonlib
from coredata import MesonException
-def do_replacement(regex, line, confdata):
- match = re.search(regex, line)
- while match:
- varname = match.group(1)
- if varname in confdata.keys():
- var = confdata.get(varname)
- if isinstance(var, str):
- pass
- elif isinstance(var, mparser.StringNode):
- var = var.value
- elif isinstance(var, int):
- var = str(var)
- else:
- raise RuntimeError('Tried to replace a variable with something other than a string or int.')
- else:
- var = ''
- line = line.replace('@' + varname + '@', var)
- match = re.search(regex, line)
- return line
-
-def do_mesondefine(line, confdata):
- arr = line.split()
- if len(arr) != 2:
- raise build.InvalidArguments('#mesondefine does not contain exactly two tokens: %s', line.strip())
- varname = arr[1]
- try:
- v = confdata.get(varname)
- except KeyError:
- return '/* undef %s */\n' % varname
- if isinstance(v, mparser.BooleanNode):
- v = v.value
- if isinstance(v, bool):
- if v:
- return '#define %s\n' % varname
- else:
- return '#undef %s\n' % varname
- elif isinstance(v, int):
- return '#define %s %d\n' % (varname, v)
- elif isinstance(v, str):
- return '#define %s %s\n' % (varname, v)
- else:
- raise build.InvalidArguments('#mesondefine argument "%s" is of unknown type.' % varname)
-
-def replace_if_different(dst, dst_tmp):
- # If contents are identical, don't touch the file to prevent
- # unnecessary rebuilds.
- try:
- if open(dst, 'r').read() == open(dst_tmp, 'r').read():
- os.unlink(dst_tmp)
- return
- except FileNotFoundError:
- pass
- os.replace(dst_tmp, dst)
-
-def do_conf_file(src, dst, confdata):
- data = open(src).readlines()
- regex = re.compile('@(.*?)@')
- result = []
- for line in data:
- if line.startswith('#mesondefine'):
- line = do_mesondefine(line, confdata)
- else:
- line = do_replacement(regex, line, confdata)
- result.append(line)
- dst_tmp = dst + '~'
- open(dst_tmp, 'w').writelines(result)
- replace_if_different(dst, dst_tmp)
-
class TestSerialisation:
def __init__(self, name, fname, is_cross, exe_wrapper, is_parallel, cmd_args, env,
should_fail, valgrind_args):
@@ -160,7 +92,7 @@ class Backend():
ofile = langlist[language]
ofile.write('#include<%s>\n' % src)
[x.close() for x in langlist.values()]
- [replace_if_different(x, x + '.tmp') for x in abs_files]
+ [mesonlib.replace_if_different(x, x + '.tmp') for x in abs_files]
return result
def relpath(self, todir, fromdir):
@@ -295,18 +227,6 @@ class Backend():
args += self.build_target_link_arguments(compiler, d.get_dependencies())
return args
- def generate_configure_files(self):
- for cf in self.build.get_configure_files():
- infile = os.path.join(self.environment.get_source_dir(),
- cf.get_subdir(),
- cf.get_source_name())
- outdir = os.path.join(self.environment.get_build_dir(),
- cf.get_subdir())
- os.makedirs(outdir, exist_ok=True)
- outfile = os.path.join(outdir, cf.get_target_name())
- confdata = cf.get_configuration_data()
- do_conf_file(infile, outfile, confdata)
-
def write_test_file(self, datafile):
arr = []
for t in self.build.get_tests():
diff --git a/build.py b/build.py
index fff3d11..89103d5 100644
--- a/build.py
+++ b/build.py
@@ -68,7 +68,6 @@ class Build:
self.data = []
self.static_linker = None
self.static_cross_linker = None
- self.configure_files = []
self.pot = []
self.subprojects = {}
self.pkgconfig_gens = []
diff --git a/interpreter.py b/interpreter.py
index 319aead..ee8eca7 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -1412,8 +1412,10 @@ class Interpreter():
conffile = os.path.join(self.subdir, inputfile)
self.build_def_files.append(conffile)
- c = ConfigureFileHolder(self.subdir, inputfile, output, conf.held_object)
- self.build.configure_files.append(c.held_object)
+ os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
+ ifile_abs = os.path.join(self.environment.source_dir, self.subdir, inputfile)
+ ofile_abs = os.path.join(self.environment.build_dir, self.subdir, output)
+ mesonlib.do_conf_file(ifile_abs, ofile_abs, conf.held_object)
conf.mark_used()
elif 'command' in kwargs:
res = self.func_run_command(node, kwargs['command'], {})
diff --git a/mesonlib.py b/mesonlib.py
index 10e5265..6ab6051 100644
--- a/mesonlib.py
+++ b/mesonlib.py
@@ -14,9 +14,12 @@
"""A library of random helper functionality."""
-import platform, subprocess, operator, os, shutil
+import platform, subprocess, operator, os, shutil, re
+
from glob import glob
+from coredata import MesonException
+
def is_osx():
return platform.system().lower() == 'darwin'
@@ -120,3 +123,71 @@ def get_library_dirs():
unixdirs.append('/lib64')
unixdirs += glob('/lib/' + plat + '*')
return unixdirs
+
+
+def do_replacement(regex, line, confdata):
+ match = re.search(regex, line)
+ while match:
+ varname = match.group(1)
+ if varname in confdata.keys():
+ var = confdata.get(varname)
+ if isinstance(var, str):
+ pass
+ elif isinstance(var, int):
+ var = str(var)
+ else:
+ raise RuntimeError('Tried to replace a variable with something other than a string or int.')
+ else:
+ var = ''
+ line = line.replace('@' + varname + '@', var)
+ match = re.search(regex, line)
+ return line
+
+def do_mesondefine(line, confdata):
+ arr = line.split()
+ if len(arr) != 2:
+ raise MesonException('#mesondefine does not contain exactly two tokens: %s', line.strip())
+ varname = arr[1]
+ try:
+ v = confdata.get(varname)
+ except KeyError:
+ return '/* undef %s */\n' % varname
+ if isinstance(v, bool):
+ if v:
+ return '#define %s\n' % varname
+ else:
+ return '#undef %s\n' % varname
+ elif isinstance(v, int):
+ return '#define %s %d\n' % (varname, v)
+ elif isinstance(v, str):
+ return '#define %s %s\n' % (varname, v)
+ else:
+ raise MesonException('#mesondefine argument "%s" is of unknown type.' % varname)
+
+
+def do_conf_file(src, dst, confdata):
+ data = open(src).readlines()
+ regex = re.compile('@(.*?)@')
+ result = []
+ for line in data:
+ if line.startswith('#mesondefine'):
+ line = do_mesondefine(line, confdata)
+ else:
+ line = do_replacement(regex, line, confdata)
+ result.append(line)
+ dst_tmp = dst + '~'
+ open(dst_tmp, 'w').writelines(result)
+ replace_if_different(dst, dst_tmp)
+
+
+def replace_if_different(dst, dst_tmp):
+ # If contents are identical, don't touch the file to prevent
+ # unnecessary rebuilds.
+ try:
+ if open(dst, 'r').read() == open(dst_tmp, 'r').read():
+ os.unlink(dst_tmp)
+ return
+ except FileNotFoundError:
+ pass
+ os.replace(dst_tmp, dst)
+
diff --git a/ninjabackend.py b/ninjabackend.py
index 3facb08..d467c07 100644
--- a/ninjabackend.py
+++ b/ninjabackend.py
@@ -120,7 +120,6 @@ class NinjaBackend(backends.Backend):
outfilename = os.path.join(self.environment.get_build_dir(), self.ninja_filename)
tempfilename = outfilename + '~'
outfile = open(tempfilename, 'w')
- self.generate_configure_files()
self.generate_pkgconfig_files()
outfile.write('# This is the build file for project "%s"\n' % self.build.get_project())
outfile.write('# It is autogenerated by the Meson build system.\n')
diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build
index 911a50f..8dec8fe 100644
--- a/test cases/common/16 configure file/meson.build
+++ b/test cases/common/16 configure file/meson.build
@@ -7,11 +7,15 @@ conf.set('other', 'string 2')
conf.set('second', ' bonus')
conf.set('BE_TRUE', true)
-configure_file(input : 'config.h.in',
+cfile = configure_file(input : 'config.h.in',
output : 'config.h',
configuration : conf)
-e = executable('inctest', 'prog.c')
+e = executable('inctest', 'prog.c',
+# Note that you should NOT do this. Don't add generated headers here
+# This tests that we do the right thing even if people add in conf files
+# to their sources.
+cfile)
test('inctest', e)
# Now generate a header file with an external script.
diff --git a/vs2010backend.py b/vs2010backend.py
index 9da55be..062e09a 100644
--- a/vs2010backend.py
+++ b/vs2010backend.py
@@ -62,7 +62,6 @@ class Vs2010Backend(backends.Backend):
return all_output_files
def generate(self):
- self.generate_configure_files()
self.generate_pkgconfig_files()
sln_filename = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.sln')
projlist = self.generate_projects()
diff --git a/xcodebackend.py b/xcodebackend.py
index cd05788..d2158bc 100644
--- a/xcodebackend.py
+++ b/xcodebackend.py
@@ -74,7 +74,6 @@ class XCodeBackend(backends.Backend):
self.generate_target_dependency_map()
self.generate_pbxdep_map()
self.generate_containerproxy_map()
- self.generate_configure_files()
self.generate_pkgconfig_files()
self.proj_dir = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.xcodeproj')
os.makedirs(self.proj_dir, exist_ok=True)