-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathsetup.py
More file actions
137 lines (111 loc) · 4.19 KB
/
setup.py
File metadata and controls
137 lines (111 loc) · 4.19 KB
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# Copyright (c) 2021-2024 J. D. Mitchell + Maria Tsalakou
#
# Distributed under the terms of the GPL license version 3.
#
# The full license is in the file LICENSE, distributed with this software.
# pylint: disable=import-error
"""This package provides a python interface to the C++ library libsemigroups
(libsemigroups.rtfd.io).
"""
import distutils.errors # pylint: disable=deprecated-module
import glob
import os
import platform
import sys
from pathlib import Path
from typing import Any
import pkgconfig
from pybind11.setup_helpers import (
ParallelCompile,
Pybind11Extension,
build_ext,
has_flag,
naive_recompile,
tmp_chdir,
)
from setuptools import setup
ParallelCompile("NPY_NUM_BUILD_JOBS", needs_recompile=naive_recompile).install()
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
from build_tools.packaging_helpers import ( # pylint: disable=wrong-import-position
validate_libsemigroups,
)
validate_libsemigroups()
libsemigroups_info = pkgconfig.parse("libsemigroups")
extra_libs = set(libsemigroups_info["libraries"])
extra_libs.remove("semigroups")
include_dirs = set(libsemigroups_info["include_dirs"])
for lib in extra_libs:
include_dirs.update(set(pkgconfig.parse(lib)["include_dirs"]))
include_dirs = sorted(list(include_dirs))
print("Include directories are:")
print(include_dirs)
print("Library directories args are:")
print(libsemigroups_info["library_dirs"])
def get_arch():
"""Simple function to return the architecture, namely, x86 or not"""
arch = platform.machine().lower()
if arch in {"x86_64", "amd64", "i386", "i686"}:
return "x86"
if arch in {"arm64", "aarch64", "armv7l", "armv6l"}:
return "arm"
return arch
def get_macro_value(compiler: Any, macro: str, include_directories: list[str]) -> bool:
"""Check the value of a libsemigroups C++ preprocessor macro"""
with tmp_chdir():
fname = Path("macro-check.cpp")
file_text = f"""
#include <libsemigroups/config.hpp>
int main () {{
static_assert({macro});
return 0;
}}
"""
fname.write_text(file_text, encoding="utf-8")
try:
compiler.compile([str(fname)], include_dirs=include_directories)
except distutils.errors.CompileError:
return False
return True
class LibsemigroupsBuildExt(build_ext):
# pylint: disable=too-few-public-methods
"""Class conditionally add compile flags"""
def build_extensions(self):
"""Adds compile flags before calling build_extensions in build_ext"""
compiler = self.compiler
hpcombi_enabled = get_macro_value(compiler, "LIBSEMIGROUPS_HPCOMBI_ENABLED", include_dirs)
if hpcombi_enabled:
for flag in ("-flax-vector-conversions", "-mavx"):
if has_flag(compiler, flag):
print(f"Compiler supports '{flag}' flag, adding it to 'extra_compile_args'")
for ext in self.extensions:
ext.extra_compile_args += [flag]
else:
print(
f"Compiler does not support '{flag}' flag, not adding it to "
"'extra_compile_args'"
)
if get_arch() == "arm" and (
any(x.startswith("gcc") for x in compiler.compiler)
or any(x.startswith("g++") for x in compiler.compiler_cxx)
):
print(
"Compiler is gcc, and architecture is arm, adding '-fpermissive' to "
"'extra_compile_args'"
)
for ext in self.extensions:
ext.extra_compile_args += ["-fpermissive"]
for ext in self.extensions:
print(f"'extra_compile_args' for '{ext.name}' are:")
print(ext.extra_compile_args)
super().build_extensions()
ext_modules = [
Pybind11Extension(
"_libsemigroups_pybind11",
glob.glob("src/*.cpp"),
include_dirs=include_dirs,
library_dirs=libsemigroups_info["library_dirs"],
language="c++",
libraries=["semigroups"],
)
]
setup(ext_modules=ext_modules, cmdclass={"build_ext": LibsemigroupsBuildExt})