aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interpreter.py8
-rw-r--r--manual tests/1 basic/main.c12
-rw-r--r--manual tests/1 basic/meson.build11
-rw-r--r--manual tests/1 basic/subprojects/sqlite.wrap10
-rw-r--r--wrap.py92
5 files changed, 132 insertions, 1 deletions
diff --git a/interpreter.py b/interpreter.py
index 6c4f07e..33dbbef 100644
--- a/interpreter.py
+++ b/interpreter.py
@@ -19,6 +19,7 @@ import dependencies
import mlog
import build
import optinterpreter
+import wrap
import os, sys, platform, subprocess, shutil, uuid
class InterpreterException(coredata.MesonException):
@@ -915,7 +916,12 @@ class Interpreter():
subdir = os.path.join('subprojects', dirname)
abs_subdir = os.path.join(self.build.environment.get_source_dir(), subdir)
if not os.path.isdir(abs_subdir):
- raise InterpreterException('Subproject directory does not exist.')
+ r = wrap.Resolver(os.path.join(self.build.environment.get_source_dir(), 'subprojects'))
+ resolved = r.resolve(dirname)
+ if resolved is None:
+ 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)
self.global_args_frozen = True
mlog.log('\nExecuting subproject ', mlog.bold(dirname), '.\n', sep='')
subi = Interpreter(self.build, dirname, subdir)
diff --git a/manual tests/1 basic/main.c b/manual tests/1 basic/main.c
new file mode 100644
index 0000000..39d3a9a
--- /dev/null
+++ b/manual tests/1 basic/main.c
@@ -0,0 +1,12 @@
+#include<sqlite3.h>
+#include<stdio.h>
+
+int main(int argc, char **argv) {
+ sqlite3 *db;
+ if(sqlite3_open(":memory:", &db) != SQLITE_OK) {
+ printf("Sqlite failed.\n");
+ return 1;
+ }
+ sqlite3_close(db);
+ return 0;
+}
diff --git a/manual tests/1 basic/meson.build b/manual tests/1 basic/meson.build
new file mode 100644
index 0000000..afdda34
--- /dev/null
+++ b/manual tests/1 basic/meson.build
@@ -0,0 +1,11 @@
+project('downloader', 'c')
+
+s = subproject('sqlite')
+
+e = executable('dtest', 'main.c',
+include_directories : s.get_variable('sqinc'),
+link_args : ['-pthread', '-ldl'],
+c_args : '-pthread',
+link_with : s.get_variable('sqlib'))
+
+test('dltest', e)
diff --git a/manual tests/1 basic/subprojects/sqlite.wrap b/manual tests/1 basic/subprojects/sqlite.wrap
new file mode 100644
index 0000000..879a170
--- /dev/null
+++ b/manual tests/1 basic/subprojects/sqlite.wrap
@@ -0,0 +1,10 @@
+[mesonwrap]
+directory = sqlite-amalgamation-3080802
+
+source_url = http://sqlite.com/2015/sqlite-amalgamation-3080802.zip
+source_filename = sqlite-amalgamation-3080802.zip
+source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663
+
+patch_url = https://dl.dropboxusercontent.com/u/37517477/sqlite-meson.tar.gz
+patch_filename = sqlite-meson.tar.gz
+patch_hash = 8c9d00702d5fe4a6bf25a36b821a332f6b2dfd117c66fe818b88b23d604635e9
diff --git a/wrap.py b/wrap.py
new file mode 100644
index 0000000..4402cba
--- /dev/null
+++ b/wrap.py
@@ -0,0 +1,92 @@
+# 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 mlog
+import glob, urllib.request, os, hashlib, shutil
+
+class PackageDefinition:
+ def __init__(self, fname):
+ self.values = {}
+ ifile = open(fname)
+ first = ifile.readline().strip()
+ if first != '[mesonwrap]':
+ raise RuntimeError('Invalid format of package file')
+ for line in ifile:
+ line = line.strip()
+ if line == '':
+ continue
+ (k, v) = line.split('=', 1)
+ k = k.strip()
+ v = v.strip()
+ self.values[k] = v
+
+ def get(self, key):
+ return self.values[key]
+
+ def has_patch(self):
+ return 'patch_url' in self.values
+
+class Resolver:
+ def __init__(self, subdir_root):
+ self.subdir_root = subdir_root
+ self.cachedir = os.path.join(self.subdir_root, 'packagecache')
+
+ def resolve(self, packagename):
+ fname = os.path.join(self.subdir_root, packagename + '.wrap')
+ if not os.path.isfile(fname):
+ return None
+ p = PackageDefinition(fname)
+ self.download(p, packagename)
+ self.extract_package(p)
+ return p.get('directory')
+
+ def get_data(self, url):
+ u = urllib.request.urlopen(url)
+ data = u.read()
+ u.close()
+ h = hashlib.sha256()
+ h.update(data)
+ hashvalue = h.hexdigest()
+ return (data, hashvalue)
+
+ def download(self, p, packagename):
+ ofname = os.path.join(self.cachedir, p.get('source_filename'))
+ if os.path.exists(ofname):
+ print('Using', packagename, 'from cache.')
+ return
+ srcurl = p.get('source_url')
+ print('Dowloading', packagename, 'from', srcurl)
+ (srcdata, dhash) = self.get_data(srcurl)
+ expected = p.get('source_hash')
+ if dhash != expected:
+ raise RuntimeError('Incorrect hash for source %s:\n %s expected\n %s actual.' % (packagename, expected, dhash))
+ if p.has_patch():
+ purl = p.get('patch_url')
+ print('Downloading patch from', purl)
+ (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))
+ open(os.path.join(self.cachedir, p.get('patch_filename')), 'wb').write(pdata)
+ else:
+ print('Package does not require patch.')
+ open(ofname, 'wb').write(srcdata)
+
+ def extract_package(self, package):
+ if os.path.isdir(os.path.join(self.subdir_root, package.get('directory'))):
+ return
+ print(os.path.join(self.cachedir, package.get('source_filename')))
+ shutil.unpack_archive(os.path.join(self.cachedir, package.get('source_filename')), self.subdir_root)
+ if package.has_patch():
+ shutil.unpack_archive(os.path.join(self.cachedir, package.get('patch_filename')), self.subdir_root)