Merged trunk changes.

pull/255/head
Jussi Pakkanen 9 years ago
commit 5c5f8c7813
  1. 1
      authors.txt
  2. 2
      backends.py
  3. 169
      compilers.py
  4. 5
      coredata.py
  5. 26
      cross/iphone.txt
  6. 8
      cross/ubuntu-armhf.txt
  7. 80
      dependencies.py
  8. 16
      environment.py
  9. 9
      interpreter.py
  10. 2
      man/meson.1
  11. 2
      man/mesonconf.1
  12. 2
      man/mesongui.1
  13. 2
      man/mesonintrospect.1
  14. 2
      man/wraptool.1
  15. 11
      meson.py
  16. 7
      mesonconf.py
  17. 13
      mesonlib.py
  18. 112
      ninjabackend.py
  19. 10
      test cases/common/58 run target/helloprinter.c
  20. 6
      test cases/common/58 run target/meson.build
  21. 6
      test cases/failing/19 target clash/clash.c
  22. 15
      test cases/failing/19 target clash/meson.build
  23. 5
      test cases/frameworks/1 boost/meson.build
  24. 18
      test cases/frameworks/1 boost/nomod.cpp
  25. 217
      tools/ac_converter.py
  26. 122
      tools/autotools2meson.py
  27. 2
      tools/cmake2meson.py

@ -20,3 +20,4 @@ Mathieu Duponchelle
Jouni Roivas
Rafaël Kooi
Marko Raatikainen
German Diago Gomez

@ -209,7 +209,7 @@ class Backend():
commands = []
commands += compiler.get_always_args()
if self.environment.coredata.buildtype != 'plain':
commands += compiler.get_std_warn_args()
commands += compiler.get_warn_args(self.environment.coredata.warning_level)
commands += self.build.get_global_args(compiler)
commands += self.environment.coredata.external_args[compiler.get_language()]
commands += target.get_extra_args(compiler.get_language())

