-
Notifications
You must be signed in to change notification settings - Fork 1k
/
Copy pathcmake_gen.py
127 lines (100 loc) · 3.3 KB
/
cmake_gen.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env python3
from pathlib import Path
SOURCEFILE_EXTS = (
".c",
".cpp",
".S",
)
def get_default_config():
return dict(
sources=set(),
includedirs=set(),
extra_libs=set(),
target="",
objlib=True,
ldflags="",
precompiled="false",
binaries=dict(),
)
def parse_configfile(file: Path):
rawcfg = dict()
for line in open(file):
line = line.strip()
if not line:
continue
if line.startswith("#"):
continue
key, value = line.split("=", 1)
key = key
value = value
rawcfg[key.strip()] = value.strip()
cfg = dict()
cfg["objlib"] = False if rawcfg.get("dot_a_linkage") == "true" else True
cfg["ldflags"] = rawcfg.get("ldflags", "")
cfg["precompiled"] = rawcfg.get("precompiled", "false")
return cfg
def get_sources(dir: Path, recursive: bool = False, relative_to: Path = None):
if relative_to is None:
relative_to = dir
if recursive:
walker = type(dir).rglob
else:
walker = type(dir).glob
return {
str(file.relative_to(relative_to)).replace("\\", "/")
for file in walker(dir, "*")
if file.is_file() and file.suffix in SOURCEFILE_EXTS
}
def render(dir: Path, template, config):
with open(dir / "CMakeLists.txt", "w") as outfile:
outfile.write(template.render(**config))
def get_static_libs(dir: Path):
result = dict()
cpu = ""
fpconf = "-" # format: f"{fpu}-{float_abi}"; this makes "-" by default
for file in dir.glob("src/*/lib*.a"):
if not file.is_file():
continue
cpu = file.parent.name
result.setdefault(cpu + fpconf, list()).append(file.relative_to(dir))
for file in dir.glob("src/*/*/lib*.a"):
if not file.is_file():
continue
fpconf = file.parent.name
cpu = file.parent.parent.name
result.setdefault(cpu + fpconf, list()).append(file.relative_to(dir))
return result
def config_for_bareflat(dir: Path, force_recurse: bool = False):
# no library.properties
config = get_default_config()
config["target"] = dir.name
config["sources"].update(get_sources(dir, recursive=force_recurse))
config["includedirs"].add(dir.relative_to(dir))
utils = dir / "utility"
if utils.exists() and utils.is_dir():
config["sources"].update(
get_sources(utils, relative_to=dir, recursive=force_recurse)
)
config["includedirs"].add(utils.relative_to(dir))
return config
def config_for_modern(dir: Path):
# library.properties present, src/ present
config = get_default_config()
config.update(parse_configfile(dir / "library.properties"))
config["target"] = dir.name
config["sources"].update(get_sources(dir / "src", recursive=True, relative_to=dir))
config["includedirs"].add((dir / "src").relative_to(dir))
config["binaries"].update(get_static_libs(dir))
return config
def autoconfig(libdir: Path):
conf_file = libdir / "library.properties"
srcdir = libdir / "src"
if (
conf_file.exists()
and conf_file.is_file()
and srcdir.exists()
and srcdir.is_dir()
):
return config_for_modern(libdir)
else:
return config_for_bareflat(libdir)