aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.py2
-rw-r--r--dependencies.py21
-rw-r--r--interpreter.py16
-rw-r--r--manual tests/2 multiwrap/meson.build18
-rw-r--r--manual tests/2 multiwrap/prog.c66
-rw-r--r--manual tests/2 multiwrap/subprojects/libpng.wrap11
-rw-r--r--manual tests/2 multiwrap/subprojects/lua.wrap10
-rw-r--r--manual tests/2 multiwrap/subprojects/zlib.wrap10
-rw-r--r--mesonlib.py30
-rw-r--r--test cases/common/72 build always/main.c7
-rw-r--r--test cases/common/72 build always/meson.build15
-rw-r--r--test cases/common/72 build always/version.c.in3
-rw-r--r--test cases/common/72 build always/version.h3
-rwxr-xr-xtest cases/common/72 build always/version_gen.py29
-rw-r--r--test cases/common/73 vcstag/meson.build8
-rw-r--r--test cases/common/73 vcstag/tagprog.c9
-rw-r--r--test cases/common/73 vcstag/vcstag.c.in2
-rw-r--r--test cases/linuxlike/1 pkg-config/meson.build2
-rwxr-xr-xvcstagger.py62
-rw-r--r--wrap.py2
20 files changed, 315 insertions, 11 deletions
diff --git a/build.py b/build.py
index 7b05f19..3cce771 100644
--- a/build.py
+++ b/build.py
@@ -742,6 +742,8 @@ class CustomTarget:
else:
self.install = False
self.build_always = kwargs.get('build_always', False)
+ if not isinstance(self.build_always, bool):
+ raise InvalidArguments('Argument build_always must be a boolean.')
def get_basename(self):
return self.name
diff --git a/dependencies.py b/dependencies.py
index 2e48ac6..e3dfc74 100644
--- a/dependencies.py
+++ b/dependencies.py
@@ -72,7 +72,8 @@ class Dependency():
class PkgConfigDependency(Dependency):
pkgconfig_found = None
- def __init__(self, name, required):
+ def __init__(self, name, kwargs):
+ required = kwargs.get('required', True)
Dependency.__init__(self)
self.name = name
if PkgConfigDependency.pkgconfig_found is None:
@@ -92,9 +93,19 @@ class PkgConfigDependency(Dependency):
self.cargs = []
self.libs = []
else:
- mlog.log('Dependency', mlog.bold(name), 'found:', mlog.green('YES'))
- self.is_found = True
self.modversion = out.decode().strip()
+ mlog.log('Dependency', mlog.bold(name), 'found:', mlog.green('YES'), self.modversion)
+ version_requirement = kwargs.get('version', None)
+ if version_requirement is None:
+ self.is_found = True
+ else:
+ if not isinstance(version_requirement, str):
+ raise DependencyException('Version argument must be string.')
+ self.is_found = mesonlib.version_compare(self.modversion, version_requirement)
+ if not self.is_found and required:
+ raise DependencyException('Invalid version of a dependency, needed %s %s found %s.' % (name, version_requirement, self.modversion))
+ if not self.is_found:
+ return
p = subprocess.Popen(['pkg-config', '--cflags', name], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out = p.communicate()[0]
@@ -521,7 +532,7 @@ class Qt5Dependency(Dependency):
if isinstance(mods, str):
mods = [mods]
for module in mods:
- self.modules.append(PkgConfigDependency('Qt5' + module, False))
+ self.modules.append(PkgConfigDependency('Qt5' + module, kwargs))
if len(self.modules) == 0:
raise DependencyException('No Qt5 modules specified.')
if not qt5toolinfo_printed:
@@ -795,7 +806,7 @@ def find_external_dependency(name, kwargs):
pkg_exc = None
pkgdep = None
try:
- pkgdep = PkgConfigDependency(name, required)
+ pkgdep = PkgConfigDependency(name, kwargs)
if pkgdep.found():
return pkgdep
except Exception as e:
diff --git a/interpreter.py b/interpreter.py
index cd36d29..75a4135 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2014 The Meson development team
+# Copyright 2012-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.
@@ -726,8 +726,7 @@ class Interpreter():
'get_option' : self.func_get_option,
'subproject' : self.func_subproject,
'pkgconfig_gen' : self.func_pkgconfig_gen,
- 'vcs_info' : self.func_vcs_info,
- 'vcs_configure' : self.func_vcs_configure,
+ 'vcs_tag' : self.func_vcs_tag,
}
def get_build_def_files(self):
@@ -931,6 +930,7 @@ class Interpreter():
raise InterpreterException('Subproject directory does not exist and can not be downloaded.')
subdir = os.path.join('subprojects', resolved)
abs_subdir = os.path.join(self.build.environment.get_source_dir(), 'subprojects', subdir)
+ os.makedirs(os.path.join(self.build.environment.get_build_dir(), subdir), exist_ok=True)
self.global_args_frozen = True
mlog.log('\nExecuting subproject ', mlog.bold(dirname), '.\n', sep='')
subi = Interpreter(self.build, dirname, subdir)
@@ -1113,6 +1113,16 @@ class Interpreter():
def func_jar(self, node, args, kwargs):
return self.build_target(node, args, kwargs, JarHolder)
+ def func_vcs_tag(self, node, args, kwargs):
+ fallback = kwargs.get('fallback', None)
+ if not isinstance(fallback, str):
+ raise InterpreterException('Keyword argument must exist and be a string.')
+ del kwargs['fallback']
+ scriptfile = os.path.join(os.path.split(__file__)[0], 'vcstagger.py')
+ kwargs['command'] = [sys.executable, scriptfile, '@INPUT@', '@OUTPUT@', fallback]
+ kwargs['build_always'] = True
+ return self.func_custom_target(node, ['vcstag'], kwargs)
+
def func_custom_target(self, node, args, kwargs):
if len(args) != 1:
raise InterpreterException('Incorrect number of arguments')
diff --git a/manual tests/2 multiwrap/meson.build b/manual tests/2 multiwrap/meson.build
new file mode 100644
index 0000000..81337ad
--- /dev/null
+++ b/manual tests/2 multiwrap/meson.build
@@ -0,0 +1,18 @@
+project('multiwrap', 'c')
+
+# Using multiple downloaded projects for great justice.
+
+if meson.get_compiler('c').get_id() != 'msvc'
+ add_global_arguments('-std=c99', language : 'c')
+ extra_libs = ['-lm']
+else
+ extra_libs = []
+endif
+
+luap = subproject('lua')
+pngp = subproject('libpng')
+
+executable('prog', 'prog.c',
+include_directories : [pngp.get_variable('incdir'), luap.get_variable('incdir')],
+link_with :[pngp.get_variable('libpng'), luap.get_variable('lualib')],
+link_args : extra_libs)
diff --git a/manual tests/2 multiwrap/prog.c b/manual tests/2 multiwrap/prog.c
new file mode 100644
index 0000000..dd0349e
--- /dev/null
+++ b/manual tests/2 multiwrap/prog.c
@@ -0,0 +1,66 @@
+#include<lua.h>
+#include<stdio.h>
+#include<stdlib.h>
+#include<png.h>
+#include<string.h>
+#if !defined(_MSC_VER)
+#include<unistd.h>
+#endif
+
+static void *l_alloc (void *ud, void *ptr, size_t osize,
+ size_t nsize) {
+ (void)ud;
+ (void)osize;
+ if (nsize == 0) {
+ free(ptr);
+ return NULL;
+ } else {
+ return realloc(ptr, nsize);
+ }
+}
+
+void open_image(const char *fname) {
+ png_image image;
+
+ memset(&image, 0, (sizeof image));
+ image.version = PNG_IMAGE_VERSION;
+
+ if(png_image_begin_read_from_file(&image, fname) != 0) {
+ png_bytep buffer;
+
+ image.format = PNG_FORMAT_RGBA;
+ buffer = malloc(PNG_IMAGE_SIZE(image));
+
+ if(png_image_finish_read(&image, NULL, buffer, 0, NULL) != 0) {
+ printf("Image %s read failed: %s\n", fname, image.message);
+ }
+// png_free_image(&image);
+ free(buffer);
+ } else {
+ printf("Image %s open failed: %s", fname, image.message);
+ }
+}
+
+int printer(lua_State *l) {
+ if(!lua_isstring(l, 1)) {
+ fprintf(stderr, "Incorrect call.\n");
+ return 0;
+ }
+ open_image(lua_tostring(l, 1));
+ return 0;
+}
+
+
+int main(int argc, char **argv) {
+ lua_State *l = lua_newstate(l_alloc, NULL);
+ if(!l) {
+ printf("Lua state allocation failed.\n");
+ return 1;
+ }
+ lua_register(l, "printer", printer);
+ lua_getglobal(l, "printer");
+ lua_pushliteral(l, "foobar.png");
+ lua_call(l, 1, 0);
+ lua_close(l);
+ return 0;
+}
diff --git a/manual tests/2 multiwrap/subprojects/libpng.wrap b/manual tests/2 multiwrap/subprojects/libpng.wrap
new file mode 100644
index 0000000..bd65080
--- /dev/null
+++ b/manual tests/2 multiwrap/subprojects/libpng.wrap
@@ -0,0 +1,11 @@
+[mesonwrap]
+
+directory = libpng-1.6.16
+
+source_url = ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng16/libpng-1.6.16.tar.gz
+source_filename = libpng-1.6.16.tar.gz
+source_hash = 02f96b6bad5a381d36d7ba7a5d9be3b06f7fe6c274da00707509c23592a073ad
+
+patch_url = https://dl.dropboxusercontent.com/u/37517477/libpng-meson.tar.gz
+patch_filename = libpng-meson.tar.gz
+patch_hash = b91d1abb19711a5aaa4b8581000df0e15420e46d9ce6ecf688e33144ea688f06
diff --git a/manual tests/2 multiwrap/subprojects/lua.wrap b/manual tests/2 multiwrap/subprojects/lua.wrap
new file mode 100644
index 0000000..da2ca14
--- /dev/null
+++ b/manual tests/2 multiwrap/subprojects/lua.wrap
@@ -0,0 +1,10 @@
+[mesonwrap]
+directory = lua-5.3.0
+
+source_url = http://www.lua.org/ftp/lua-5.3.0.tar.gz
+source_filename = lua-5.3.0.tar.gz
+source_hash = ae4a5eb2d660515eb191bfe3e061f2b8ffe94dce73d32cfd0de090ddcc0ddb01
+
+patch_url = https://dl.dropboxusercontent.com/u/37517477/lua53-meson.zip
+patch_filename = lua53-meson.zip
+patch_hash = 076d0d57d33ec996c556722c8eeb624a364c66fe9d2225e590b1bc9ae34fbd6e \ No newline at end of file
diff --git a/manual tests/2 multiwrap/subprojects/zlib.wrap b/manual tests/2 multiwrap/subprojects/zlib.wrap
new file mode 100644
index 0000000..7ea3354
--- /dev/null
+++ b/manual tests/2 multiwrap/subprojects/zlib.wrap
@@ -0,0 +1,10 @@
+[mesonwrap]
+directory = zlib-1.2.8
+
+source_url = http://zlib.net/zlib-1.2.8.tar.gz
+source_filename = zlib-1.2.8.tar.gz
+source_hash = 36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d
+
+patch_url = https://dl.dropboxusercontent.com/u/37517477/zlib128-meson.tar.gz
+patch_filename = zlib128-meson.tar.gz
+patch_hash = 03c868bf22d7e35c978e8b9572c4aea1181606c15c3dd19f0713a8479fe27edc
diff --git a/mesonlib.py b/mesonlib.py
index c30057e..7e15770 100644
--- a/mesonlib.py
+++ b/mesonlib.py
@@ -14,7 +14,7 @@
"""A library of random helper functionality."""
-import platform, subprocess
+import platform, subprocess, operator
def is_osx():
return platform.system().lower() == 'darwin'
@@ -41,3 +41,31 @@ def exe_exists(arglist):
except FileNotFoundError:
pass
return False
+
+def version_compare(vstr1, vstr2):
+ if vstr2.startswith('>='):
+ cmpop = operator.ge
+ vstr2 = vstr2[2:]
+ elif vstr2.startswith('<='):
+ cmpop = operator.le
+ vstr2 = vstr2[2:]
+ elif vstr2.startswith('!='):
+ cmpop = operator.ne
+ vstr2 = vstr2[2:]
+ elif vstr2.startswith('=='):
+ cmpop = operator.eq
+ vstr2 = vstr2[2:]
+ elif vstr2.startswith('='):
+ cmpop = operator.eq
+ vstr2 = vstr2[1:]
+ elif vstr2.startswith('>'):
+ cmpop = operator.gt
+ vstr2 = vstr2[1:]
+ elif vstr2.startswith('<'):
+ cmpop = operator.lt
+ vstr2 = vstr2[1:]
+ else:
+ cmpop = operator.eq
+ varr1 = [int(x) for x in vstr1.split('.')]
+ varr2 = [int(x) for x in vstr2.split('.')]
+ return cmpop(varr1, varr2)
diff --git a/test cases/common/72 build always/main.c b/test cases/common/72 build always/main.c
new file mode 100644
index 0000000..f8d9ac9
--- /dev/null
+++ b/test cases/common/72 build always/main.c
@@ -0,0 +1,7 @@
+#include<stdio.h>
+#include"version.h"
+
+int main(int argc, char **argv) {
+ printf("Version is %s.\n", version_string);
+ return 0;
+}
diff --git a/test cases/common/72 build always/meson.build b/test cases/common/72 build always/meson.build
new file mode 100644
index 0000000..7cb2e4b
--- /dev/null
+++ b/test cases/common/72 build always/meson.build
@@ -0,0 +1,15 @@
+project('run always', 'c')
+
+version = '1.0.0'
+
+vgen = find_program('version_gen.py')
+
+version_src = custom_target('Version string',
+input : 'version.c.in',
+output : 'version.c',
+command : [vgen, '@INPUT@', '@OUTPUT@', version],
+build_always : true,
+)
+
+executable('versionprinter', 'main.c', version_src,
+include_directories : include_directories('.'))
diff --git a/test cases/common/72 build always/version.c.in b/test cases/common/72 build always/version.c.in
new file mode 100644
index 0000000..619e517
--- /dev/null
+++ b/test cases/common/72 build always/version.c.in
@@ -0,0 +1,3 @@
+#include"version.h"
+
+const char *version_string = "@VERSION@";
diff --git a/test cases/common/72 build always/version.h b/test cases/common/72 build always/version.h
new file mode 100644
index 0000000..d3fe5c6
--- /dev/null
+++ b/test cases/common/72 build always/version.h
@@ -0,0 +1,3 @@
+#pragma once
+
+const char *version_string;
diff --git a/test cases/common/72 build always/version_gen.py b/test cases/common/72 build always/version_gen.py
new file mode 100755
index 0000000..4962455
--- /dev/null
+++ b/test cases/common/72 build always/version_gen.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+
+import sys, os, subprocess
+
+def generate(infile, outfile, fallback):
+ workdir = os.path.split(infile)[0]
+ if workdir == '':
+ workdir = '.'
+ p = subprocess.Popen(['git', 'describe'], cwd=workdir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (stdo, _) = p.communicate()
+ # If we are working off an extracted tarball, git version number is not available.
+ if p.returncode == 0:
+ version = stdo.decode().strip()
+ else:
+ version = fallback
+ newdata = open(infile).read().replace('@VERSION@', version)
+ try:
+ olddata = open(outfile).read()
+ if olddata == newdata:
+ return
+ except Exception:
+ pass
+ open(outfile, 'w').write(newdata)
+
+if __name__ == '__main__':
+ infile = sys.argv[1]
+ outfile = sys.argv[2]
+ fallback = sys.argv[3]
+ generate(infile, outfile, fallback)
diff --git a/test cases/common/73 vcstag/meson.build b/test cases/common/73 vcstag/meson.build
new file mode 100644
index 0000000..23ff487
--- /dev/null
+++ b/test cases/common/73 vcstag/meson.build
@@ -0,0 +1,8 @@
+project('vcstag', 'c')
+
+version_src = vcs_tag(input : 'vcstag.c.in',
+output : 'vcstag.c',
+fallback : '1.0.0')
+
+executable('tagprog', 'tagprog.c', version_src)
+
diff --git a/test cases/common/73 vcstag/tagprog.c b/test cases/common/73 vcstag/tagprog.c
new file mode 100644
index 0000000..34146b4
--- /dev/null
+++ b/test cases/common/73 vcstag/tagprog.c
@@ -0,0 +1,9 @@
+#include<stdio.h>
+
+const char *vcstag;
+
+int main(int argc, char **argv) {
+ printf("Version is %s\n", vcstag);
+ return 0;
+}
+
diff --git a/test cases/common/73 vcstag/vcstag.c.in b/test cases/common/73 vcstag/vcstag.c.in
new file mode 100644
index 0000000..09192d9
--- /dev/null
+++ b/test cases/common/73 vcstag/vcstag.c.in
@@ -0,0 +1,2 @@
+const char *vcstag = "@VCS_TAG@";
+
diff --git a/test cases/linuxlike/1 pkg-config/meson.build b/test cases/linuxlike/1 pkg-config/meson.build
index a39e33c..8e8e8f2 100644
--- a/test cases/linuxlike/1 pkg-config/meson.build
+++ b/test cases/linuxlike/1 pkg-config/meson.build
@@ -2,7 +2,7 @@ project('external dependency', 'c')
# Zlib is probably on all dev machines.
-dep = dependency('zlib')
+dep = dependency('zlib', version : '>=1.2.8')
exe = executable('zlibprog', 'prog.c', dependencies : dep)
test('zlibtest', exe)
diff --git a/vcstagger.py b/vcstagger.py
new file mode 100755
index 0000000..f754358
--- /dev/null
+++ b/vcstagger.py
@@ -0,0 +1,62 @@
+#!/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.
+
+import sys, os, subprocess
+
+def tag(infile, outfile, fallback):
+ tagid = get_string(infile, fallback)
+ newdata = open(infile).read().replace('@VCS_TAG@', tagid)
+ try:
+ olddata = open(outfile).read()
+ if olddata == newdata:
+ return
+ except Exception:
+ pass
+ open(outfile, 'w').write(newdata)
+
+def get_string(infile, fallback):
+ absfile = os.path.join(os.getcwd(), infile)
+ directory = os.path.split(absfile)[0]
+ segs = directory.replace('\\', '/').split('/')
+ for i in range(len(segs), -1, -1):
+ curdir = '/'.join(segs[:i])
+ if os.path.isdir(os.path.join(curdir, '.git')):
+ output = subprocess.check_output(['git', 'describe'],
+ cwd = directory)
+ return output.decode().strip()
+ elif os.path.isdir(os.path.join(curdir, '.hg')):
+ output = subprocess.check_output(['hg', 'identify'],
+ cwd=directory)
+ return output.decode().strip()
+ elif os.path.isdir(os.path.join(curdir, '.bzr')):
+ output = subprocess.check_output(['bzr', 'revno'],
+ cwd=directory)
+ return output.decode().strip()
+ elif os.path.isdir(os.path.join(curdir, '.svn')):
+ output = subprocess.check_output(['svn', 'info'],
+ cwd=directory)
+ for line in output.decode().split('\n'):
+ (k, v) = line.split(':', 1)
+ if k.strip() == 'Revision':
+ return v.strip()
+ raise RuntimeError('Svn output malformed.')
+ return fallback
+
+if __name__ == '__main__':
+ infile = sys.argv[1]
+ outfile = sys.argv[2]
+ fallback = sys.argv[3]
+ tag(infile, outfile, fallback)
diff --git a/wrap.py b/wrap.py
index 2c3e087..af2b213 100644
--- a/wrap.py
+++ b/wrap.py
@@ -79,7 +79,7 @@ class Resolver:
(pdata, phash) = self.get_data(purl)
expected = p.get('patch_hash')
if phash != expected:
- raise RuntimeError('Incorrect hash for patch %s:\n %s expected\n %s actual.' % (packagename, expected, phash))
+ raise RuntimeError('Incorrect hash for patch %s:\n %s expected\n %s actual' % (packagename, expected, phash))
open(os.path.join(self.cachedir, p.get('patch_filename')), 'wb').write(pdata)
else:
mlog.log('Package does not require patch.')