Browse Source

Adapting Boost Python library detection to Boost >= 1.67. Closes #4288.

gjaeger1 2 months ago
parent
commit
30e42009c0

+ 1
- 0
ciimage/Dockerfile View File

@@ -23,6 +23,7 @@ RUN sed -i '/^#\sdeb-src /s/^#//' "/etc/apt/sources.list" \
23 23
 && apt-get -y install libgcrypt11-dev \
24 24
 && apt-get -y install libgpgme-dev \
25 25
 && apt-get -y install libhdf5-dev \
26
+&& apt-get -y install libboost-python-dev \
26 27
 && dub fetch urld && dub build urld --compiler=gdc \
27 28
 && dub fetch dubtestproject \
28 29
 && dub build dubtestproject:test1 --compiler=ldc2 \

+ 17
- 12
mesonbuild/dependencies/boost.py View File

@@ -134,22 +134,31 @@ class BoostDependency(ExternalDependency):
134 134
             else:
135 135
                 self.incdir = self.detect_nix_incdir()
136 136
 
137
-        if self.check_invalid_modules():
138
-            return
139
-
140 137
         mlog.debug('Boost library root dir is', mlog.bold(self.boost_root))
141 138
         mlog.debug('Boost include directory is', mlog.bold(self.incdir))
142 139
 
143 140
         # 1. check if we can find BOOST headers.
144 141
         self.detect_headers_and_version()
145 142
 
143
+        if not self.is_found:
144
+            return # if we can not find 'boost/version.hpp'
145
+
146 146
         # 2. check if we can find BOOST libraries.
147
-        if self.is_found:
148
-            self.detect_lib_modules()
149
-            mlog.debug('Boost library directory is', mlog.bold(self.libdir))
147
+        self.detect_lib_modules()
148
+        mlog.debug('Boost library directory is', mlog.bold(self.libdir))
149
+
150
+        mlog.debug('Installed Boost libraries: ')
151
+        for key in sorted(self.lib_modules.keys()):
152
+            mlog.debug(key, self.lib_modules[key])
153
+
154
+        # 3. check if requested modules are valid, that is, either found or in the list of known boost libraries
155
+        self.check_invalid_modules()
156
+
157
+        # 4. final check whether or not we find all requested and valid modules
158
+        self.check_find_requested_modules()
150 159
 
151 160
     def check_invalid_modules(self):
152
-        invalid_modules = [c for c in self.requested_modules if 'boost_' + c not in BOOST_LIBS]
161
+        invalid_modules = [c for c in self.requested_modules if 'boost_' + c not in self.lib_modules and 'boost_' + c not in BOOST_LIBS]
153 162
 
154 163
         # previous versions of meson allowed include dirs as modules
155 164
         remove = []
@@ -273,6 +282,7 @@ class BoostDependency(ExternalDependency):
273 282
             else:
274 283
                 self.detect_lib_modules_nix()
275 284
 
285
+    def check_find_requested_modules(self):
276 286
         # 3. Check if we can find the modules
277 287
         for m in self.requested_modules:
278 288
             if 'boost_' + m not in self.lib_modules:
@@ -491,7 +501,6 @@ class BoostDependency(ExternalDependency):
491 501
     def get_sources(self):
492 502
         return []
493 503
 
494
-
495 504
 # Generated with boost_names.py