@ -145,6 +145,9 @@ class CCompiler():
def get_linker_always_args(self):
return []
def get_warn_args(self, level):
return self.warn_args[level]
def get_soname_args(self, shlib_name, path, soversion):
return []
@ -260,8 +263,7 @@ int someSymbolHereJustForFun;
'''
return self.compiles(templ % hname)
def compiles(self, code):
mlog.debug('Running compile test:\n\n', code)
def compiles(self, code, extra_args = []):
suflen = len(self.default_suffix)
(fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix)
os.close(fd)
@ -269,8 +271,12 @@ int someSymbolHereJustForFun;
ofile.write(code)
ofile.close()
commands = self.get_exelist()
commands += extra_args
commands += self.get_compile_only_args()
commands.append(srcname)
mlog.debug('Running compile test.')
mlog.debug('Command line: ', ' '.join(commands))
mlog.debug('Code:\n', code)
p = subprocess.Popen(commands, cwd=os.path.split(srcname)[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stde, stdo) = p.communicate()
stde = stde.decode()
@ -324,7 +330,24 @@ int someSymbolHereJustForFun;
os.remove(exename)
return RunResult(True, pe.returncode, so, se)
def cross_sizeof(self, element, prefix, env):
templ = '''%s
int temparray[%d-sizeof(%s)];
'''
extra_args = []
try:
extra_args = env.cross_info.config['properties'][self.language + '_args']
except KeyError:
pass
for i in range(1, 1024):
code = templ % (prefix, i, element)
if self.compiles(code, extra_args):
return i
raise EnvironmentException('Cross checking sizeof overflowed.')
def sizeof(self, element, prefix, env):
if self.is_cross:
return self.cross_sizeof(element, prefix, env)
templ = '''#include<stdio.h>
%s
@ -333,30 +356,35 @@ int main(int argc, char **argv) {
return 0;
};
'''
varname = 'sizeof ' + element
varname = varname.replace(' ', '_')
if self.is_cross:
val = env.cross_info.config['properties'][varname]
if val is not None:
if isinstance(val, int):
return val
raise EnvironmentException('Cross variable {0} is not an integer.'.format(varname))
cross_failed = False
try:
res = self.run(templ % (prefix, element))
except CrossNoRunException:
cross_failed = True
if cross_failed:
message = '''Can not determine size of {0} because cross compiled binaries are not runnable.
Please define the corresponding variable {1} in your cross compilation definition file.'''.format(element, varname)
raise EnvironmentException(message)
res = self.run(templ % (prefix, element))
if not res.compiled:
raise EnvironmentException('Could not compile sizeof test.')
if res.returncode != 0:
raise EnvironmentException('Could not run sizeof test binary.')
return int(res.stdout)
def cross_alignment(self, typename, env):
templ = '''#include<stddef.h>
struct tmp {
char c;
%s target;
};
int testarray[%d-offsetof(struct tmp, target)];
'''
try:
extra_args = env.cross_info.config['properties'][self.language + '_args']
except KeyError:
pass
for i in range(1, 1024):
code = templ % (typename, i)
if self.compiles(code, extra_args):
return i
raise EnvironmentException('Cross checking offsetof overflowed.')
def alignment(self, typename, env):
if self.is_cross:
return self.cross_alignment(typename, env)
templ = '''#include<stdio.h>
#include<stddef.h>
@ -370,23 +398,7 @@ int main(int argc, char **argv) {
return 0;
}
'''
varname = 'alignment ' + typename
varname = varname.replace(' ', '_')
if self.is_cross:
val = env.cross_info.config['properties'][varname]
if val is not None:
if isinstance(val, int):
return val
raise EnvironmentException('Cross variable {0} is not an integer.'.format(varname))
cross_failed = False
try:
res = self.run(templ % typename)
except CrossNoRunException:
cross_failed = True
if cross_failed:
message = '''Can not determine alignment of {0} because cross compiled binaries are not runnable.
Please define the corresponding variable {1} in your cross compilation definition file.'''.format(typename, varname)
raise EnvironmentException(message)
res = self.run(templ % typename)
if not res.compiled:
raise EnvironmentException('Could not compile alignment test.')
if res.returncode != 0:
@ -413,7 +425,7 @@ int main(int argc, char **argv) {
if val is not None:
if isinstance(val, bool):
return val
raise EnvironmentException('Cross variable {0} is not an boolean.'.format(varname))
raise EnvironmentException('Cross variable {0} is not a boolean.'.format(varname))
return self.compiles(templ % (prefix, funcname))
def has_member(self, typename, membername, prefix):
@ -915,13 +927,13 @@ class VisualStudioCCompiler(CCompiler):
self.always_args = VisualStudioCCompiler.vs2013_always_args
else:
self.always_args = VisualStudioCCompiler.vs2010_always_args
self.warn_args = {'1': ['/W2'],
'2': ['/W3'],
'3': ['/w4']}
def get_always_args(self):
return self.always_args
def get_std_warn_args(self):
return self.std_warn_args
def get_buildtype_args(self, buildtype):
return msvc_buildtype_args[buildtype]
@ -1039,7 +1051,8 @@ def get_gcc_soname_args(gcc_type, shlib_name, path, soversion):
sostr = ''
else:
sostr = '.' + soversion
if gcc_type == GCC_STANDARD:
if gcc_type == GCC_STANDARD or gcc_type == GCC_MINGW:
# Might not be correct for mingw but seems to work.
return ['-Wl,-soname,lib%s.so%s' % (shlib_name, sostr)]
elif gcc_type == GCC_OSX:
return ['-install_name', os.path.join(path, 'lib' + shlib_name + '.dylib')]
@ -1047,17 +1060,13 @@ def get_gcc_soname_args(gcc_type, shlib_name, path, soversion):
raise RuntimeError('Not implemented yet.')
class GnuCCompiler(CCompiler):
old_warn = ['-Wall', '-pedantic', '-Winvalid-pch']
new_warn = ['-Wall', '-Wpedantic', '-Winvalid-pch']
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
self.id = 'gcc'
self.gcc_type = gcc_type
if mesonlib.version_compare(version, ">=4.9.0"):
self.warn_args= GnuCCompiler.new_warn
else:
self.warn_args = GnuCCompiler.old_warn
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wpedantic', '-Winvalid-pch'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']}
def get_pic_args(self):
if self.gcc_type == GCC_MINGW:
@ -1067,9 +1076,6 @@ class GnuCCompiler(CCompiler):
def get_always_args(self):
return ['-pipe']
def get_std_warn_args(self):
return self.warn_args
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
@ -1089,7 +1095,7 @@ class GnuCCompiler(CCompiler):
return super().can_compile(filename) or filename.split('.')[-1].lower() == 's' # Gcc can do asm, too.
class GnuObjCCompiler(ObjCCompiler):
std_warn_args = ['-Wall', '-Wpedantic', '-Winvalid-pch']
std_opt_args = ['-O2']
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
ObjCCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
@ -1097,9 +1103,9 @@ class GnuObjCCompiler(ObjCCompiler):
# Not really correct, but GNU objc is only used on non-OSX non-win. File a bug
# if this breaks your use case.
self.gcc_type = GCC_STANDARD
def get_std_warn_args(self):
return GnuObjCCompiler.std_warn_args
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wpedantic', '-Winvalid-pch'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']}
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
@ -1114,7 +1120,6 @@ class GnuObjCCompiler(ObjCCompiler):
return get_gcc_soname_args(self.gcc_type, shlib_name, path, soversion)
class GnuObjCPPCompiler(ObjCPPCompiler):
std_warn_args = ['-Wall', '-Wpedantic', '-Winvalid-pch']
std_opt_args = ['-O2']
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
@ -1123,9 +1128,9 @@ class GnuObjCPPCompiler(ObjCPPCompiler):
# Not really correct, but GNU objc is only used on non-OSX non-win. File a bug
# if this breaks your use case.
self.gcc_type = GCC_STANDARD
def get_std_warn_args(self):
return GnuObjCPPCompiler.std_warn_args
self.warn_args = {'1': ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'2': ['-Wall', '-Wpedantic', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']}
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
@ -1155,9 +1160,9 @@ class ClangCCompiler(CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
self.id = 'clang'
def get_std_warn_args(self):
return ClangCCompiler.std_warn_args
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wpedantic', '-Winvalid-pch'],
'3' : ['-Weverything']}
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
@ -1179,8 +1184,6 @@ class ClangCCompiler(CCompiler):
class GnuCPPCompiler(CPPCompiler):
new_warn = ['-Wall', '-Wpedantic', '-Winvalid-pch', '-Wnon-virtual-dtor']
old_warn = ['-Wall', '-pedantic', '-Winvalid-pch', '-Wnon-virtual-dtor']
# may need to separate the latter to extra_debug_args or something
std_debug_args = ['-g']
@ -1188,17 +1191,13 @@ class GnuCPPCompiler(CPPCompiler):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.id = 'gcc'
self.gcc_type = gcc_type
if mesonlib.version_compare(version, ">=4.9.0"):
self.warn_args= GnuCPPCompiler.new_warn
else:
self.warn_args = GnuCPPCompiler.old_warn
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wpedantic', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']}
def get_always_args(self):
return ['-pipe']
def get_std_warn_args(self):
return self.warn_args
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
@ -1212,14 +1211,12 @@ class GnuCPPCompiler(CPPCompiler):
return get_gcc_soname_args(self.gcc_type, shlib_name, path, soversion)
class ClangCPPCompiler(CPPCompiler):
std_warn_args = ['-Wall', '-Wpedantic', '-Winvalid-pch', '-Wnon-virtual-dtor']
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
self.id = 'clang'
def get_std_warn_args(self):
return ClangCPPCompiler.std_warn_args
self.warn_args = {'1': ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'2': ['-Wall', '-Wpedantic', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3': ['-Weverything']}
def get_buildtype_args(self, buildtype):
return gnulike_buildtype_args[buildtype]
@ -1237,8 +1234,6 @@ class ClangCPPCompiler(CPPCompiler):
return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))]
class FortranCompiler():
std_warn_args = ['-Wall']
def __init__(self, exelist, version,is_cross, exe_wrapper=None):
super().__init__()
self.exelist = exelist
@ -1304,7 +1299,7 @@ end program prog
def get_linker_always_args(self):
return []
def get_std_warn_args(self):
def get_std_warn_args(self, level):
return FortranCompiler.std_warn_args
def get_buildtype_args(self, buildtype):
@ -1363,6 +1358,10 @@ end program prog
def module_name_to_filename(self, module_name):
return module_name.lower() + '.mod'
def get_warn_args(self, level):
return ['-Wall']
class GnuFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper=None)
@ -1388,7 +1387,7 @@ class SunFortranCompiler(FortranCompiler):
def get_always_args(self):
return []
def get_std_warn_args(self):
def get_warn_args(self):
return []
def get_module_outdir_args(self, path):
@ -1413,7 +1412,7 @@ class IntelFortranCompiler(FortranCompiler):
return True
return False
def get_std_warn_args(self):
def get_warn_args(self, level):
return IntelFortranCompiler.std_warn_args
class PathScaleFortranCompiler(FortranCompiler):
@ -1435,7 +1434,7 @@ class PathScaleFortranCompiler(FortranCompiler):
return True
return False
def get_std_warn_args(self):
def get_std_warn_args(self, level):
return PathScaleFortranCompiler.std_warn_args
class PGIFortranCompiler(FortranCompiler):
@ -1457,7 +1456,7 @@ class PGIFortranCompiler(FortranCompiler):
return True
return False
def get_std_warn_args(self):
def get_warn_args(self, level):
return PGIFortranCompiler.std_warn_args
@ -1480,7 +1479,7 @@ class Open64FortranCompiler(FortranCompiler):
return True
return False
def get_std_warn_args(self):
def get_warn_args(self, level):
return Open64FortranCompiler.std_warn_args
class NAGFortranCompiler(FortranCompiler):
@ -1502,7 +1501,7 @@ class NAGFortranCompiler(FortranCompiler):
return True
return False
def get_std_warn_args(self):
def get_warn_args(self, level):
return NAGFortranCompiler.std_warn_args

@ -14,7 +14,7 @@
import pickle, os, uuid
version = '0.26.0-research'
version = '0.27.0-research'
builtin_options = {'buildtype': True,
'strip': True,
@ -29,8 +29,10 @@ builtin_options = {'buildtype': True,
'mandir' : True,
'localedir' : True,
'werror' : True,
'warning_level': True,
'layout' : True,
}
# This class contains all data that must persist over multiple
# invocations of Meson. It is roughly the same thing as
# cmakecache.
@ -55,6 +57,7 @@ class CoreData():
self.use_pch = options.use_pch
self.unity = options.unity
self.coverage = options.coverage
self.warning_level = options.warning_level
self.werror = options.werror
self.layout = options.layout
self.user_options = {}

@ -0,0 +1,26 @@
# This is a cross compilation file from OSX Yosemite to iPhone
# Apple keeps changing the location and names of files so
# these might not work for you. Use the googels and xcrun.
[binaries]
c = 'clang'
cpp = 'clang++'
ar = 'ar'
strip = 'strip'
[properties]
root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer'
c_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk']
cpp_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk']
c_link_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk']
cpp_link_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk']
has_function_printf = true
has_function_hfkerhisadf = false
[host_machine]
system = 'ios'
cpu = 'armv7'
endian = 'little'

@ -10,14 +10,6 @@ pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config'
[properties]
root = '/usr/arm-linux-gnueabihf'
sizeof_int = 4
sizeof_wchar_t = 4
sizeof_void* = 4
alignment_char = 1
alignment_void* = 4
alignment_double = 4 # Don't know if this is correct...
has_function_printf = true
has_function_hfkerhisadf = false

@ -393,6 +393,7 @@ class BoostDependency(Dependency):
def __init__(self, environment, kwargs):
Dependency.__init__(self)
self.name = 'boost'
self.libdir = ''
try:
self.boost_root = os.environ['BOOST_ROOT']
if not os.path.isabs(self.boost_root):
@ -400,9 +401,15 @@ class BoostDependency(Dependency):
except KeyError:
self.boost_root = None
if self.boost_root is None:
self.incdir = '/usr/include/boost'
if mesonlib.is_windows():
self.boost_root = self.detect_win_root()
self.incdir = self.boost_root
else:
self.incdir = '/usr/include'
else:
self.incdir = os.path.join(self.boost_root, 'include/boost')
self.incdir = os.path.join(self.boost_root, 'include')
self.boost_inc_subdir = os.path.join(self.incdir, 'boost')
mlog.debug('Boost library root dir is', self.boost_root)
self.src_modules = {}
self.lib_modules = {}
self.lib_modules_mt = {}
@ -422,17 +429,26 @@ class BoostDependency(Dependency):
else:
mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red('NO'))
def detect_win_root(self):
globtext = 'c:\\local\\boost_*'
files = glob.glob(globtext)
if len(files) > 0:
return files[0]
return 'C:\\'
def get_compile_args(self):
args = []
if self.boost_root is not None:
args.append('-I' + os.path.join(self.boost_root, 'include'))
if mesonlib.is_windows():
args.append('-I' + self.boost_root)
else:
args.append('-I' + os.path.join(self.boost_root, 'include'))
else:
args.append('-I' + self.incdir)
return args
def get_requested(self, kwargs):
modules = 'modules'
if not modules in kwargs:
raise DependencyException('Boost dependency must specify "%s" keyword.' % modules)
candidates = kwargs[modules]
candidates = kwargs.get('modules', [])
if isinstance(candidates, str):
return [candidates]
for c in candidates:
@ -453,7 +469,7 @@ class BoostDependency(Dependency):
def detect_version(self):
try:
ifile = open(os.path.join(self.incdir, 'version.hpp'))
ifile = open(os.path.join(self.boost_inc_subdir, 'version.hpp'))
except FileNotFoundError:
self.version = None
return
@ -466,13 +482,41 @@ class BoostDependency(Dependency):
self.version = None
def detect_src_modules(self):
for entry in os.listdir(self.incdir):
entry = os.path.join(self.incdir, entry)
for entry in os.listdir(self.boost_inc_subdir):
entry = os.path.join(self.boost_inc_subdir, entry)
if stat.S_ISDIR(os.stat(entry).st_mode):
self.src_modules[os.path.split(entry)[-1]] = True
def detect_lib_modules(self):
globber = 'libboost_*.so' # FIXME, make platform independent.
if mesonlib.is_windows():
return self.detect_lib_modules_win()
return self.detect_lib_modules_nix()
def detect_lib_modules_win(self):
if mesonlib.is_32bit():
gl = 'lib32*'
else:
gl = 'lib64*'
libdir = glob.glob(os.path.join(self.boost_root, gl))
if len(libdir) == 0:
return
libdir = libdir[0]
self.libdir = libdir
globber = 'boost_*-gd-*.lib' # FIXME
for entry in glob.glob(os.path.join(libdir, globber)):
(_, fname) = os.path.split(entry)
base = fname.split('_', 1)[1]
modname = base.split('-', 1)[0]
self.lib_modules_mt[modname] = fname
def detect_lib_modules_nix(self):
libsuffix = None
if mesonlib.is_osx():
libsuffix = 'dylib'
else:
libsuffix = 'so'
globber = 'libboost_*.{}'.format(libsuffix)
if self.boost_root is None:
libdirs = mesonlib.get_library_dirs()
else:
@ -488,12 +532,24 @@ class BoostDependency(Dependency):
else:
self.lib_modules[name] = True
def get_link_args(self):
def get_win_link_args(self):
args = []
if self.boost_root:
# FIXME, these are in gcc format, not msvc.
# On the other hand, so are the args that
# pkg-config returns.
args.append('/LIBPATH:' + self.libdir)
for module in self.requested_modules:
module = BoostDependency.name2lib.get(module, module)
if module in self.lib_modules_mt:
args.append(self.lib_modules_mt[module])
return args
def get_link_args(self):
if mesonlib.is_windows():
return self.get_win_link_args()
args = []
if self.boost_root:
args.append('-L' + os.path.join(self.boost_root, 'lib'))
for module in self.requested_modules:
module = BoostDependency.name2lib.get(module, module)

@ -189,7 +189,12 @@ class Environment():
return GnuCCompiler(ccache + [compiler], version, GCC_OSX, is_cross, exe_wrap)
if (out.startswith('cc') or 'gcc' in out) and \
'Free Software Foundation' in out:
return GnuCCompiler(ccache + [compiler], version, GCC_STANDARD, is_cross, exe_wrap)
lowerout = out.lower()
if 'mingw' in lowerout or 'msys' in lowerout or 'mingw' in compiler.lower():
gtype = GCC_MINGW
else:
gtype = GCC_STANDARD
return GnuCCompiler(ccache + [compiler], version, gtype, is_cross, exe_wrap)
if 'clang' in out:
return ClangCCompiler(ccache + [compiler], version, is_cross, exe_wrap)
if 'Microsoft' in out:
@ -308,7 +313,12 @@ class Environment():
return GnuCPPCompiler(ccache + [compiler], version, GCC_OSX, is_cross, exe_wrap)
if (out.startswith('c++ ') or 'g++' in out or 'GCC' in out) and \
'Free Software Foundation' in out:
return GnuCPPCompiler(ccache + [compiler], version, GCC_STANDARD, is_cross, exe_wrap)
lowerout = out.lower()
if 'mingw' in lowerout or 'msys' in lowerout or 'mingw' in compiler.lower():
gtype = GCC_MINGW
else:
gtype = GCC_STANDARD
return GnuCPPCompiler(ccache + [compiler], version, gtype, is_cross, exe_wrap)
if 'clang' in out:
return ClangCPPCompiler(ccache + [compiler], version, is_cross, exe_wrap)
if 'Microsoft' in out:
@ -622,7 +632,7 @@ class CrossBuildInfo():
for i in res:
if not self.ok_type(i):
raise EnvironmentException('Malformed value in cross file variable %s.' % varname)
self.items[varname] = res
self.config[s][entry] = res
else:
raise EnvironmentException('Malformed value in cross file variable %s.' % varname)

@ -1462,11 +1462,18 @@ class Interpreter():
self.add_target(name, tg.held_object)
return tg
@stringArgs
@noKwargs
def func_run_target(self, node, args, kwargs):
if len(args) < 2:
raise InterpreterException('Incorrect number of arguments')
for i in args:
try:
i = i.held_object
except AttributeError:
pass
if not isinstance(i, (str, build.BuildTarget)):
mlog.debug('Wrong type:', str(i))
raise InterpreterException('Invalid argument to run_target.')
name = args[0]
command = args[1]
cmd_args = args[2:]

@ -1,4 +1,4 @@
.TH MESON "1" "July 2015" "meson 0.25.0" "User Commands"
.TH MESON "1" "September 2015" "meson 0.26.0" "User Commands"
.SH NAME
meson - a high productivity build system
.SH DESCRIPTION

@ -1,4 +1,4 @@
.TH MESONCONF "1" "July 2015" "mesonconf 0.25.0" "User Commands"
.TH MESONCONF "1" "September 2015" "mesonconf 0.26.0" "User Commands"
.SH NAME
mesonconf - a tool to configure Meson builds
.SH DESCRIPTION

@ -1,4 +1,4 @@
.TH MESONGUI "1" "July 2015" "mesongui 0.25.0" "User Commands"
.TH MESONGUI "1" "September 2015" "mesongui 0.26.0" "User Commands"
.SH NAME
mesongui - a gui for the Meson build system
.SH DESCRIPTION

@ -1,4 +1,4 @@
.TH MESONCONF "1" "July 2015" "mesonintrospect 0.25.0" "User Commands"
.TH MESONCONF "1" "September 2015" "mesonintrospect 0.26.0" "User Commands"
.SH NAME
mesonintrospect - a tool to extract information about a Meson build
.SH DESCRIPTION

@ -1,4 +1,4 @@
.TH WRAPTOOL "1" "July 2015" "meson 0.25.0" "User Commands"
.TH WRAPTOOL "1" "September 2015" "meson 0.26.0" "User Commands"
.SH NAME
wraptool - source dependency downloader
.SH DESCRIPTION

@ -29,6 +29,15 @@ parser = argparse.ArgumentParser()
backendlist = ['ninja', 'vs2010', 'xcode']
build_types = ['plain', 'debug', 'debugoptimized', 'release']
layouts = ['mirror', 'flat']
warning_levels = ['1', '2', '3']
default_warning = '1'
try:
warn_candidate = os.environ['MESON_WARN_LEVEL']
if warn_candidate in warning_levels:
default_warning = warn_candidate
except KeyError:
pass
if mesonlib.is_windows():
def_prefix = 'c:/'
@ -65,6 +74,8 @@ parser.add_argument('--werror', action='store_true', dest='werror', default=Fals
help='Treat warnings as errors')
parser.add_argument('--layout', choices=layouts, dest='layout', default='mirror',\
help='Build directory layout.')
parser.add_argument('--warnlevel', default=default_warning, dest='warning_level', choices=warning_levels,\
help='Level of compiler warnings to use (larger is more, default is %(default)s)')
parser.add_argument('--cross-file', default=None, dest='cross_file',
help='file describing cross compilation environment')
parser.add_argument('-D', action='append', dest='projectoptions', default=[],

@ -18,7 +18,7 @@ import sys, os
import pickle
import argparse
import coredata, optinterpreter
from meson import build_types, layouts
from meson import build_types, layouts, warning_levels
parser = argparse.ArgumentParser()
@ -84,6 +84,10 @@ class Conf:
if v not in layouts:
raise ConfException('Invalid layout type %s.' % v)
self.coredata.layout = v
elif k == 'warnlevel':
if not v in warning_levels:
raise ConfException('Invalid warning level %s.' % v)
self.coredata.warning_level = v
elif k == 'strip':
self.coredata.strip = self.tobool(v)
elif k == 'coverage':
@ -162,6 +166,7 @@ class Conf:
print('Core options\n')
carr = []
carr.append(['buildtype', 'Build type', self.coredata.buildtype])
carr.append(['warnlevel', 'Warning level', self.coredata.warning_level])
carr.append(['strip', 'Strip on install', self.coredata.strip])
carr.append(['coverage', 'Coverage report', self.coredata.coverage])
carr.append(['pch', 'Precompiled headers', self.coredata.use_pch])

@ -14,7 +14,7 @@
"""A library of random helper functionality."""
import platform, subprocess, operator, os, shutil, re
import platform, subprocess, operator, os, shutil, re, sys
from glob import glob
@ -79,6 +79,9 @@ def is_windows():
platname = platform.system().lower()
return platname == 'windows' or 'mingw' in platname
def is_32bit():
return not(sys.maxsize > 2**32)
def is_debianlike():
try:
open('/etc/debian_version', 'r')
@ -113,9 +116,13 @@ def detect_vcs(source_dir):
return vcs
return None
numpart = re.compile('[0-9.]+')
def version_compare(vstr1, vstr2):
if '-' in vstr1:
vstr1 = vstr1.split('-')[0]
match = numpart.match(vstr1.strip())
if match is None:
raise MesonException('Unconparable version string %s.' % vstr1)
vstr1 = match.group(0)
if vstr2.startswith('>='):
cmpop = operator.ge
vstr2 = vstr2[2:]

@ -114,6 +114,13 @@ class NinjaBackend(backends.Backend):
self.source_suffix_in_objs = True
self.ninja_filename = 'build.ninja'
self.fortran_deps = {}
self.all_outputs = {}
def check_outputs(self, elem):
for n in elem.outfilenames:
if n in self.all_outputs:
raise MesonException('Multiple producers for Ninja target "%s". Please rename your targets.' % n)
self.all_outputs[n] = True
def generate(self, interp):
self.interpreter = interp
@ -259,7 +266,8 @@ class NinjaBackend(backends.Backend):
obj_list.append(self.generate_single_compile(target, outfile, src, True, unity_deps + header_deps))
linker = self.determine_linker(target, src_list)
elem = self.generate_link(target, outfile, outname, obj_list, linker, pch_objects)
self.generate_shlib_aliases(target, self.get_target_dir(target), outfile, elem)
self.generate_shlib_aliases(target, self.get_target_dir(target))
elem.write(outfile)
self.processed_targets[name] = True
def process_target_dependencies(self, target, outfile):
@ -326,17 +334,42 @@ class NinjaBackend(backends.Backend):
elem.add_item('COMMAND', cmd)
elem.add_item('description', 'Generating %s with a custom command.' % target.name)
elem.write(outfile)
self.check_outputs(elem)
self.processed_targets[target.name + target.type_suffix()] = True
def generate_run_target(self, target, outfile):
runnerscript = os.path.join(self.environment.get_script_dir(), 'commandrunner.py')
elem = NinjaBuildElement(target.name, 'CUSTOM_COMMAND', [])
cmd = [sys.executable, runnerscript, self.environment.get_source_dir(), self.environment.get_build_dir(),
target.subdir, target.command] + target.args
deps = []
arg_strings = []
for i in target.args:
if isinstance(i, str):
arg_strings.append(i)
elif isinstance(i, build.BuildTarget):
deps.append(self.get_target_filename(i))
else:
raise MesonException('Unreachable code.')
elem = NinjaBuildElement(target.name, 'CUSTOM_COMMAND', deps)
cmd = [sys.executable, runnerscript, self.environment.get_source_dir(), self.environment.get_build_dir(), target.subdir]
texe = target.command
try:
texe = texe.held_object
except AttributeError:
pass
if isinstance(texe, build.Executable):
abs_exe = os.path.join(self.environment.get_build_dir(), self.get_target_filename(texe))
deps.append(self.get_target_filename(texe))
if self.environment.is_cross_build() \
and self.environment.cross_info.config['binaries'].get('exe_wrapper', None) is not None:
cmd += [self.environment.cross_info.config['binaries']['exe_wrapper']]
cmd.append(abs_exe)
else:
cmd.append(target.command)
cmd += target.args
elem.add_item('COMMAND', cmd)
elem.add_item('description', 'Running external command %s.' % target.name)
elem.add_item('pool', 'console')
elem.write(outfile)
self.check_outputs(elem)
self.processed_targets[target.name + target.type_suffix()] = True
def generate_po(self, outfile):
@ -349,6 +382,7 @@ class NinjaBackend(backends.Backend):
elem.add_item('FILELIST', os.path.join(self.environment.get_source_dir(), input_file))
elem.add_item('OUTDIR', os.path.join(self.environment.get_source_dir(), subdir))
elem.write(outfile)
self.check_outputs(elem)
for l in languages:
infile = os.path.join(self.environment.get_source_dir(), subdir, l + '.po')
outfilename = os.path.join(subdir, l + '.gmo')
@ -356,6 +390,7 @@ class NinjaBackend(backends.Backend):
lelem.add_item('INFILE', infile)
lelem.add_item('OUTFILE', outfilename)
lelem.write(outfile)
self.check_outputs(lelem)
def generate_coverage_rules(self, outfile):
(gcovr_exe, lcov_exe, genhtml_exe) = environment.find_coverage_tools()
@ -372,6 +407,7 @@ class NinjaBackend(backends.Backend):
'-o', os.path.join(self.environment.get_log_dir(), 'coverage.txt')])
elem.add_item('DESC', 'Generating text coverage report.')
elem.write(outfile)
self.check_outputs(elem)
if lcov_exe and genhtml_exe:
added_rule = True
phony_elem = NinjaBuildElement('coverage-html', 'phony', 'coveragereport/index.html')
@ -385,6 +421,7 @@ class NinjaBackend(backends.Backend):
'--legend', '--show-details', 'coverage.info']
elem.add_item('COMMAND', command)
elem.add_item('DESC', 'Generating HTML coverage report.')
self.check_outputs(elem)
elem.write(outfile)
if not added_rule:
mlog.log(mlog.red('Warning:'), 'coverage requested but neither gcovr nor lcov/genhtml found.')
@ -412,6 +449,7 @@ class NinjaBackend(backends.Backend):
self.generate_custom_install_script(d)
self.generate_subdir_install(d)
elem.write(outfile)
self.check_outputs(elem)
ofile = open(install_data_file, 'wb')
pickle.dump(d, ofile)
@ -517,6 +555,7 @@ class NinjaBackend(backends.Backend):
elem.add_item('DESC', 'Running test suite.')
elem.add_item('pool', 'console')
elem.write(outfile)
self.check_outputs(elem)
if valgrind:
velem = NinjaBuildElement('test-valgrind', 'CUSTOM_COMMAND', ['all', 'PHONY'])
@ -524,6 +563,7 @@ class NinjaBackend(backends.Backend):
velem.add_item('DESC', 'Running test suite under Valgrind.')
velem.add_item('pool', 'console')
velem.write(outfile)
self.check_outputs(velem)
def generate_rules(self, outfile):
outfile.write('# Rules for compiling.\n\n')
@ -600,6 +640,7 @@ class NinjaBackend(backends.Backend):
elem.add_dep([os.path.join(self.get_target_private_dir(target), i) for i in class_list])
elem.add_item('ARGS', commands)
elem.write(outfile)
self.check_outputs(elem)
def generate_cs_resource_tasks(self, target, outfile):
args = []
@ -615,6 +656,7 @@ class NinjaBackend(backends.Backend):
elem.add_item('COMMAND', ['resgen', rel_sourcefile, ofilename])
elem.add_item('DESC', 'Compiling resource %s.' % rel_sourcefile)
elem.write(outfile)
self.check_outputs(elem)
deps.append(ofilename)
a = '-resource:' + ofilename
else:
@ -654,6 +696,7 @@ class NinjaBackend(backends.Backend):
elem = NinjaBuildElement(outputs, 'cs_COMPILER', rel_srcs)
elem.add_dep(deps)
elem.add_item('ARGS', commands)
self.check_outputs(elem)
elem.write(outfile)
def generate_single_java_compile(self, src, target, compiler, outfile):
@ -666,6 +709,7 @@ class NinjaBackend(backends.Backend):
element = NinjaBuildElement(rel_obj, compiler.get_language() + '_COMPILER', rel_src)
element.add_item('ARGS', args)
element.write(outfile)
self.check_outputs(element)
return plain_class_path
def generate_java_link(self, outfile):
@ -689,6 +733,7 @@ class NinjaBackend(backends.Backend):
element = NinjaBuildElement(rel_vapi, valac.get_language() + '_COMPILER', rel_s)
element.add_item('ARGS', args)
element.write(outfile)
self.check_outputs(element)
fastvapis[s] = (vapibase, rel_vapi)
return fastvapis
@ -751,6 +796,7 @@ class NinjaBackend(backends.Backend):
element.add_orderdep(vapi_order_deps)
element.add_dep(extra_dep_files)
element.write(outfile)
self.check_outputs(element)
return generated_c
def generate_rust_target(self, target, outfile):
@ -790,6 +836,7 @@ class NinjaBackend(backends.Backend):
element.add_item('targetdep', depfile)
element.add_item('cratetype', cratetype)
element.write(outfile)
self.check_outputs(element)
def generate_static_link_rules(self, is_cross, outfile):
if self.build.has_language('java'):
@ -832,11 +879,17 @@ class NinjaBackend(backends.Backend):
langname == 'rust' or langname == 'cs':
continue
crstr = ''
cross_args = []
if is_cross:
crstr = '_CROSS'
try:
cross_args = self.environment.cross_info.config['properties'][langname + '_link_args']
except KeyError:
pass
rule = 'rule %s%s_LINKER\n' % (langname, crstr)
command = ' command = %s $ARGS %s $in $LINK_ARGS $aliasing\n' % \
command = ' command = %s %s $ARGS %s $in $LINK_ARGS $aliasing\n' % \
(' '.join(compiler.get_linker_exelist()),\
' '.join(cross_args),\
' '.join(compiler.get_linker_output_args('$out')))
description = ' description = Linking target $out'
outfile.write(rule)
@ -957,8 +1010,15 @@ rule FORTRAN_DEP_HACK
if d != '$out' and d != '$in':
d = qstr % d
quoted_depargs.append(d)
command = " command = %s $ARGS %s %s %s $in\n" % \
cross_args = []
if is_cross:
try:
cross_args = self.environment.cross_info.config['properties'][langname + '_args']
except KeyError:
pass
command = " command = %s %s $ARGS %s %s %s $in\n" % \
(' '.join(compiler.get_exelist()),\
' '.join(cross_args),
' '.join(quoted_depargs),\
' '.join(compiler.get_output_args('$out')),\
' '.join(compiler.get_compile_only_args()))
@ -983,6 +1043,13 @@ rule FORTRAN_DEP_HACK
crstr = ''
rule = 'rule %s%s_PCH\n' % (langname, crstr)
depargs = compiler.get_dependency_gen_args('$out', '$DEPFILE')
cross_args = []
if is_cross:
try:
cross_args = self.environment.cross_info.config['properties'][langname + '_args']
except KeyError:
pass
quoted_depargs = []
for d in depargs:
if d != '$out' and d != '$in':
@ -992,8 +1059,9 @@ rule FORTRAN_DEP_HACK
output = ''
else:
output = ' '.join(compiler.get_output_args('$out'))
command = " command = %s $ARGS %s %s %s $in\n" % \
command = " command = %s %s $ARGS %s %s %s $in\n" % \
(' '.join(compiler.get_exelist()),\
' '.join(cross_args),\
' '.join(quoted_depargs),\
output,\
' '.join(compiler.get_compile_only_args()))
@ -1086,6 +1154,7 @@ rule FORTRAN_DEP_HACK
elem.add_dep(self.get_target_filename(exe))
elem.add_item('COMMAND', cmdlist)
elem.write(outfile)
self.check_outputs(elem)
def scan_fortran_module_outputs(self, target):
compiler = None
@ -1233,6 +1302,7 @@ rule FORTRAN_DEP_HACK
if srcfile == src:
depelem = NinjaBuildElement(modfile, 'FORTRAN_DEP_HACK', rel_obj)
depelem.write(outfile)
self.check_outputs(depelem)
commands += compiler.get_module_outdir_args(self.get_target_private_dir_abs(target))
element = NinjaBuildElement(rel_obj, compiler_name, rel_src)
@ -1257,6 +1327,7 @@ rule FORTRAN_DEP_HACK
element.add_item('DEPFILE', dep_file)
element.add_item('ARGS', commands)
element.write(outfile)
self.check_outputs(element)
return rel_obj
# Fortran is a bit weird (again). When you link against a library, just compiling a source file
@ -1322,6 +1393,7 @@ rule FORTRAN_DEP_HACK
elem.add_item('ARGS', commands)
elem.add_item('DEPFILE', dep)
elem.write(outfile)
self.check_outputs(elem)
return pch_objects
def generate_shsym(self, outfile, target):
@ -1332,6 +1404,7 @@ rule FORTRAN_DEP_HACK
if self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler():
elem.add_item('CROSS', '--cross-host=' + self.environment.cross_info.config['host_machine']['system'])
elem.write(outfile)
self.check_outputs(elem)
def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[]):
if isinstance(target, build.StaticLibrary):
@ -1395,6 +1468,7 @@ rule FORTRAN_DEP_HACK
elem = NinjaBuildElement(outname, linker_rule, obj_list)
elem.add_dep(dep_targets)
elem.add_item('LINK_ARGS', commands)
self.check_outputs(elem)
return elem
def determine_rpath_dirs(self, target):
@ -1411,19 +1485,19 @@ rule FORTRAN_DEP_HACK
return os.path.join(self.get_target_private_dir_abs(t), self.get_target_filename(t) + '.symbols')
return self.get_target_filename(t)
def generate_shlib_aliases(self, target, outdir, outfile, elem):
def generate_shlib_aliases(self, target, outdir):
basename = target.get_filename()
aliases = target.get_aliaslist()
aliascmd = []
if shutil.which('ln'):
if not mesonlib.is_windows():
for alias in aliases:
aliasfile = os.path.join(outdir, alias)
cmd = ["&&", 'ln', '-s', '-f', basename, aliasfile]
aliascmd += cmd
aliasfile = os.path.join(self.environment.get_build_dir(), outdir, alias)
try:
os.remove(aliasfile)
except Exception:
pass
os.symlink(basename, aliasfile)
else:
mlog.log("Library versioning disabled because host does not support symlinks.")
elem.add_item('aliasing', aliascmd)
elem.write(outfile)
mlog.debug("Library versioning disabled because host does not support symlinks.")
def generate_gcov_clean(self, outfile):
gcno_elem = NinjaBuildElement('clean-gcno', 'CUSTOM_COMMAND', 'PHONY')
@ -1432,6 +1506,7 @@ rule FORTRAN_DEP_HACK
gcno_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcno'])
gcno_elem.add_item('description', 'Deleting gcno files')
gcno_elem.write(outfile)
self.check_outputs(gcno_elem, gcno_elem)
gcda_elem = NinjaBuildElement('clean-gcda', 'CUSTOM_COMMAND', 'PHONY')
script_root = self.environment.get_script_dir()
@ -1439,6 +1514,7 @@ rule FORTRAN_DEP_HACK
gcda_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcda'])
gcda_elem.add_item('description', 'Deleting gcda files')
gcda_elem.write(outfile)
self.check_outputs(gcda_elem)
def is_compilable_file(self, filename):
if filename.endswith('.cpp') or\
@ -1464,6 +1540,7 @@ rule FORTRAN_DEP_HACK
infilename = os.path.join(self.build_to_src, target.get_source_subdir(), src)
elem = NinjaBuildElement(outfilename, rule.name, infilename)
elem.write(outfile)
self.check_outputs(elem)
if self.is_compilable_file(outfilename):
src_deps.append(outfilename)
else:
@ -1476,6 +1553,7 @@ rule FORTRAN_DEP_HACK
elem = NinjaBuildElement('all', 'phony', targetlist)
elem.write(outfile)
self.check_outputs(elem)
default = 'default all\n\n'
outfile.write(default)
@ -1491,6 +1569,7 @@ rule FORTRAN_DEP_HACK
elem.add_dep('clean-gcda')
elem.add_dep('clean-gcno')
elem.write(outfile)
self.check_outputs(elem)
deps = [os.path.join(self.build_to_src, df) \
for df in self.interpreter.get_build_def_files()]
@ -1510,3 +1589,4 @@ rule FORTRAN_DEP_HACK
elem = NinjaBuildElement(deps, 'phony', '')
elem.write(outfile)
self.check_outputs(elem)

@ -0,0 +1,10 @@
#include<stdio.h>
int main(int argc, char **argv) {
if(argc != 2) {
printf("I can not haz argument.\n");
} else {
printf("I can haz argument: %s\n", argv[1]);
}
return 0;
}

@ -1,3 +1,9 @@
project('run target', 'c')
run_target('mycommand', 'scripts/script.sh')
# Make it possible to run built programs.
# In cross builds exe_wrapper should be added if it exists.
exe = executable('helloprinter', 'helloprinter.c')
run_target('runhello', exe, 'argument')

@ -0,0 +1,6 @@
#include<stdio.h>
int main(int argc, char **argv) {
printf("Clash 2.\n");
return 0;
}

@ -0,0 +1,15 @@
project('clash', 'c')
# This setup causes a namespace clash when two Meson targets would
# produce a Ninja targets with the same name. It only works on
# unix, because on Windows the target has a '.exe' suffix.
#
# This test might fail to work on different backends or when
# output location is redirected.
if host_machine.system() == 'windows'
error('This is expected.')
endif
executable('clash', 'clash.c')
run_target('clash', 'echo', 'clash 1')

@ -2,6 +2,8 @@ project('boosttest', 'cpp')
if meson.get_compiler('cpp').get_id() != 'msvc'
add_global_arguments('-std=c++11', language : 'cpp')
else
add_global_arguments('/EHsc', language : 'cpp')
endif
# We want to have multiple separate configurations of Boost
@ -11,11 +13,14 @@ endif
nolinkdep = dependency('boost', modules: 'utility')
linkdep = dependency('boost', modules : ['thread', 'system'])
testdep = dependency('boost', modules : 'test')
nomoddep = dependency('boost')
nolinkexe = executable('nolinkedexe', 'nolinkexe.cc', dependencies : nolinkdep)
linkexe = executable('linkedexe', 'linkexe.cc', dependencies : linkdep)
unitexe = executable('utf', 'unit_test.cpp', dependencies: testdep)
nomodexe = executable('nomod', 'nomod.cpp', dependencies : nomoddep)
test('Boost nolinktext', nolinkexe)
test('Boost linktext', linkexe)
test('Boost UTF test', unitexe)
test('Boost nomod', nomodexe)

@ -0,0 +1,18 @@
#include<boost/any.hpp>
#include<iostream>
boost::any get_any() {
boost::any foobar = 3;
return foobar;
}
int main(int argc, char **argv) {
boost::any result = get_any();
if(boost::any_cast<int>(result) == 3) {
std::cout << "Everything is fine in the worls.\n";
return 0;
} else {
std::cout << "Mathematics stopped working.\n";
return 1;
}
}

@ -0,0 +1,217 @@
#!/usr/bin/env python3
# Copyright 2015 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This script reads config.h.meson, looks for header
checks and writes the corresponding meson declaration.
Copy config.h.in to config.h.meson, replace #undef
with #mesondefine and run this. We can't do this automatically
because some configure scripts have #undef statements
that are unrelated to configure checks.
"""
import sys
print('''cc = meson.get_compiler('c')
cdata = configuration_data()''')
print('check_headers = [')
for line in open(sys.argv[1]):
line = line.strip()
if line.startswith('#mesondefine') and \
line.endswith('_H'):
token = line.split()[1]
tarr = token.split('_')[1:-1]
tarr = [x.lower() for x in tarr]
hname = '/'.join(tarr) + '.h'
print(" ['%s', '%s']," % (token, hname))
print(']\n')
print('''foreach h : check_headers
if cc.has_header(h.get(1))
cdata.set(h.get(0), 1)
endif
endforeach
''')
# Add stuff here as it is encountered.
function_data = \
{'HAVE_FEENABLEEXCEPT' : ('feenableexcept', 'fenv.h'),
'HAVE_FECLEAREXCEPT' : ('feclearexcept', 'fenv.h'),
'HAVE_FEDISABLEEXCEPT' : ('fedisableexcept', 'fenv.h'),
'HAVE_MMAP' : ('mmap', 'sys/mman.h'),
'HAVE_GETPAGESIZE' : ('getpagesize', 'unistd.h'),
'HAVE_GETISAX' : ('getisax', 'sys/auxv.h'),
'HAVE_GETTIMEOFDAY' : ('gettimeofday', 'sys/time.h'),
'HAVE_MPROTECT' : ('mprotect', 'sys/mman.h'),
'HAVE_POSIX_MEMALIGN' : ('posix_memalign', 'stdlib.h'),
'HAVE_SIGACTION' : ('sigaction', 'signal.h'),
'HAVE_ALARM' : ('alarm', 'unistd.h'),
'HAVE_CLOCK_GETTIME' : ('clock_gettime', 'time.h'),
'HAVE_CTIME_R' : ('ctime_r', 'time.h'),
'HAVE_DRAND48' : ('drand48', 'stdlib.h'),
'HAVE_FLOCKFILE' : ('flockfile', 'stdio.h'),
'HAVE_FORK' : ('fork', 'unistd.h'),
'HAVE_FUNLOCKFILE' : ('funlockfile', 'stdio.h'),
'HAVE_GETLINE' : ('getline', 'stdio.h'),
'HAVE_LINK' : ('link', 'unistd.h'),
'HAVE_RAISE' : ('raise', 'signal.h'),
'HAVE_STRNDUP' : ('strndup', 'string.h'),
'HAVE_SCHED_GETAFFINITY' : ('sched_getaffinity', 'sched.h'),
'HAVE_WAITPID' : ('waitpid', 'sys/wait.h'),
'HAVE_XRENDERCREATECONICALGRADIENT' : ('XRenderCreateConicalGradient', 'xcb/render.h'),
'HAVE_XRENDERCREATELINEARGRADIENT' : ('XRenderCreateLinearGradient', 'xcb/render.h'),
'HAVE_XRENDERCREATERADIALGRADIENT' : ('XRenderCreateRadialGradient', 'xcb/render.h'),
'HAVE_XRENDERCREATESOLIDFILL' : ('XRenderCreateSolidFill', 'xcb/render.h'),
'HAVE_DCGETTEXT': ('dcgettext', 'libintl.h'),
'HAVE_ENDMNTENT': ('endmntent', 'mntent.h'),
'HAVE_ENDSERVENT' : ('endservent', 'netdb.h'),
'HAVE_EVENTFD': ('eventfd', 'sys/eventfd.h'),
'HAVE_FALLOCATE': ('fallocate', 'fcntl.h'),
'HAVE_FCHMOD': ('fchmod', 'sys/stat.h'),
'HAVE_FCHOWN': ('fchown', 'unistd.h'),
'HAVE_FDWALK': ('fdwalk', 'stdlib.h'),
'HAVE_FSYNC': ('fsync', 'unistd.h'),
'HAVE_GETC_UNLOCKED': ('getc_unlocked', 'stdio.h'),
'HAVE_GETFSSTAT': ('getfsstat', 'sys/mount.h'),
'HAVE_GETMNTENT_R': ('getmntent_r', 'mntent.h'),
'HAVE_GETPROTOBYNAME_R': ('getprotobyname_r', 'netdb.h'),
'HAVE_GETRESUID' : ('getresuid', 'unistd.h'),
'HAVE_GETVFSSTAT' : ('getvfsstat', 'sys/statvfs.h'),
'HAVE_GMTIME_R' : ('gmtime_r', 'time.h'),
'HAVE_HASMNTOPT': ('hasmntopt', 'mntent.h'),
'HAVE_IF_INDEXTONAME': ('if_indextoname', 'net/if.h'),
'HAVE_IF_NAMETOINDEX': ('if_nametoindex', 'net/if.h'),
'HAVE_INOTIFY_INIT1': ('inotify_init1', 'sys/inotify.h'),
'HAVE_ISSETUGID': ('issetugid', 'unistd.h'),
'HAVE_KEVENT': ('kevent', 'sys/event.h'),
'HAVE_KQUEUE': ('kqueue', 'sys/event.h'),
'HAVE_LCHMOD': ('lchmod', 'sys/stat.h'),
'HAVE_LCHOWN': ('lchown', 'unistd.h'),
'HAVE_LSTAT': ('lstat', 'sys/stat.h'),
'HAVE_MEMCPY': ('memcpy', 'string.h'),
'HAVE_MEMALIGN': ('memalign', 'stdlib.h'),
'HAVE_MEMMEM': ('memmem', 'string.h'),
'HAVE_NEWLOCALE': ('newlocale', 'locale.h'),
'HAVE_PIPE2': ('pipe2', 'fcntl.h'),
'HAVE_POLL': ('poll', 'poll.h'),
'HAVE_PRLIMIT': ('prlimit', 'sys/resource.h'),
'HAVE_PTHREAD_ATTR_SETSTACKSIZE': ('pthread_attr_setstacksize', 'pthread.h'),
'HAVE_PTHREAD_CONDATTR_SETCLOCK': ('pthread_condattr_setclock', 'pthread.h'),
'HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP': ('pthread_cond_timedwait_relative_np', 'pthread.h'),
'HAVE_READLINK': ('readlink', 'unistd.h'),
'HAVE_RES_INIT': ('res_init', 'resolv.h'),
'HAVE_SENDMMSG': ('sendmmsg', 'sys/socket.h'),
'HAVE_SETENV': ('setenv', 'stdlib.h'),
'HAVE_SETMNTENT': ('setmntent', 'mntent.h'),
'HAVE_SNPRINTF': ('snprintf', 'stdio.h'),
'HAVE_SPLICE': ('splice', 'fcntl.h'),
'HAVE_STATFS': ('statfs', 'mount.h'),
'HAVE_STATVFS': ('statvfs', 'sys/statvfs.h'),
'HAVE_STPCOPY': ('stpcopy', 'string.h'),
'HAVE_STRCASECMP': ('strcasecmp', 'strings.h'),
'HAVE_STRLCPY': ('strlcpy', 'string.h'),
'HAVE_STRNCASECMP': ('strncasecmp', 'strings.h'),
'HAVE_STRSIGNAL': ('strsignal', 'signal.h'),
'HAVE_STRTOD_L': ('strtod_l', 'stdlib.h'),
'HAVE_STRTOLL_L': ('strtoll_l', 'stdlib.h'),
'HAVE_STRTOULL_L': ('strtoull_l', 'stdlib.h'),
'HAVE_SYMLINK': ('symlink', 'unistd.h'),
'HAVE_SYSCTLBYNAME': ('sysctlbyname', 'sys/sysctl.h'),
'HAVE_TIMEGM': ('timegm', 'time.h'),
'HAVE_UNSETENV': ('unsetenv', 'stdlib.h'),
'HAVE_USELOCALE': ('uselocale', 'xlocale.h'),
'HAVE_UTIMES': ('utimes', 'sys/time.h'),
'HAVE_VALLOC': ('valloc', 'stdlib.h'),
'HAVE_VASPRINTF': ('vasprintf', 'stdio.h'),
'HAVE_VSNPRINTF': ('vsnprintf', 'stdio.h'),
'HAVE_BCOPY': ('bcopy', 'strings.h'),
'HAVE_STRERROR': ('strerror', 'string.h'),
'HAVE_MEMMOVE': ('memmove', 'string.h'),
'HAVE_STRTOIMAX': ('strtoimax', 'inttypes.h'),
'HAVE_STRTOLL': ('strtoll', 'stdlib.h'),
'HAVE_STRTOQ': ('strtoq', 'stdlib.h'),
'HAVE_ACCEPT4': ('accept4', 'sys/socket.h'),
'HAVE_CHMOD': ('chmod', 'sys/stat.h'),
'HAVE_CHOWN': ('chown', 'unistd.h'),
'HAVE_FSTAT': ('fstat', 'sys/stat.h'),
'HAVE_GETADDRINFO': ('getaddrinfo', 'netdb.h'),
'HAVE_GETGRGID_R': ('getgrgid_r', 'grp.h'),
'HAVE_GETGRNAM_R': ('getgrnam_r', 'grp.h'),
'HAVE_GETGROUPS': ('getgroups', 'grp.h'),
'HAVE_GETOPT_LONG': ('getopt_long', 'getopt.h'),
'HAVE_GETPWNAM_R': ('getpwnam', 'pwd.h'),
'HAVE_GETPWUID_R': ('getpwuid_r', 'pwd.h'),
'HAVE_GETUID': ('getuid', 'unistd.h'),
'HAVE_LRINTF': ('lrintf', 'math.h'),
'HAVE_MKFIFO': ('mkfifo', 'sys/stat.h'),
'HAVE_MLOCK': ('mlock', 'sys/mman.h'),
'HAVE_NANOSLEEP': ('nanosleep', 'time.h'),
'HAVE_PIPE': ('pipe', 'unistd.h'),
'HAVE_PPOLL': ('ppoll', 'poll.h'),
'HAVE_REGEXEC': ('regexec', 'regex.h'),
'HAVE_SETEGID': ('setegid', 'unistd.h'),
'HAVE_SETEUID': ('seteuid', 'unistd.h'),
'HAVE_SETPGID': ('setpgid', 'unistd.h'),
'HAVE_SETREGID': ('setregid', 'unistd.h'),
'HAVE_SETRESGID': ('setresgid', 'unistd.h'),
'HAVE_SETRESUID': ('setresuid', 'unistd.h'),
'HAVE_SHM_OPEN': ('shm_open', 'fcntl.h'),
'HAVE_SLEEP': ('sleep', 'unistd.h'),
'HAVE_STRERROR_R': ('strerror_r', 'string.h'),
'HAVE_STRTOF': ('strtof', 'stdlib.h'),
'HAVE_SYSCONF': ('sysconf', 'unistd.h'),
'HAVE_USLEEP': ('usleep', 'unistd.h'),
'HAVE_VFORK': ('vfork', 'unistd.h'),
}
print('check_functions = [')
for line in open(sys.argv[1]):
try:
token = line.split()[1]
if token in function_data:
fdata = function_data[token]
print(" ['%s', '%s', '#include<%s>']," % (token, fdata[0], fdata[1]))
elif token.startswith('HAVE_') and not token.endswith('_H'):
print('# check token', token)
except Exception:
pass
print(']\n')
print('''foreach f : check_functions
if cc.has_function(f.get(1), prefix : f.get(2))
cdata.set(f.get(0), 1)
endif
endforeach
''')
# Convert sizeof checks.
for line in open(sys.argv[1]):
arr = line.strip().split()
if len(arr) != 2:
continue
elem = arr[1]
if elem.startswith('SIZEOF_'):
typename = elem.split('_', 1)[1].replace('_P', '*').replace('_', ' ').lower().replace('size t', 'size_t')
print("cdata.set('%s', cc.sizeof('%s'))" % (elem, typename))
print('''
configure_file(input : 'config.h.in',
output : 'config.h',
configuration : cdata)''')

@ -1,122 +0,0 @@
#!/usr/bin/python3
# Copyright 2014 Jussi Pakkanen
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys, os, re
class Converter():
def __init__(self, root):
self.project_root = root
def readlines(self, file, continuator):
line = file.readline()
while line != '':
line = line.rstrip()
while line.endswith(continuator):
line = line[:-1] + file.readline().rstrip()
yield line
line = file.readline()
def convert(self, subdir=None):
if subdir is None:
subdir = self.project_root
try:
ifile = open(os.path.join(subdir, 'Makefile.am'))
except FileNotFoundError:
print('Makefile.am not found in subdir', subdir)
return
ofile = open(os.path.join(subdir, 'meson.build'), 'w')
if subdir == self.project_root:
self.process_autoconf(ofile, subdir)
for line in self.readlines(ifile, '\\'):
items = line.strip().split()
if len(items) == 0:
ofile.write('\n')
continue
if items[0] == 'SUBDIRS':
for i in items[2:]:
if i != '.':
ofile.write("subdir('%s')\n" % i)
self.convert(os.path.join(subdir, i))
elif items[0].endswith('_SOURCES'):
self.convert_target(ofile, items)
else:
ofile.write("# %s\n" % line)
def convert_target(self, ofile, items):
if items[0].endswith('la_SOURCES'):
func = 'shared_library'
tname = "'%s'" % items[0][:-11]
elif items[0].endswith('a_SOURCES'):
func = 'static_library'
tname = "'%s'" % items[0][:-10]
else:
func = 'executable'
tname = "'%s'" % items[0][:-8]
sources = [tname]
for s in items[2:]:
if s.startswith('$(') and s.endswith(')'):
s = s[2:-1]
else:
s = "'%s'" % s
sources.append(s)
ofile.write('%s(%s)\n' % (func, ',\n'.join(sources)))
def process_autoconf(self, ofile, subdir):
ifile = open(os.path.join(subdir, 'configure.ac'))
languages = []
name = 'undetected'
outlines = []
for line in self.readlines(ifile, ','):
line = line.strip()
if line == 'AC_PROG_CC':
languages.append("'c'")
elif line == 'AC_PROG_CXX':
languages.append("'cpp'")
elif line.startswith('AC_INIT'):
line = line[8:]
if line[0] == '[':
name = line.split(']')[0][1:]
else:
name = line.split()[0]
elif line.startswith('#'):
outlines.append(line + '\n')
elif line.startswith('PKG_CHECK_MODULES'):
rest = line.split('(', 1)[-1].strip()
pkgstanza = rest.split()[1:]
for i in pkgstanza:
i = i.strip()
dep = None
if '=' in i:
continue
if i.startswith('['):
dep = i[1:]
elif re.match('[a-zA-Z]', i):
dep = i
if dep is not None:
outlines.append("%s_dep = dependency('%s')\n" % (dep, dep))
else:
outlines.append('# %s\n' % line)
ofile.write("project(%s)\n" % ', '.join(["'%s'" % name] + languages))
ofile.writelines(outlines)
if __name__ == '__main__':
if len(sys.argv) != 2:
print(sys.argv[0], '<Autotools project root>')
sys.exit(1)
c = Converter(sys.argv[1])
c.convert()

@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python3
# Copyright 2014 Jussi Pakkanen

Loading…
Cancel
Save