Changeset View
Changeset View
Standalone View
Standalone View
bin/compiler.py
1 | # -*- coding: utf-8 -*- | 1 | # -*- coding: utf-8 -*- | ||
---|---|---|---|---|---|
2 | # this package contains functions to check the current compiler | 2 | # this package contains functions to check the current compiler | ||
3 | # copyright: | 3 | # copyright: | ||
4 | # Hannah von Reth <vonreth@kde.org> | 4 | # Hannah von Reth <vonreth@kde.org> | ||
5 | 5 | | |||
6 | import os | 6 | import os | ||
7 | import subprocess | 7 | import subprocess | ||
8 | import re | 8 | import re | ||
9 | 9 | | |||
10 | from CraftDebug import craftDebug | 10 | from CraftDebug import craftDebug, deprecated | ||
11 | import utils | 11 | import utils | ||
12 | from CraftConfig import * | 12 | from CraftConfig import * | ||
13 | 13 | | |||
14 | 14 | | |||
15 | class Compiler(object): | ||||
16 | __supportedPlatforms = ["windows", "linux", "macos", "freebsd"] | ||||
17 | | ||||
18 | def __init__(self): | ||||
19 | compiler = craftSettings.get("General","KDECOMPILER", "") | ||||
20 | if compiler != "": | ||||
21 | arch = "32" if craftSettings.get("General", "Architecture") == "x86" else "64" | ||||
22 | if compiler.startswith("msvc"): | ||||
23 | split = ["windows", f"{compiler}_{arch}" , "cl"] | ||||
24 | elif compiler.startswith("mingw"): | ||||
25 | split = ["windows", f"mingw_{arch}", "gcc"] | ||||
26 | if not craftSettings.getboolean("ContinuousIntegration", "Enabled", False): | ||||
27 | print(f"Your using the old compiler setting\n" | ||||
28 | f"\t[General]\n" | ||||
29 | f"\tKDECOMPILER={compiler}\n" | ||||
30 | f"please update your settings to\n" | ||||
31 | f"\t[General]\n" | ||||
32 | f"\tABI=" + "-".join(split), | ||||
33 | file=sys.stderr) | ||||
34 | else: | ||||
35 | split = craftSettings.get("General","ABI").split("-") | ||||
36 | if len(split) != 3: | ||||
37 | raise Exception("Invalid compiler: " + craftSettings.get("General","ABI")) | ||||
38 | | ||||
39 | self._platform, self._abi, self._compiler = split | ||||
40 | | ||||
41 | self._architecture = "x86" if self._abi.endswith("32") else "x64" | ||||
42 | | ||||
43 | if not self._platform in Compiler.__supportedPlatforms: | ||||
44 | raise Exception("Unsupported platform: " + self._platform) | ||||
45 | | ||||
46 | def __str__(self): | ||||
47 | return f"{self.platform}-{self.abi}-{self.compiler}" | ||||
48 | | ||||
49 | @property | ||||
50 | def platform(self): | ||||
51 | return self._platform | ||||
52 | | ||||
53 | @property | ||||
54 | def abi(self): | ||||
55 | return self._abi | ||||
56 | | ||||
57 | @property | ||||
58 | def compiler(self): | ||||
59 | return self._compiler | ||||
60 | | ||||
61 | @property | ||||
62 | def architecture(self): | ||||
63 | return self._architecture | ||||
64 | | ||||
65 | def _getGCCTarget(self): | ||||
66 | result = utils.utilsCache.getCommandOutput("gcc", "-dumpmachine") | ||||
67 | if result: | ||||
68 | result = result.strip() | ||||
69 | craftDebug.log.debug(f"GCC Target Processor: {result}") | ||||
70 | else: | ||||
71 | # if no mingw is installed return mingw-w32 it is part of base | ||||
72 | if self.isX64(): | ||||
73 | result = "x86_64-w64-mingw32" | ||||
74 | else: | ||||
75 | result = "i686-w64-mingw32" | ||||
76 | return result | ||||
77 | | ||||
78 | def isNative(self): | ||||
79 | # TODO: any reason to keep that? | ||||
80 | return craftSettings.getboolean("General", "Native", True) | ||||
81 | | ||||
82 | def isX64(self): | ||||
83 | return self.architecture == "x64" | ||||
84 | | ||||
85 | def isX86(self): | ||||
86 | return self.architecture == "x86" | ||||
87 | | ||||
88 | def isGCC(self): | ||||
89 | return self.compiler == "gcc" | ||||
90 | | ||||
91 | def isClang(self): | ||||
92 | return self.compiler == "clang" | ||||
15 | 93 | | |||
94 | def isGCCLike(self): | ||||
95 | return self.isGCC() or self.isClang() | ||||
16 | 96 | | |||
17 | def _getGCCTarget(): | 97 | def isCl(self): | ||
18 | result = utils.utilsCache.getCommandOutput("gcc", "-dumpmachine") | 98 | return self.compiler == "cl" | ||
19 | if result: | 99 | | ||
20 | result = result.strip() | 100 | def isMinGW(self): | ||
21 | craftDebug.log.debug(f"GCC Target Processor: {result}") | 101 | return self.abi == "mingw" | ||
22 | else: | 102 | | ||
23 | #if no mingw is installed return mingw-w32 it is part of base | 103 | def isMinGW_W32(self): | ||
24 | if isX64(): | 104 | return self.isMinGW() and self.isX86() | ||
25 | result = "x86_64-w64-mingw32" | 105 | | ||
106 | def isMinGW_W64(self): | ||||
107 | return self.isMinGW() and self.isX64() | ||||
108 | | ||||
109 | def isMSVC(self): | ||||
110 | return self.abi.startswith("msvc") | ||||
111 | | ||||
112 | def isMSVC2010(self): | ||||
113 | return self.abi == "msvc10" | ||||
114 | | ||||
115 | def isMSVC2012(self): | ||||
116 | return self.abi == "msvc12" | ||||
117 | | ||||
118 | def isMSVC2013(self): | ||||
119 | return self.abi == "msvc13" | ||||
120 | | ||||
121 | def isMSVC2015(self): | ||||
122 | return self.abi == "msvc15" | ||||
123 | | ||||
124 | def isMSVC2017(self): | ||||
125 | return self.abi == " msvc17" | ||||
126 | | ||||
127 | def isIntel(self): | ||||
128 | return self.compiler == "intel" | ||||
129 | | ||||
130 | @deprecated("self.compiler") | ||||
131 | def getCompilerExecutableName(self): | ||||
132 | return self.compiler | ||||
133 | | ||||
134 | @deprecated("craftCompiler") | ||||
135 | def getCompilerName(self): | ||||
136 | return str(craftCompiler) | ||||
137 | | ||||
138 | @deprecated("craftCompiler") | ||||
139 | def getSimpleCompilerName(self): | ||||
140 | return str(craftCompiler) | ||||
141 | | ||||
142 | def getGCCLikeVersion(self, compilerExecutable): | ||||
143 | result = utils.utilsCache.getCommandOutput(compilerExecutable, "--version") | ||||
144 | if result: | ||||
145 | result = re.findall("\d+\.\d+\.?\d*", result)[0] | ||||
146 | craftDebug.log.debug("{0} Version: {1}".format(compilerExecutable, result)) | ||||
147 | return result or "0" | ||||
148 | | ||||
149 | def getVersion(self): | ||||
150 | if self.isGCCLike(): | ||||
151 | return self.getGCCLikeVersion(self.getCompilerExecutableName()) | ||||
152 | elif self.isMSVC(): | ||||
153 | return self.internalVerison() | ||||
154 | else: | ||||
155 | return None | ||||
156 | | ||||
157 | def getVersionWithName(self): | ||||
158 | if self.isGCCLike(): | ||||
159 | return f"{self.getCompilerName()} {self.getVersion()}" | ||||
160 | elif self.isIntel(): | ||||
161 | return os.getenv("PRODUCT_NAME_FULL") | ||||
162 | elif self.isMSVC(): | ||||
163 | return f"Microsoft Visual Studio {self.getVersion()}" | ||||
26 | else: | 164 | else: | ||
27 | result = "i686-w64-mingw32" | 165 | return None | ||
28 | return result | 166 | | ||
29 | 167 | def getShortName(self): | |||
30 | def architecture(): | 168 | if not self.isMSVC(): | ||
31 | return craftSettings.get("General", "Architecture" ) | 169 | return self.getCompilerName() | ||
32 | 170 | return f"vc{self.internalVerison()}" | |||
33 | def isNative(): | 171 | | ||
34 | return craftSettings.getboolean("General", "Native", True) | 172 | def internalVerison(self): | ||
35 | 173 | if not self.isMSVC(): | |||
36 | def isX64(): | 174 | return self.getVersion() | ||
37 | return architecture() == "x64" | 175 | versions = { | ||
38 | 176 | "msvc2010": 10, | |||
39 | def isX86(): | 177 | "msvc2012": 11, | ||
40 | return architecture() == "x86" | 178 | "msvc2013": 12, | ||
41 | 179 | "msvc2015": 14, | |||
42 | 180 | "msvc2017": 15 | |||
43 | def _compiler(): | 181 | } | ||
44 | return craftSettings.get("General","KDECOMPILER") | 182 | c = self.abi.split("_")[0] | ||
45 | 183 | if c not in versions: | |||
46 | def isGCC(): | 184 | craftDebug.log.critical(f"Unknown MSVC Compiler {self.abi}") | ||
47 | return isMinGW() or _compiler().endswith("-gcc") | 185 | return versions[c] | ||
48 | 186 | | |||
49 | def isClang(): | 187 | def msvcPlatformToolset(self): | ||
50 | return _compiler().endswith("-clang") | 188 | versions = { | ||
51 | 189 | "msvc2010": 100, | |||
52 | def isGCCLike(): | 190 | "msvc2012": 110, | ||
53 | return (isGCC() or isClang()) | 191 | "msvc2013": 120, | ||
54 | 192 | "msvc2015": 140, | |||
55 | def isMinGW(): | 193 | "msvc2017": 141 | ||
56 | return _compiler().startswith("mingw") | 194 | } | ||
57 | 195 | c = self.abi.split("_")[0] | |||
58 | def isMinGW_W32(): | 196 | if c not in versions: | ||
59 | return isMinGW() and _getGCCTarget() == "i686-w64-mingw32" | 197 | craftDebug.log.critical(f"Unknown MSVC Compiler {self.abi}") | ||
60 | 198 | return versions[c] | |||
61 | def isMinGW_W64(): | 199 | | ||
62 | return isMinGW() and isX64() | 200 | craftCompiler = Compiler() | ||
63 | | ||||
64 | def isMSVC(): | | |||
65 | return _compiler().startswith("msvc") | | |||
66 | | ||||
67 | def isMSVC2010(): | | |||
68 | return _compiler().startswith("msvc2010") | | |||
69 | | ||||
70 | def isMSVC2012(): | | |||
71 | return _compiler().startswith("msvc2012") | | |||
72 | | ||||
73 | def isMSVC2013(): | | |||
74 | return _compiler().startswith("msvc2013") | | |||
75 | | ||||
76 | def isMSVC2015(): | | |||
77 | return _compiler().startswith("msvc2015") | | |||
78 | | ||||
79 | def isMSVC2017(): | | |||
80 | return _compiler().startswith("msvc2017") | | |||
81 | | ||||
82 | def isIntel(): | | |||
83 | return _compiler() == "intel" | | |||
84 | | ||||
85 | def getCompilerExecutableName(): | | |||
86 | if isGCC(): | | |||
87 | return "gcc" | | |||
88 | elif isClang(): | | |||
89 | return "clang" | | |||
90 | elif isMSVC(): | | |||
91 | return "cl" | | |||
92 | else: | | |||
93 | craftDebug.log.critical(f"Unsupported Compiler {_compiler()}") | | |||
94 | | ||||
95 | def getCompilerName(): | | |||
96 | if isMinGW(): | | |||
97 | return "mingw-w64" | | |||
98 | elif isMSVC(): | | |||
99 | return _compiler() | | |||
100 | elif isIntel(): | | |||
101 | return "intel-%s-%s" % (os.getenv("TARGET_ARCH"), os.getenv("TARGET_VS")) | | |||
102 | elif isGCC(): | | |||
103 | return "gcc" | | |||
104 | elif isClang(): | | |||
105 | return "clang" | | |||
106 | else: | | |||
107 | craftDebug.log.critical("Unknown Compiler %s" % _compiler()) | | |||
108 | | ||||
109 | def getSimpleCompilerName(): | | |||
110 | if isMinGW(): | | |||
111 | return "mingw64" | | |||
112 | elif isMSVC(): | | |||
113 | return "msvc" | | |||
114 | elif isIntel(): | | |||
115 | return "intel" | | |||
116 | else: | | |||
117 | return getCompilerName() | | |||
118 | | ||||
119 | def getGCCLikeVersion(compilerExecutable): | | |||
120 | result = utils.utilsCache.getCommandOutput(compilerExecutable, "--version") | | |||
121 | if result: | | |||
122 | result = re.findall("\d+\.\d+\.?\d*",result)[0] | | |||
123 | craftDebug.log.debug("{0} Version: {1}".format(compilerExecutable, result)) | | |||
124 | return result or "0" | | |||
125 | | ||||
126 | def getVersion(): | | |||
127 | if isGCCLike(): | | |||
128 | return getGCCLikeVersion(getCompilerExecutableName()) | | |||
129 | elif isMSVC(): | | |||
130 | return "20{0}".format(_compiler()[len(_compiler())-2:]) | | |||
131 | else: | | |||
132 | return None | | |||
133 | | ||||
134 | def getVersionWithName(): | | |||
135 | if isGCCLike(): | | |||
136 | return f"{getCompilerName()} {getVersion()}" | | |||
137 | elif isIntel(): | | |||
138 | return os.getenv("PRODUCT_NAME_FULL") | | |||
139 | elif isMSVC(): | | |||
140 | return f"Microsoft Visual Studio {getVersion()}" | | |||
141 | else: | | |||
142 | return None | | |||
143 | | ||||
144 | def getShortName(): | | |||
145 | if not isMSVC(): | | |||
146 | return getCompilerName() | | |||
147 | return f"vc{internalVerison()}" | | |||
148 | | ||||
149 | | ||||
150 | def internalVerison(): | | |||
151 | if not isMSVC(): | | |||
152 | return getVersion() | | |||
153 | versions = { | | |||
154 | "msvc2010": 10, | | |||
155 | "msvc2012": 11, | | |||
156 | "msvc2013": 12, | | |||
157 | "msvc2015": 14, | | |||
158 | "msvc2017": 15 | | |||
159 | } | | |||
160 | c = _compiler().split("-", 1)[0] | | |||
161 | if c not in versions: | | |||
162 | craftDebug.log.critical(f"Unknown MSVC Compiler {c}") | | |||
163 | return versions[c] | | |||
164 | | ||||
165 | | ||||
166 | def msvcPlatformToolset(): | | |||
167 | versions = { | | |||
168 | "msvc2010": 100, | | |||
169 | "msvc2012": 110, | | |||
170 | "msvc2013": 120, | | |||
171 | "msvc2015": 140, | | |||
172 | "msvc2017": 141 | | |||
173 | } | | |||
174 | c = _compiler().split("-", 1)[0] | | |||
175 | if c not in versions: | | |||
176 | craftDebug.log.critical(f"Unknown MSVC Compiler {c}") | | |||
177 | return versions[c] | | |||
178 | 201 | | |||
179 | if __name__ == '__main__': | 202 | if __name__ == '__main__': | ||
180 | print("Testing Compiler.py") | 203 | print("Testing Compiler.py") | ||
181 | print("Configured compiler (KDECOMPILER): %s" % _compiler()) | 204 | print(f"Configured compiler (ABI): {craftCompiler}") | ||
182 | print("Version: %s" % getVersionWithName()) | 205 | print("Version: %s" % craftCompiler.getVersionWithName()) | ||
183 | print("Compiler Name: %s" % getCompilerName()) | 206 | print("Compiler Name: %s" % craftCompiler.getCompilerName()) | ||
184 | print("Native compiler: %s" % ("No", "Yes")[isNative()]) | 207 | print("Native compiler: %s" % ("No", "Yes")[craftCompiler.isNative()]) | ||
185 | if isGCCLike(): | 208 | if craftCompiler.isGCCLike(): | ||
186 | print("Compiler Version: %s" % getGCCLikeVersion(getCompilerExecutableName())) | 209 | print("Compiler Version: %s" % craftCompiler.getGCCLikeVersion(craftCompiler.getCompilerExecutableName())) | ||
187 | print("Compiler Target: %s" % _getGCCTarget()) | 210 | print("Compiler Target: %s" % craftCompiler._getGCCTarget()) |