Skip to content

Commit f95d160

Browse files
committed
TST: add package linking a library from a subproject
Note that for Meson versions older than 1.2.3, CI failed with: ``` mesonpy.BuildError: Could not map installation path to an equivalent wheel directory: '{libdir_static}/libexamplelib.a' ``` because the `--skip-subprojects` install option isn't honored. Hence the test skip on older versions.
1 parent ec42b20 commit f95d160

File tree

10 files changed

+170
-0
lines changed

10 files changed

+170
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-FileCopyrightText: 2024 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
from ._example import example_sum
6+
7+
__all__ = ['example_sum']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// SPDX-FileCopyrightText: 2022 The meson-python developers
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
#include <Python.h>
6+
7+
#include "examplelib.h"
8+
9+
static PyObject* example_sum(PyObject* self, PyObject *args)
10+
{
11+
int a, b;
12+
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
13+
return NULL;
14+
}
15+
16+
long result = sum(a, b);
17+
18+
return PyLong_FromLong(result);
19+
}
20+
21+
static PyMethodDef methods[] = {
22+
{"example_sum", (PyCFunction)example_sum, METH_VARARGS, NULL},
23+
{NULL, NULL, 0, NULL},
24+
};
25+
26+
static struct PyModuleDef module = {
27+
PyModuleDef_HEAD_INIT,
28+
"_example",
29+
NULL,
30+
-1,
31+
methods,
32+
};
33+
34+
PyMODINIT_FUNC PyInit__example(void)
35+
{
36+
return PyModule_Create(&module);
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SPDX-FileCopyrightText: 2022 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
py.extension_module(
6+
'_example',
7+
'_examplemod.c',
8+
dependencies: bar_dep,
9+
install: true,
10+
subdir: 'foo',
11+
install_rpath: '$ORIGIN',
12+
)
13+
14+
py.install_sources(
15+
['__init__.py'],
16+
subdir: 'foo',
17+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SPDX-FileCopyrightText: 2022 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
project(
6+
'link-library-in-subproject',
7+
'c',
8+
version: '1.0.0',
9+
meson_version: '>=1.2.3',
10+
)
11+
12+
py = import('python').find_installation(pure: false)
13+
14+
bar_proj = subproject('bar')
15+
bar_dep = bar_proj.get_variable('bar_dep')
16+
17+
subdir('foo')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SPDX-FileCopyrightText: 2022 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
[build-system]
6+
build-backend = 'mesonpy'
7+
requires = ['meson-python']
8+
9+
[project]
10+
name = 'link-library-in-subproject'
11+
version = '1.2.3'
12+
license = 'MIT'
13+
authors = [{ name = 'The meson-python developers' }]
14+
15+
[tool.meson-python.args]
16+
setup = ['--default-library=static']
17+
install = ['--skip-subprojects']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
// When building the `examplelib` DLL, this macro expands to `__declspec(dllexport)`
4+
// so we can annotate symbols appropriately as being exported. When used in
5+
// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so
6+
// that consumers know the symbol is defined inside the DLL. In all other cases,
7+
// the macro expands to nothing.
8+
// Note: BAR_DLL_{EX,IM}PORTS are set in meson.build
9+
#if defined(BAR_DLL_EXPORTS)
10+
#define BAR_DLL __declspec(dllexport)
11+
#elif defined(BAR_DLL_IMPORTS)
12+
#define BAR_DLL __declspec(dllimport)
13+
#else
14+
#define BAR_DLL
15+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-FileCopyrightText: 2022 The meson-python developers
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
#include "bar_dll.h"
6+
7+
BAR_DLL int sum(int a, int b) {
8+
return a + b;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// SPDX-FileCopyrightText: 2022 The meson-python developers
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
#include "bar_dll.h"
6+
7+
BAR_DLL int sum(int a, int b);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# SPDX-FileCopyrightText: 2022 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
project('bar', 'c', version: '1.2.3')
6+
7+
if meson.get_compiler('c').get_id() in ['msvc', 'clang-cl', 'intel-cl']
8+
export_dll_args = ['-DBAR_DLL_EXPORTS']
9+
import_dll_args = ['-DBAR_DLL_IMPORTS']
10+
else
11+
export_dll_args = []
12+
import_dll_args = []
13+
endif
14+
15+
example_lib = library(
16+
'examplelib',
17+
'examplelib.c',
18+
c_args: export_dll_args,
19+
install: true,
20+
)
21+
22+
# A second library that we don't link from `foo`. If we install the subproject,
23+
# this second library also ends up in the wheel. To prevent that, we need to
24+
# skip installing this `bar` subproject, and statically link `example_lib`.
25+
unwanted_lib = library(
26+
'unwantedlib',
27+
'examplelib.c',
28+
c_args: export_dll_args,
29+
install: true,
30+
)
31+
32+
33+
bar_dep = declare_dependency(
34+
compile_args: import_dll_args,
35+
link_with: example_lib,
36+
include_directories: '.',
37+
)

tests/test_wheel.py

+7
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ def test_sharedlib_in_package(venv, wheel_sharedlib_in_package):
168168
assert int(output) == 7
169169

170170

171+
@pytest.mark.skipif(MESON_VERSION < (1, 2, 3), reason='Meson version too old')
172+
def test_link_library_in_subproject(venv, wheel_link_library_in_subproject):
173+
venv.pip('install', wheel_link_library_in_subproject)
174+
output = venv.python('-c', 'import foo; print(foo.example_sum(3, 6))')
175+
assert int(output) == 9
176+
177+
171178
@pytest.mark.skipif(sys.platform not in {'linux', 'darwin'}, reason='Not supported on this platform')
172179
def test_rpath(wheel_link_against_local_lib, tmp_path):
173180
artifact = wheel.wheelfile.WheelFile(wheel_link_against_local_lib)

0 commit comments

Comments
 (0)