forked from JuliaLang/julia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
normalize_triplet.py
executable file
·138 lines (123 loc) · 3.74 KB
/
normalize_triplet.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
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python
import re, sys
# This script designed to mimick `src/PlatformNames.jl` in `BinaryProvider.jl`, which has
# a method `platform_key_abi()` to parse uname-like output into something standarized.
if len(sys.argv) < 2:
print("Usage: {} <host triplet> [<gcc version>] [<cxxabi11>]".format(sys.argv[0]))
sys.exit(1)
arch_mapping = {
'x86_64': '(x86_|amd)64',
'i686': "i\\d86",
'aarch64': "aarch64",
'arm': "arm(v7l)?",
'powerpc64le': "p(ower)?pc64le",
}
platform_mapping = {
'darwin': "-apple-darwin[\\d\\.]*",
'freebsd': "-(.*-)?freebsd[\\d\\.]*",
'windows': "-w64-mingw32",
'linux': "-(.*-)?linux",
}
libc_mapping = {
'blank_libc': "",
'gnu': "-gnu",
'musl': "-musl",
}
call_abi_mapping = {
'blank_call_abi': "",
'eabihf': "eabihf",
}
gcc_version_mapping = {
'blank_gcc': "",
'gcc4': "-gcc4",
'gcc7': "-gcc7",
'gcc8': "-gcc8",
'gcc9': "-gcc8",
}
cxx_abi_mapping = {
'blank_cxx_abi': "",
'cxx03': "-cxx03",
'cxx11': "-cxx11",
}
# Helper function to collapse dictionary of mappings down into a regex of
# named capture groups joined by "|" operators
c = lambda mapping: "("+"|".join(["(?P<%s>%s)"%(k,v) for (k, v) in mapping.items()]) + ")"
mondo_regex = re.compile(
"^"+
c(arch_mapping)+
c(platform_mapping)+
c(libc_mapping)+
c(call_abi_mapping)+
c(gcc_version_mapping)+
c(cxx_abi_mapping)+
"$"
)
# Apply our mondo regex to our input:
m = mondo_regex.match(sys.argv[1])
if m is None:
print("ERROR: Unmatchable platform string '%s'!"%(sys.argv[1]))
sys.exit(1)
# Helper function to find the single named field within the giant regex
# that is not `nothing` for each mapping we give it.
def get_field(m, mapping):
g = m.groupdict()
for k in mapping:
if g[k] is not None:
return k
arch = get_field(m, arch_mapping)
platform = get_field(m, platform_mapping)
libc = get_field(m, libc_mapping)
call_abi = get_field(m, call_abi_mapping)
gcc_version = get_field(m, gcc_version_mapping)
cxx_abi = get_field(m, cxx_abi_mapping)
# The default libc on Linux is glibc
if platform == "linux" and libc == "blank_libc":
libc = "gnu"
def r(x):
x = x.replace("blank_call_abi", "")
x = x.replace("blank_gcc", "")
x = x.replace("blank_cxx_abi", "")
x = x.replace("blank_libc", "")
return x
def p(x):
# These contain characters that can't be easily represented as
# capture group names, unfortunately:
os_remapping = {
'darwin': 'apple-darwin14',
'windows': 'w64-mingw32',
'freebsd': 'unknown-freebsd11.1',
}
x = r(x)
if x:
for k in os_remapping:
x = x.replace(k, os_remapping[k])
return '-' + x
return x
# If the user passes in a GCC version (like 8.2.0) use that to force a
# "-gcc8" tag at the end of the triplet, but only if it has otherwise
# not been specified
if gcc_version == "blank_gcc":
if len(sys.argv) >= 3:
gcc_version = {
"4": "gcc4",
"5": "gcc4",
"6": "gcc4",
"7": "gcc7",
"8": "gcc8",
"9": "gcc8",
}[list(filter(lambda x: re.match("\d+\.\d+(\.\d+)?", x), sys.argv[2].split()))[-1][0]]
if cxx_abi == "blank_cxx_abi":
if len(sys.argv) == 4:
cxx_abi = {
"0": "cxx03",
"1": "cxx11",
"": "",
}[sys.argv[3]]
print(arch+p(platform)+p(libc)+r(call_abi)+p(gcc_version)+p(cxx_abi))
# Testing suite:
# triplets="i686-w64-mingw32 x86_64-pc-linux-musl arm-linux-musleabihf x86_64-linux-gnu arm-linux-gnueabihf x86_64-apple-darwin14 x86_64-unknown-freebsd11.1"
# for t in $triplets; do
# if [[ $(./normalize_triplet.py "$t") != "$t" ]]; then
# echo "ERROR: Failed test on $t"
# fi
# done