Skip to content

Commit

Permalink
Add a second shared library in another directory
Browse files Browse the repository at this point in the history
  • Loading branch information
rgommers committed Oct 29, 2024
1 parent c4ef660 commit e4b9839
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 14 deletions.
34 changes: 23 additions & 11 deletions tests/packages/sharedlib-in-package/mypkg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@


def _enable_sharedlib_loading():
"""Ensure the `examplelib` shared library on Windows can be loaded
"""
Ensure the `examplelib` and `examplelib2` shared libraries can be loaded on
Windows.
One shared library is installed alongside this __init__.py file. Windows can
load it because it searches for DLLs in the directory a .pyd (Python extension
module) is located in. Cygwin does not. For a shared library in another
directory inside the package, Windows also needs a hint.
This function is Windows-specific due to lack of RPATH support on Windows.
It cannot find shared libraries installed within wheels unless we either
amend the DLL search path or pre-load the DLL.
This shared library is installed alongside this __init__.py file. Due to
lack of RPATH support, Windows cannot find shared libraries installed
within wheels unless we either amend the DLL search path or pre-load the
DLL.
Note that `delvewheel` inserts a similar snippet into the main
`__init__.py` of a package when it vendors external shared libraries.
.. note::
Expand All @@ -22,15 +31,18 @@ def _enable_sharedlib_loading():
with `ctypes.WinDLL` may be preferred (the SciPy code base has an
example of this).
"""
if os.name == "NOnt":
basedir = os.path.dirname(__file__)
os.add_dll_directory(basedir)
basedir = os.path.dirname(__file__)
subdir = os.path.join(basedir, 'sub')
if os.name == "nt":
os.add_dll_directory(subdir)
elif sys.platform == "cygwin":
basedir = os.path.dirname(__file__)
os.environ["PATH"] = f"{os.environ['PATH']:s}:{basedir:s}"
os.environ["PATH"] = f"{os.environ['PATH']}:{basedir}:{subdir}"


_enable_sharedlib_loading()


from ._example import example_sum
from ._example import example_prod, example_sum


__all__ = ['example_prod', 'example_sum']
14 changes: 14 additions & 0 deletions tests/packages/sharedlib-in-package/mypkg/_examplemod.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <Python.h>

#include "examplelib.h"
#include "examplelib2.h"

static PyObject* example_sum(PyObject* self, PyObject *args)
{
Expand All @@ -18,7 +19,20 @@ static PyObject* example_sum(PyObject* self, PyObject *args)
return PyLong_FromLong(result);
}

static PyObject* example_prod(PyObject* self, PyObject *args)
{
int a, b;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}

long result = prod(a, b);

return PyLong_FromLong(result);
}

static PyMethodDef methods[] = {
{"example_prod", (PyCFunction)example_prod, METH_VARARGS, NULL},
{"example_sum", (PyCFunction)example_sum, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL},
};
Expand Down
2 changes: 1 addition & 1 deletion tests/packages/sharedlib-in-package/mypkg/examplelib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: MIT

#include "mypkg_dll.h"
#include "sub/mypkg_dll.h"

MYPKG_DLL int sum(int a, int b) {
return a + b;
Expand Down
2 changes: 1 addition & 1 deletion tests/packages/sharedlib-in-package/mypkg/examplelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
//
// SPDX-License-Identifier: MIT

#include "mypkg_dll.h"
#include "sub/mypkg_dll.h"

MYPKG_DLL int sum(int a, int b);
5 changes: 4 additions & 1 deletion tests/packages/sharedlib-in-package/mypkg/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ example_lib_dep = declare_dependency(
link_with: example_lib,
)

subdir('sub')

py.extension_module(
'_example',
'_examplemod.c',
dependencies: example_lib_dep,
dependencies: [example_lib_dep, example_lib2_dep],
include_directories: 'sub',
install: true,
subdir: 'mypkg',
install_rpath: '$ORIGIN',
Expand Down
9 changes: 9 additions & 0 deletions tests/packages/sharedlib-in-package/mypkg/sub/examplelib2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2022 The meson-python developers
//
// SPDX-License-Identifier: MIT

#include "mypkg_dll.h"

MYPKG_DLL int prod(int a, int b) {
return a * b;
}
7 changes: 7 additions & 0 deletions tests/packages/sharedlib-in-package/mypkg/sub/examplelib2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2022 The meson-python developers
//
// SPDX-License-Identifier: MIT

#include "mypkg_dll.h"

MYPKG_DLL int prod(int a, int b);
16 changes: 16 additions & 0 deletions tests/packages/sharedlib-in-package/mypkg/sub/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2022 The meson-python developers
#
# SPDX-License-Identifier: MIT

example_lib2 = shared_library(
'examplelib2',
'examplelib2.c',
c_args: export_dll_args,
install: true,
install_dir: py.get_install_dir() / 'mypkg/sub',
)

example_lib2_dep = declare_dependency(
compile_args: import_dll_args,
link_with: example_lib2,
)
2 changes: 2 additions & 0 deletions tests/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ def test_sharedlib_in_package(venv, wheel_sharedlib_in_package):
venv.pip('install', wheel_sharedlib_in_package)
output = venv.python('-c', 'import mypkg; print(mypkg.example_sum(2, 5))')
assert int(output) == 7
output = venv.python('-c', 'import mypkg; print(mypkg.example_prod(6, 7))')
assert int(output) == 42


@pytest.mark.skipif(MESON_VERSION < (1, 2, 3), reason='Meson version too old')
Expand Down

0 comments on commit e4b9839

Please sign in to comment.