-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.py
More file actions
84 lines (67 loc) · 2.53 KB
/
Copy pathsetup.py
File metadata and controls
84 lines (67 loc) · 2.53 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
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2020-2026, Christian Gaser. See LICENSE.
"""
Build the exact TFCE max-tree as a Python extension.
The C core is shared with the MATLAB toolbox and lives at the repository root.
There is exactly one implementation of TFCE in this repository and both bindings
sit on it -- but a source distribution cannot reach outside its own directory, so
the core is *vendored* into src/tfce/_c/ at build time.
That gives two cases, and both work:
* building from the git checkout -- the core is copied down from the repository
root, so an edit to the C is picked up by the next build with nothing to
remember;
* building from an sdist -- there is no repository root, and the copy already
made when the sdist was created is used as it stands.
src/tfce/_c/ is therefore generated, and is git-ignored.
"""
import os
import shutil
import numpy as np
from setuptools import Extension, setup
from Cython.Build import cythonize
HERE = os.path.dirname(os.path.abspath(__file__))
CORE = os.path.abspath(os.path.join(HERE, os.pardir, "c"))
VENDOR = os.path.join("src", "tfce", "_c")
CORE_FILES = [
"tfce_capi.c",
"tfce_capi.h",
"tfce_maxtree.h",
"tfce_batch.h",
"tfce_threads.h",
]
def vendor_core():
"""Copy the C core into the package, so the sdist is self-contained."""
dest = os.path.join(HERE, VENDOR)
os.makedirs(dest, exist_ok=True)
for name in CORE_FILES:
src = os.path.join(CORE, name)
dst = os.path.join(dest, name)
if os.path.exists(src):
# a git checkout: ../c is the source of truth, always
shutil.copyfile(src, dst)
elif not os.path.exists(dst):
raise RuntimeError(
f"{name} is neither in {CORE} nor vendored in {VENDOR}. "
f"A source distribution should carry it; a checkout should have "
f"it in the c/ folder beside python/."
)
vendor_core()
extra_compile_args = ["-O3"]
extra_link_args = []
if os.name == "nt":
extra_compile_args = ["/O2"]
else:
extra_compile_args += ["-std=c99", "-pthread"]
extra_link_args += ["-pthread"]
ext = Extension(
"tfce._maxtree",
sources=[
os.path.join("src", "tfce", "_maxtree.pyx"),
os.path.join(VENDOR, "tfce_capi.c"),
],
include_dirs=[np.get_include(), VENDOR],
extra_compile_args=extra_compile_args,
extra_link_args=extra_link_args,
define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
)
setup(ext_modules=cythonize([ext], language_level=3))