496 505
 BOOST_LIBS = [
497 506
     'boost_atomic',
@@ -547,10 +556,6 @@ BOOST_LIBS = [
547 556
     'boost_math_c99l',
548 557
     'boost_mpi',
549 558
     'boost_program_options',
550
-    'boost_python',
551
-    'boost_python3',
552
-    'boost_numpy',
553
-    'boost_numpy3',
554 559
     'boost_random',
555 560
     'boost_regex',
556 561
     'boost_serialization',

+ 53
- 0
test cases/frameworks/1 boost/meson.build View File

@@ -26,18 +26,71 @@ testdep = dependency('boost', modules : ['unit_test_framework'])
26 26
 nomoddep = dependency('boost')
27 27
 extralibdep = dependency('boost', modules : ['thread', 'system', 'log_setup', 'log'])
28 28
 
29
+pymod = import('python')
30
+python2 = pymod.find_installation('python2', required: host_machine.system() == 'linux', disabler: true)
31
+python3 = pymod.find_installation('python3', required: host_machine.system() == 'linux', disabler: true)
32
+python2dep = python2.dependency(required: host_machine.system() == 'linux', disabler: true)
33
+python3dep = python3.dependency(required: host_machine.system() == 'linux', disabler: true)
34
+
35
+# compile python 2/3 modules only if we found a corresponding python version
36
+if(python2dep.found() and host_machine.system() == 'linux')
37
+  if(dep.version().version_compare('>=1.67'))
38
+    # if we have a new version of boost, we need to construct the module name based
39
+    # on the installed version of python (and hope that they match the version boost
40
+    # was compiled against)
41
+    py2version_string = ''.join(python2dep.version().split('.'))
42
+    bpython2dep = dependency('boost', modules : ['python' + py2version_string])
43
+  else
44
+    # if we have an older version of boost, we need to use the old module names
45
+    bpython2dep = dependency('boost', modules : ['python'])
46
+  endif
47
+
48
+  if not (bpython2dep.found())
49
+    bpython2dep = disabler()
50
+  endif
51
+else
52
+  python2dep = disabler()
53
+  bpython2dep = disabler()
54
+endif
55
+
56
+if(python3dep.found() and host_machine.system() == 'linux')
57
+  if(dep.version().version_compare('>=1.67'))
58
+    py3version_string = ''.join(python3dep.version().split('.'))
59
+    bpython3dep = dependency('boost', modules : ['python' + py3version_string])
60
+  else
61
+    bpython3dep = dependency('boost', modules : ['python3'])
62
+  endif
63
+
64
+  if not (bpython3dep.found())
65
+    bpython3dep = disabler()
66
+  endif
67
+else
68
+  python3dep = disabler()
69
+  bpython3dep = disabler()
70
+endif
71
+
29 72
 linkexe = executable('linkedexe', 'linkexe.cc', dependencies : linkdep)
30 73
 staticexe = executable('staticlinkedexe', 'linkexe.cc', dependencies : staticdep)
31 74
 unitexe = executable('utf', 'unit_test.cpp', dependencies: testdep)
32 75
 nomodexe = executable('nomod', 'nomod.cpp', dependencies : nomoddep)
33 76
 extralibexe = executable('extralibexe', 'extralib.cpp', dependencies : extralibdep)
34 77
 
78
+# python modules are shared libraries
79
+python2module = shared_library('python2_module', ['python_module.cpp'], dependencies: [python2dep, bpython2dep], name_prefix: '', cpp_args: ['-DMOD_NAME=python2_module'])
80
+python3module = shared_library('python3_module', ['python_module.cpp'], dependencies: [python3dep, bpython3dep], name_prefix: '', cpp_args: ['-DMOD_NAME=python3_module'])
81
+
35 82
 test('Boost linktest', linkexe)
36 83
 test('Boost statictest', staticexe)
37 84
 test('Boost UTF test', unitexe)
38 85
 test('Boost nomod', nomodexe)
39 86
 test('Boost extralib test', extralibexe)
40 87
 
88
+# explicitly use the correct python interpreter so that we don't have to provide two different python scripts that have different shebang lines
89
+python2interpreter = find_program(python2.path(), required: false, disabler: true)
90
+test('Boost Python2', python2interpreter, args: ['./test_python_module.py', meson.current_build_dir()], workdir: meson.current_source_dir(), depends: python2module)
91
+python3interpreter = find_program(python3.path(), required: false, disabler: true)
92
+test('Boost Python3', python3interpreter, args: ['./test_python_module.py', meson.current_build_dir()], workdir: meson.current_source_dir(), depends: python2module)
93
+
41 94
 subdir('partial_dep')
42 95
 
43 96
 # check we can apply a version constraint

+ 22
- 0
test cases/frameworks/1 boost/python_module.cpp View File

@@ -0,0 +1,22 @@
1
+#define PY_SSIZE_T_CLEAN
2
+#include <Python.h>
3
+#include <boost/python.hpp>
4
+
5
+struct World
6
+{
7
+    void set(std::string msg) { this->msg = msg; }
8
+    std::string greet() { return msg; }
9
+    std::string version() { return std::to_string(PY_MAJOR_VERSION) + "." + std::to_string(PY_MINOR_VERSION); }
10
+    std::string msg;
11
+};
12
+
13
+
14
+BOOST_PYTHON_MODULE(MOD_NAME)
15
+{
16
+    using namespace boost::python;
17
+    class_<World>("World")
18
+        .def("greet", &World::greet)
19
+        .def("set", &World::set)
20
+        .def("version", &World::version)
21
+    ;
22
+}

+ 27
- 0
test cases/frameworks/1 boost/test_python_module.py View File

@@ -0,0 +1,27 @@
1
+import sys
2
+sys.path.append(sys.argv[1])
3
+
4
+# import compiled python module depending on version of python we are running with
5
+if sys.version_info[0] == 2:
6
+    import python2_module
7
+
8
+if sys.version_info[0] == 3:
9
+    import python3_module
10
+
11
+
12
+def run():
13
+    msg = 'howdy'
14
+    if sys.version_info[0] == 2:
15
+        w = python2_module.World()
16
+
17
+    if sys.version_info[0] == 3:
18
+        w = python3_module.World()
19
+
20
+    w.set(msg)
21
+
22
+    assert(msg == w.greet())
23
+    version_string = str(sys.version_info[0]) + "." + str(sys.version_info[1])
24
+    assert(version_string == w.version())
25
+
26
+if __name__ == '__main__':
27
+    run()

Loading…
Cancel
Save