summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-09-16 22:05:48 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2017-12-17 21:17:13 +0200
commit46c071ea5c36b153fdf7d388c580bfa1a26cf226 (patch)
tree9f5000bfcaad81d9bbf0622c9f796e8067132baf
parent202b2fedf300f62b8c1c3b52cd5320845038d85e (diff)
downloadmeson-46c071ea5c36b153fdf7d388c580bfa1a26cf226.tar.gz
Add functionality to promote nested dependencies to top level.
-rw-r--r--docs/markdown/Using-wraptool.md14
-rw-r--r--docs/markdown/snippets/wrap_promote.md11
-rw-r--r--mesonbuild/wrap/wraptool.py50
-rwxr-xr-xrun_unittests.py21
-rw-r--r--test cases/unit/13 promote/meson.build5
-rw-r--r--test cases/unit/13 promote/subprojects/s1/meson.build7
-rw-r--r--test cases/unit/13 promote/subprojects/s1/s1.c6
-rw-r--r--test cases/unit/13 promote/subprojects/s1/subprojects/s3/meson.build4
-rw-r--r--test cases/unit/13 promote/subprojects/s1/subprojects/s3/s3.c3
-rw-r--r--test cases/unit/13 promote/subprojects/s1/subprojects/scommon/meson.build4
-rw-r--r--test cases/unit/13 promote/subprojects/s1/subprojects/scommon/scommon_broken.c1
-rw-r--r--test cases/unit/13 promote/subprojects/s2/meson.build6
-rw-r--r--test cases/unit/13 promote/subprojects/s2/s2.c6
-rw-r--r--test cases/unit/13 promote/subprojects/s2/subprojects/scommon/meson.build4
-rw-r--r--test cases/unit/13 promote/subprojects/s2/subprojects/scommon/scommon_ok.c3
15 files changed, 145 insertions, 0 deletions
diff --git a/docs/markdown/Using-wraptool.md b/docs/markdown/Using-wraptool.md
index 8e5f8985c..1be938b9c 100644
--- a/docs/markdown/Using-wraptool.md
+++ b/docs/markdown/Using-wraptool.md
@@ -57,3 +57,17 @@ In this case `zlib` has a newer release available. Updating it is straightforwar
Updated zlib to branch 1.2.8 revision 4
Wraptool can do other things besides these. Documentation for these can be found in the command line help, which can be accessed by `wraptool --help`.
+
+## Promoting dependencies
+
+Meson will only search for subprojects from the top level `subprojects` directory. If you have subprojects that themselves have subprojects, you must transfer them to the top level. This can be done by going to your source root and issuing a promotion command.
+
+ meson wrap promote projname
+
+This will cause Meson to go through your entire project tree, find an embedded subproject and copy it to the top level.
+
+If there are multiple embedded copies of a subproject, Meson will not try to guess which one you want. Instead it will print all the possibilities. You can then manually select which one to promote by writing it out fully.
+
+ meson wrap promote subprojects/s1/subprojects/projname
+
+This functionality was added in Meson release 0.43.0.
diff --git a/docs/markdown/snippets/wrap_promote.md b/docs/markdown/snippets/wrap_promote.md
new file mode 100644
index 000000000..20fee47d1
--- /dev/null
+++ b/docs/markdown/snippets/wrap_promote.md
@@ -0,0 +1,11 @@
+# Can promote dependencies with wrap command
+
+The `promote` command makes it easy to copy nested dependencies to the top level.
+
+ meson wrap promote scommon
+
+This will search the project tree for a subproject called `scommon` and copy it to the top level.
+
+If there are many embedded subprojects with the same name, you have to specify which one to promote manually like this:
+
+ meson wrap promote subprojects/s1/subprojects/scommon
diff --git a/mesonbuild/wrap/wraptool.py b/mesonbuild/wrap/wraptool.py
index 79b00e0f2..42f0bb683 100644
--- a/mesonbuild/wrap/wraptool.py
+++ b/mesonbuild/wrap/wraptool.py
@@ -142,6 +142,51 @@ def info(name):
for v in versions:
print(' ', v['branch'], v['revision'])
+def do_promotion(from_path, spdir_name):
+ sproj_name = os.path.split(from_path)[1]
+ outputdir = os.path.join(spdir_name, sproj_name)
+ if os.path.exists(outputdir):
+ sys.exit('Output dir %s already exists. Will not overwrite.' % outputdir)
+ shutil.copytree(from_path, outputdir, ignore=shutil.ignore_patterns('subprojects'))
+
+def detect_subprojects(spdir_name, current_dir='', result=None):
+ if result is None:
+ result = {}
+ spdir = os.path.join(current_dir, spdir_name)
+ if not os.path.exists(spdir):
+ return result
+ for trial in glob(os.path.join(spdir, '*')):
+ basename = os.path.split(trial)[1]
+ if trial == 'packagecache':
+ continue
+ if not os.path.isdir(trial):
+ continue
+ if basename in result:
+ result[basename].append(trial)
+ else:
+ result[basename] = [trial]
+ detect_subprojects(spdir_name, trial, result)
+ return result
+
+def promote(argument):
+ path_segment, subproject_name = os.path.split(argument)
+ spdir_name = 'subprojects'
+ sprojs = detect_subprojects(spdir_name)
+ if subproject_name not in sprojs:
+ sys.exit('Subproject %s not found in directory tree.' % subproject_name)
+ matches = sprojs[subproject_name]
+ if len(matches) == 1:
+ do_promotion(matches[0], spdir_name)
+ return
+ if path_segment == '':
+ print('There are many versions of %s in tree. Please specify which one to promote:\n' % subproject_name)
+ for s in matches:
+ print(s)
+ sys.exit(1)
+ system_native_path_argument = argument.replace('/', os.sep)
+ if system_native_path_argument in matches:
+ do_promotion(argument, spdir_name)
+
def status():
print('Subproject status')
for w in glob('subprojects/*.wrap'):
@@ -189,6 +234,11 @@ def run(args):
print('info requires exactly one argument.')
return 1
info(args[0])
+ elif command == 'promote':
+ if len(args) != 1:
+ print('promote requires exactly one argument.')
+ return 1
+ promote(args[0])
elif command == 'status':
status()
else:
diff --git a/run_unittests.py b/run_unittests.py
index d7d5ed08f..f742624f1 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -468,6 +468,7 @@ class BasePlatformTests(unittest.TestCase):
self.mconf_command = meson_command + ['configure']
self.mintro_command = meson_command + ['introspect']
self.mtest_command = meson_command + ['test', '-C', self.builddir]
+ self.wrap_command = meson_command + ['wrap']
# Backend-specific build commands
self.build_command, self.clean_command, self.test_command, self.install_command, \
self.uninstall_command = get_backend_commands(self.backend)
@@ -1643,6 +1644,26 @@ int main(int argc, char **argv) {
self.setconf("-Dfree_array_opt=['a,b', 'c,d']", will_build=False)
self.opt_has('free_array_opt', ['a,b', 'c,d'])
+ def test_subproject_promotion(self):
+ testdir = os.path.join(self.unit_test_dir, '13 promote')
+ workdir = os.path.join(self.builddir, 'work')
+ shutil.copytree(testdir, workdir)
+ spdir = os.path.join(workdir, 'subprojects')
+ s3dir = os.path.join(spdir, 's3')
+ scommondir = os.path.join(spdir, 'scommon')
+ self.assertFalse(os.path.isdir(s3dir))
+ subprocess.check_call(self.wrap_command + ['promote', 's3'], cwd=workdir)
+ self.assertTrue(os.path.isdir(s3dir))
+ self.assertFalse(os.path.isdir(scommondir))
+ self.assertNotEqual(subprocess.call(self.wrap_command + ['promote', 'scommon'],
+ cwd=workdir,
+ stdout=subprocess.DEVNULL), 0)
+ self.assertFalse(os.path.isdir(scommondir))
+ subprocess.check_call(self.wrap_command + ['promote', 'subprojects/s2/subprojects/scommon'], cwd=workdir)
+ self.assertTrue(os.path.isdir(scommondir))
+ self.init(workdir)
+ self.build()
+
class FailureTests(BasePlatformTests):
'''
diff --git a/test cases/unit/13 promote/meson.build b/test cases/unit/13 promote/meson.build
new file mode 100644
index 000000000..066cf36cf
--- /dev/null
+++ b/test cases/unit/13 promote/meson.build
@@ -0,0 +1,5 @@
+project('promotion test', 'c')
+
+subproject('s1')
+subproject('s2')
+
diff --git a/test cases/unit/13 promote/subprojects/s1/meson.build b/test cases/unit/13 promote/subprojects/s1/meson.build
new file mode 100644
index 000000000..88c467bf4
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s1/meson.build
@@ -0,0 +1,7 @@
+project('s1', 'c')
+
+sc = subproject('scommon')
+s3 = subproject('s3')
+
+executable('s1', 's1.c',
+ link_with : [sc.get_variable('clib'), s3.get_variable('l')])
diff --git a/test cases/unit/13 promote/subprojects/s1/s1.c b/test cases/unit/13 promote/subprojects/s1/s1.c
new file mode 100644
index 000000000..7d1d775c1
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s1/s1.c
@@ -0,0 +1,6 @@
+int func();
+int func2();
+
+int main(int argc, char **argv) {
+ return func() + func2();
+}
diff --git a/test cases/unit/13 promote/subprojects/s1/subprojects/s3/meson.build b/test cases/unit/13 promote/subprojects/s1/subprojects/s3/meson.build
new file mode 100644
index 000000000..894fe265b
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s1/subprojects/s3/meson.build
@@ -0,0 +1,4 @@
+project('s3', 'c')
+
+l = static_library('s3', 's3.c')
+
diff --git a/test cases/unit/13 promote/subprojects/s1/subprojects/s3/s3.c b/test cases/unit/13 promote/subprojects/s1/subprojects/s3/s3.c
new file mode 100644
index 000000000..0166603e5
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s1/subprojects/s3/s3.c
@@ -0,0 +1,3 @@
+int func2() {
+ return -42;
+}
diff --git a/test cases/unit/13 promote/subprojects/s1/subprojects/scommon/meson.build b/test cases/unit/13 promote/subprojects/s1/subprojects/scommon/meson.build
new file mode 100644
index 000000000..231f2757b
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s1/subprojects/scommon/meson.build
@@ -0,0 +1,4 @@
+project('scommon', 'c')
+
+clib = static_library('scommon', 'scommon_broken.c')
+
diff --git a/test cases/unit/13 promote/subprojects/s1/subprojects/scommon/scommon_broken.c b/test cases/unit/13 promote/subprojects/s1/subprojects/scommon/scommon_broken.c
new file mode 100644
index 000000000..3665a9cbc
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s1/subprojects/scommon/scommon_broken.c
@@ -0,0 +1 @@
+#error This file must not be used. The other scommon one should be instead.
diff --git a/test cases/unit/13 promote/subprojects/s2/meson.build b/test cases/unit/13 promote/subprojects/s2/meson.build
new file mode 100644
index 000000000..32bcf8f39
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s2/meson.build
@@ -0,0 +1,6 @@
+project('s2', 'c')
+
+sc = subproject('scommon')
+
+executable('s2', 's2.c', link_with : sc.get_variable('clib'))
+
diff --git a/test cases/unit/13 promote/subprojects/s2/s2.c b/test cases/unit/13 promote/subprojects/s2/s2.c
new file mode 100644
index 000000000..2a6d1e63d
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s2/s2.c
@@ -0,0 +1,6 @@
+int func();
+
+
+int main(int argc, char **argv) {
+ return func() != 42;
+}
diff --git a/test cases/unit/13 promote/subprojects/s2/subprojects/scommon/meson.build b/test cases/unit/13 promote/subprojects/s2/subprojects/scommon/meson.build
new file mode 100644
index 000000000..e0d8c7ddc
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s2/subprojects/scommon/meson.build
@@ -0,0 +1,4 @@
+project('scommon', 'c')
+
+clib = static_library('scommon', 'scommon_ok.c')
+
diff --git a/test cases/unit/13 promote/subprojects/s2/subprojects/scommon/scommon_ok.c b/test cases/unit/13 promote/subprojects/s2/subprojects/scommon/scommon_ok.c
new file mode 100644
index 000000000..652f4eb13
--- /dev/null
+++ b/test cases/unit/13 promote/subprojects/s2/subprojects/scommon/scommon_ok.c
@@ -0,0 +1,3 @@
+int func() {
+ return 42;
+}