aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-01-09 16:36:00 -0500
committerGitHub <noreply@github.com>2017-01-09 16:36:00 -0500
commit34caf6471c0fad8823ce145d3d38afb81ee181ba (patch)
tree17d4a5db37d2df3c3748ec767701f74882fa912e
parent9cf0991a1d332cb1f492376bf718aa75020519e4 (diff)
parent6ac9a8e738dae97c64308da83949931fb726bbe7 (diff)
downloadmeson-34caf6471c0fad8823ce145d3d38afb81ee181ba.zip
meson-34caf6471c0fad8823ce145d3d38afb81ee181ba.tar.gz
meson-34caf6471c0fad8823ce145d3d38afb81ee181ba.tar.bz2
Merge pull request #787 from mesonbuild/py3module
Created a Python 3 module for simpler building of Python extension mo…
-rw-r--r--mesonbuild/environment.py8
-rw-r--r--mesonbuild/interpreter.py53
-rw-r--r--mesonbuild/modules/__init__.py7
-rw-r--r--mesonbuild/modules/gnome.py3
-rw-r--r--mesonbuild/modules/i18n.py9
-rw-r--r--mesonbuild/modules/modtest.py3
-rw-r--r--mesonbuild/modules/pkgconfig.py6
-rw-r--r--mesonbuild/modules/python3.py49
-rw-r--r--mesonbuild/modules/qt4.py3
-rw-r--r--mesonbuild/modules/qt5.py3
-rw-r--r--mesonbuild/modules/rpm.py3
-rw-r--r--mesonbuild/modules/windows.py7
-rw-r--r--test cases/python3/1 basic/meson.build3
-rw-r--r--test cases/python3/1 basic/subdir/meson.build5
-rw-r--r--test cases/python3/2 extmodule/ext/meson.build15
-rw-r--r--test cases/python3/2 extmodule/meson.build5
-rw-r--r--test cases/python3/3 cython/libdir/meson.build14
-rw-r--r--test cases/python3/3 cython/meson.build6
18 files changed, 140 insertions, 62 deletions
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index e4a55b3..64d9f8b 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -899,3 +899,11 @@ class CrossBuildInfo():
self.config['host_machine']['system'] == detect_system():
return False
return True
+
+
+class MachineInfo:
+ def __init__(self, system, cpu_family, cpu, endian):
+ self.system = system
+ self.cpu_family = cpu_family
+ self.cpu = cpu
+ self.endian = endian
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 382c04c..c736cd0 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -355,6 +355,10 @@ class BuildMachine(InterpreterObject):
def __init__(self, compilers):
self.compilers = compilers
InterpreterObject.__init__(self)
+ self.held_object = environment.MachineInfo(environment.detect_system(),
+ environment.detect_cpu_family(self.compilers),
+ environment.detect_cpu(self.compilers),
+ sys.byteorder)
self.methods.update({'system': self.system_method,
'cpu_family': self.cpu_family_method,
'cpu': self.cpu_method,
@@ -362,16 +366,16 @@ class BuildMachine(InterpreterObject):
})
def cpu_family_method(self, args, kwargs):
- return environment.detect_cpu_family(self.compilers)
+ return self.held_object.cpu_family
def cpu_method(self, args, kwargs):
- return environment.detect_cpu(self.compilers)
+ return self.held_object.cpu
def system_method(self, args, kwargs):
- return environment.detect_system()
+ return self.held_object.system
def endian_method(self, args, kwargs):
- return sys.byteorder
+ return self.held_object.endian
# This class will provide both host_machine and
# target_machine
@@ -384,23 +388,27 @@ class CrossMachineInfo(InterpreterObject):
'Machine info is currently {}\n'.format(cross_info) +
'but is missing {}.'.format(minimum_cross_info - set(cross_info)))
self.info = cross_info
+ self.held_object = environment.MachineInfo(cross_info['system'],
+ cross_info['cpu_family'],
+ cross_info['cpu'],
+ cross_info['endian'])
self.methods.update({'system': self.system_method,
'cpu': self.cpu_method,
'cpu_family': self.cpu_family_method,
'endian': self.endian_method,
})
- def system_method(self, args, kwargs):
- return self.info['system']
+ def cpu_family_method(self, args, kwargs):
+ return self.held_object.cpu_family
def cpu_method(self, args, kwargs):
- return self.info['cpu']
+ return self.held_object.cpu
- def cpu_family_method(self, args, kwargs):
- return self.info['cpu_family']
+ def system_method(self, args, kwargs):
+ return self.held_object.system
def endian_method(self, args, kwargs):
- return self.info['endian']
+ return self.held_object.endian
class IncludeDirsHolder(InterpreterObject):
def __init__(self, idobj):
@@ -1000,10 +1008,17 @@ class ModuleHolder(InterpreterObject):
state.man = self.interpreter.build.get_man()
state.global_args = self.interpreter.build.global_args
state.project_args = self.interpreter.build.projects_args.get(self.interpreter.subproject, {})
- value = fn(state, args, kwargs)
- if num_targets != len(self.interpreter.build.targets):
- raise InterpreterException('Extension module altered internal state illegally.')
- return self.interpreter.module_method_callback(value)
+ state.build_machine = self.interpreter.builtin['build_machine'].held_object
+ state.host_machine = self.interpreter.builtin['host_machine'].held_object
+ state.target_machine = self.interpreter.builtin['target_machine'].held_object
+ if self.held_object.is_snippet(method_name):
+ value = fn(self.interpreter, state, args, kwargs)
+ return self.interpreter.holderify(value)
+ else:
+ value = fn(state, args, kwargs)
+ if num_targets != len(self.interpreter.build.targets):
+ raise InterpreterException('Extension module altered internal state illegally.')
+ return self.interpreter.module_method_callback(value)
class MesonMain(InterpreterObject):
def __init__(self, build, interpreter):
@@ -1261,8 +1276,11 @@ class Interpreter(InterpreterBase):
return DataHolder(item)
elif isinstance(item, dependencies.InternalDependency):
return InternalDependencyHolder(item)
+ elif isinstance(item, dependencies.ExternalProgram):
+ return ExternalProgramHolder(item)
+ elif hasattr(item, 'held_object'):
+ return item
else:
- print(item)
raise InterpreterException('Module returned a value of unknown type.')
def process_new_values(self, invalues):
@@ -1279,16 +1297,19 @@ class Interpreter(InterpreterBase):
self.build.install_scripts.append(v)
elif isinstance(v, build.Data):
self.build.data.append(v)
+ elif isinstance(v, dependencies.ExternalProgram):
+ return ExternalProgramHolder(v)
elif isinstance(v, dependencies.InternalDependency):
# FIXME: This is special cased and not ideal:
# The first source is our new VapiTarget, the rest are deps
self.process_new_values(v.sources[0])
+ elif hasattr(v, 'held_object'):
+ pass
else:
raise InterpreterException('Module returned a value of unknown type.')
def module_method_callback(self, return_object):
if not isinstance(return_object, ModuleReturnValue):
- print(return_object)
assert(False)
raise InterpreterException('Bug in module, it returned an invalid object')
invalues = return_object.new_objects
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index 16cada0..c7f24d4 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -6,6 +6,13 @@ from ..mesonlib import MesonException
_found_programs = {}
+class ExtensionModule:
+ def __init__(self):
+ self.snippets = set() # List of methods that operate only on the interpreter.
+
+ def is_snippet(self, funcname):
+ return funcname in self.snippets
+
def find_program(program_name, target_name):
if program_name in _found_programs:
return _found_programs[program_name]
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index ad34640..47fa68e 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -29,6 +29,7 @@ from .. import compilers
from .. import interpreter
from . import GResourceTarget, GResourceHeaderTarget, GirTarget, TypelibTarget, VapiTarget
from . import find_program, get_include_args
+from . import ExtensionModule
# gresource compilation is broken due to the way
@@ -57,7 +58,7 @@ def gir_has_extra_lib_arg():
pass
return _gir_has_extra_lib_arg
-class GnomeModule:
+class GnomeModule(ExtensionModule):
gir_dep = None
@staticmethod
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
index fa52463..5738cb3 100644
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -12,13 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import sys
+import shutil
+
from os import path
from .. import coredata, mesonlib, build
from ..mesonlib import MesonException
from . import ModuleReturnValue
-
-import sys
-import shutil
+from . import ExtensionModule
PRESET_ARGS = {
'glib': [
@@ -46,7 +47,7 @@ PRESET_ARGS = {
]
}
-class I18nModule:
+class I18nModule(ExtensionModule):
def merge_file(self, state, args, kwargs):
podir = kwargs.pop('po_dir', None)
diff --git a/mesonbuild/modules/modtest.py b/mesonbuild/modules/modtest.py
index dc347e2..3e11b70 100644
--- a/mesonbuild/modules/modtest.py
+++ b/mesonbuild/modules/modtest.py
@@ -13,8 +13,9 @@
# limitations under the License.
from . import ModuleReturnValue
+from . import ExtensionModule
-class TestModule:
+class TestModule(ExtensionModule):
def print_hello(self, state, args, kwargs):
print('Hello from a Meson module')
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 38358f3..c558d48 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -12,14 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import os
+
from .. import build
from .. import mesonlib
from .. import mlog
from . import ModuleReturnValue
+from . import ExtensionModule
-import os
-class PkgConfigModule:
+class PkgConfigModule(ExtensionModule):
def _get_lname(self, l, msg, pcfile):
# Nothing special
diff --git a/mesonbuild/modules/python3.py b/mesonbuild/modules/python3.py
new file mode 100644
index 0000000..53e28c4
--- /dev/null
+++ b/mesonbuild/modules/python3.py
@@ -0,0 +1,49 @@
+# Copyright 2016-2017 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
+from .. import mesonlib, dependencies
+
+from . import ExtensionModule
+from mesonbuild.modules import ModuleReturnValue
+
+class Python3Module(ExtensionModule):
+ def __init__(self):
+ super().__init__()
+ self.snippets.add('extension_module')
+
+ def extension_module(self, interpreter, state, args, kwargs):
+ if 'name_prefix' in kwargs:
+ raise mesonlib.MesonException('Name_prefix is set automatically, specifying it is forbidden.')
+ if 'name_suffix' in kwargs:
+ raise mesonlib.MesonException('Name_suffix is set automatically, specifying it is forbidden.')
+ host_system = state.host_machine.system
+ if host_system == 'darwin':
+ # Default suffix is 'dylib' but Python does not use it for extensions.
+ suffix = 'so'
+ elif host_system == 'windows':
+ # On Windows the extension is pyd for some unexplainable reason.
+ suffix = 'pyd'
+ else:
+ suffix = []
+ kwargs['name_prefix'] = ''
+ kwargs['name_suffix'] = suffix
+ return interpreter.func_shared_module(None, args, kwargs)
+
+ def find_python(self, state, args, kwargs):
+ py3 = dependencies.ExternalProgram('python3', sys.executable, silent=True)
+ return ModuleReturnValue(py3, [py3])
+
+def initialize():
+ return Python3Module()
diff --git a/mesonbuild/modules/qt4.py b/mesonbuild/modules/qt4.py
index 6759270..9a9ec04 100644
--- a/mesonbuild/modules/qt4.py
+++ b/mesonbuild/modules/qt4.py
@@ -17,10 +17,11 @@ from .. import mlog
from .. import build
from ..mesonlib import MesonException, Popen_safe
from ..dependencies import Qt4Dependency
+from . import ExtensionModule
import xml.etree.ElementTree as ET
from . import ModuleReturnValue
-class Qt4Module():
+class Qt4Module(ExtensionModule):
tools_detected = False
def _detect_tools(self, env):
diff --git a/mesonbuild/modules/qt5.py b/mesonbuild/modules/qt5.py
index 53f1cb5..cb5c261 100644
--- a/mesonbuild/modules/qt5.py
+++ b/mesonbuild/modules/qt5.py
@@ -17,10 +17,11 @@ from .. import mlog
from .. import build
from ..mesonlib import MesonException, Popen_safe
from ..dependencies import Qt5Dependency
+from . import ExtensionModule
import xml.etree.ElementTree as ET
from . import ModuleReturnValue
-class Qt5Module():
+class Qt5Module(ExtensionModule):
tools_detected = False
def _detect_tools(self, env):
diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py
index a696db9..bd8a3c4 100644
--- a/mesonbuild/modules/rpm.py
+++ b/mesonbuild/modules/rpm.py
@@ -21,10 +21,11 @@ import datetime
from .. import mlog
from . import GirTarget, TypelibTarget
from . import ModuleReturnValue
+from . import ExtensionModule
import os
-class RPMModule:
+class RPMModule(ExtensionModule):
def generate_spec_template(self, state, args, kwargs):
compiler_deps = set()
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index 8574dbe..8203789 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -12,14 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import os
+
from .. import mesonlib, dependencies, build
from ..mesonlib import MesonException
from . import get_include_args
from . import ModuleReturnValue
+from . import ExtensionModule
-import os
-
-class WindowsModule:
+class WindowsModule(ExtensionModule):
def detect_compiler(self, compilers):
for l in ('c', 'cpp'):
diff --git a/test cases/python3/1 basic/meson.build b/test cases/python3/1 basic/meson.build
index badd3e5..9d5f874 100644
--- a/test cases/python3/1 basic/meson.build
+++ b/test cases/python3/1 basic/meson.build
@@ -1,6 +1,7 @@
project('python sample', 'c')
-py3 = find_program('python3')
+py3_mod = import('python3')
+py3 = py3_mod.find_python()
main = files('prog.py')
diff --git a/test cases/python3/1 basic/subdir/meson.build b/test cases/python3/1 basic/subdir/meson.build
index 3f275ad..8fe91b9 100644
--- a/test cases/python3/1 basic/subdir/meson.build
+++ b/test cases/python3/1 basic/subdir/meson.build
@@ -1,5 +1,4 @@
-submain = find_program('subprog.py')
-
test('subdir',
- submain,
+ py3,
+ args : files('subprog.py'),
env : 'PYTHONPATH=' + meson.source_root())
diff --git a/test cases/python3/2 extmodule/ext/meson.build b/test cases/python3/2 extmodule/ext/meson.build
index 7d67953..d5d8849 100644
--- a/test cases/python3/2 extmodule/ext/meson.build
+++ b/test cases/python3/2 extmodule/ext/meson.build
@@ -1,17 +1,6 @@
-if host_machine.system() == 'darwin'
- # Default suffix is 'dylib' but Python does not use for extensions.
- suffix = 'so'
-elif host_machine.system() == 'windows'
- # On Windows the extension is pyd for some unexplainable reason.
- suffix = 'pyd'
-else
- suffix = []
-endif
-
-pylib = shared_library('tachyon',
+pylib = py3_mod.extension_module('tachyon',
'tachyon_module.c',
dependencies : py3_dep,
- name_prefix : '',
- name_suffix : suffix)
+)
pypathdir = meson.current_build_dir()
diff --git a/test cases/python3/2 extmodule/meson.build b/test cases/python3/2 extmodule/meson.build
index 92a12b2..25e2c63 100644
--- a/test cases/python3/2 extmodule/meson.build
+++ b/test cases/python3/2 extmodule/meson.build
@@ -3,13 +3,16 @@ project('Python extension module', 'c',
# Because Windows Python ships only with optimized libs,
# we must build this project the same way.
+py3_mod = import('python3')
+py3 = py3_mod.find_python()
py3_dep = dependency('python3', required : false)
if py3_dep.found()
subdir('ext')
test('extmod',
- find_program('blaster.py'),
+ py3,
+ args : files('blaster.py'),
env : ['PYTHONPATH=' + pypathdir])
else
error('MESON_SKIP_TEST: Python3 libraries not found, skipping test.')
diff --git a/test cases/python3/3 cython/libdir/meson.build b/test cases/python3/3 cython/libdir/meson.build
index 5c0352e..7823a6b 100644
--- a/test cases/python3/3 cython/libdir/meson.build
+++ b/test cases/python3/3 cython/libdir/meson.build
@@ -1,23 +1,11 @@
-if host_machine.system() == 'darwin'
- # Default suffix is 'dylib' but Python does not use for extensions.
- suffix = 'so'
-elif host_machine.system() == 'windows'
- # On Windows the extension is pyd for some unexplainable reason.
- suffix = 'pyd'
-else
- suffix = []
-endif
-
pyx_c = custom_target('storer_pyx',
output : 'storer_pyx.c',
input : 'storer.pyx',
command : [cython, '@INPUT@', '-o', '@OUTPUT@'],
)
-slib = shared_library('storer',
+slib = py3_mod.extension_module('storer',
'storer.c', pyx_c,
- name_prefix : '',
- name_suffix : suffix,
dependencies : py3_dep)
pydir = meson.current_build_dir()
diff --git a/test cases/python3/3 cython/meson.build b/test cases/python3/3 cython/meson.build
index 22bbf7a..753b906 100644
--- a/test cases/python3/3 cython/meson.build
+++ b/test cases/python3/3 cython/meson.build
@@ -5,10 +5,14 @@ cython = find_program('cython3', required : false)
py3_dep = dependency('python3', required : false)
if cython.found() and py3_dep.found()
+ py3_dep = dependency('python3')
+ py3_mod = import('python3')
+ py3 = py3_mod.find_python()
subdir('libdir')
test('cython tester',
- find_program('cytest.py'),
+ py3,
+ args : files('cytest.py'),
env : ['PYTHONPATH=' + pydir]
)
else