Generate configure files immediately when they are declared. Closes #88.

pull/96/head
Jussi Pakkanen 10 years ago
parent 00ecf811e6
commit 2e93295c2e
  1. 86
      backends.py
  2. 1
      build.py
  3. 6
      interpreter.py
  4. 73
      mesonlib.py
  5. 1
      ninjabackend.py
  6. 8
      test cases/common/16 configure file/meson.build
  7. 1
      vs2010backend.py
  8. 1
      xcodebackend.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():

@ -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 = []

@ -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'], {})

@ -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)

@ -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')

@ -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.

@ -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()

@ -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)

Loading…
Cancel
Save