-
Notifications
You must be signed in to change notification settings - Fork 0
/
build_tanker.py
105 lines (85 loc) · 3.07 KB
/
build_tanker.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import json
import os
import sys
from pathlib import Path
from typing import Iterator, List
from cffi import FFI
tanker_ext = FFI()
def get_lib_name(name: str) -> str:
if sys.platform == "win32":
return name + ".lib"
else:
return "lib" + name + ".a"
def find_libs(names: List[str], paths: List[str]) -> Iterator[str]:
for name in names:
for lib_path in paths:
lib_name = get_lib_name(name)
candidate = Path(lib_path) / lib_name
if candidate.exists():
yield str(candidate)
def on_import() -> None:
path_from_env = os.environ.get("TANKER_PYTHON_SDK_SRC")
if path_from_env:
this_path = Path(path_from_env)
else:
this_path = Path(__file__).parent.resolve()
conan_out_path = this_path / "conan" / "out"
build_info = None
dirs = (d for d in conan_out_path.iterdir() if d.is_dir())
for d in dirs:
conan_info = d / "conanbuildinfo.json"
if conan_info.exists():
build_info = conan_info
break
if not build_info or not build_info.exists():
sys.exit(
"conanbuildinfo.json not found - cannot configure compilation with tanker/native",
)
assert build_info
conaninfo = json.loads(build_info.read_text())
libs: List[str] = []
for dep_info in conaninfo["dependencies"]:
libs_for_dep = dep_info["libs"]
lib_paths = dep_info["lib_paths"]
libs.extend(find_libs(libs_for_dep, lib_paths))
all_deps = conaninfo["dependencies"]
tanker_packages = [x for x in all_deps if x["name"] == "tanker"]
n = len(tanker_packages)
assert n == 1, "expecting one package named 'tanker', got %i" % n
tanker_package = tanker_packages[0]
includes = tanker_package["include_paths"]
tanker_cffi_source = (this_path / "cffi_src.c").read_text()
if sys.platform == "win32":
system_libs = ["crypt32"]
symbols_file = "exported_symbols.def"
exported_symbols_flags = ["/DEF:%s" % (this_path / symbols_file)]
elif sys.platform == "linux":
system_libs = ["dl", "pthread", "stdc++"]
symbols_file = "exported_symbols.ld"
exported_symbols_flags = [
"-Wl,--version-script=%s" % (this_path / symbols_file)
]
system_libs = ["dl", "pthread", "stdc++"]
else:
symbols_file = "exported_symbols.sym"
exported_symbols_flags = [
"-exported_symbols_list",
"%s" % (this_path / symbols_file),
]
# macOS system libs + compiler flags are already in the env
# thanks to the virtualenv generated by conan in setup.py
system_libs: List[str] = []
tanker_ext.set_source(
"_tanker",
tanker_cffi_source,
libraries=system_libs,
extra_objects=libs,
include_dirs=includes,
language="c",
extra_link_args=exported_symbols_flags,
)
tanker_cffi_defs = (this_path / "cffi_defs.h").read_text()
tanker_ext.cdef(tanker_cffi_defs)
on_import()
if __name__ == "__main__":
tanker_ext.compile(verbose=True)