-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsetup_cpp.py
84 lines (78 loc) · 3.18 KB
/
setup_cpp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# This file is part of the pattern-clustering project.
# https://github.com/nokia/pattern-clustering
__author__ = "Marc-Olivier Buob"
__maintainer__ = "Marc-Olivier Buob"
__email__ = "marc-olivier.buob@nokia-bell-labs.com"
__copyright__ = "Copyright (C) 2022, Nokia"
__license__ = "BSD-3"
import os
import sys
def find(dir_name :str = ".", extension :str = "") -> iter:
"""
Creates an iterator over files stored in a given directory and
matching an extension.
Args:
dir_name: The directory to process.
extension: The extension of files of interest. Pass "" if not relevant.
Returns:
The corresponding iterator.
"""
return (
os.path.join(root, f)
for (root, dirs, files) in os.walk(dir_name)
for f in files
if f.endswith(extension)
)
def find_cpp_sources(
use_pyplusplus :bool = False,
sources_ext :str = "cpp",
headers_ext :str = "hpp",
sources_dir :str = "src",
headers_dir :str = "src"
) -> list:
"""
Find sources required to produce a python package involving C++ code.
Args:
use_pyplusplus: Pass `True` if the binding required by python to wrap
the C++ code must be automatically generated using Py++. If so,
the `binding_auto.cpp` file is automatically and generated to this end.
Otherwise, we assume that the bindings are manually declared in
`binding.cpp`.
sources_ext: The extension used for C++ sources files.
headers_ext: The extension used for C++ headers files.
sources_dir: The directory containing the C++ sources. It may involves
subdirectories.
headers_dir: The directory containing the C++ headers. It may involves
subdirectories.
Returns:
The list of relevant C++ files.
"""
if use_pyplusplus:
# Py++ can automatically generate python bindings under some limitations:
# - it supports well std:: streams (like `std::cout`) and `std::string`;
# - it does not automatically wrap `std::`containers (like `std::vector`);
# - it does not support well parameters typed by a `std::container`;
# - it does not handle well references (for instance, do not return a reference);
# - the read property of `std::vector` is the only one automatically supported.
# See https://pyplusplus.readthedocs.io/en/latest/tutorials/containers/indexing_suite_v2.html.html
try:
from pyplusplus import make_bindings_auto
filename_bindings_auto = os.path.join(sources_dir, "bindings_auto.cpp")
make_bindings_auto(headers_dir, headers_ext, filename_bindings_auto)
# Ignore bindings manually written
exclude = "bindings.cpp"
except ImportError:
raise RuntimeError("Py++ is not installed.", sys.stderr)
else:
# Ignore bindings generated by py++
# The developer must manually write/complete bindings.cpp
exclude = "bindings_auto.cpp"
sources = [
f
for f in find(sources_dir, sources_ext)
if f != os.path.join(sources_dir, exclude)
]
return sources