blob: 32b01adef6f4aa8bf0f5760a3542744c0329e669 [file] [log] [blame]
Sébastien Blin1f915762020-08-03 13:27:42 -04001import tempfile
2import re
3import sys
4import os
5import subprocess
6import platform
7import argparse
8import multiprocessing
9import fileinput
10import re
11
12# vs help
13win_sdk_default = '10.0.16299.0'
Andreas Traczyk1b259072020-08-10 10:22:07 -040014win_toolset_default = 'v142'
Sébastien Blin1f915762020-08-03 13:27:42 -040015
16vs_where_path = os.path.join(
17 os.environ['ProgramFiles(x86)'], 'Microsoft Visual Studio', 'Installer', 'vswhere.exe'
18)
19
20host_is_64bit = (False, True)[platform.machine().endswith('64')]
21
Andreas Traczyk1b259072020-08-10 10:22:07 -040022
Sébastien Blin1f915762020-08-03 13:27:42 -040023def execute_cmd(cmd, with_shell=False, env_vars={}):
24 if(bool(env_vars)):
25 p = subprocess.Popen(cmd, shell=with_shell,
Andreas Traczyk1b259072020-08-10 10:22:07 -040026 stdout=sys.stdout,
27 env=env_vars)
Sébastien Blin1f915762020-08-03 13:27:42 -040028 else:
29 p = subprocess.Popen(cmd, shell=with_shell)
30 _, _ = p.communicate()
31 return p.returncode
32
Andreas Traczyk1b259072020-08-10 10:22:07 -040033
Sébastien Blin1f915762020-08-03 13:27:42 -040034def getLatestVSVersion():
35 args = [
36 '-latest',
37 '-products *',
38 '-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
39 '-property installationVersion'
40 ]
41 cmd = [vs_where_path] + args
42 output = subprocess.check_output(' '.join(cmd)).decode('utf-8')
43 if output:
44 return output.splitlines()[0].split('.')[0]
45 else:
46 return
47
48
49def findVSLatestDir():
50 args = [
51 '-latest',
52 '-products *',
53 '-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
54 '-property installationPath'
55 ]
56 cmd = [vs_where_path] + args
Andreas Traczyk1b259072020-08-10 10:22:07 -040057 output = subprocess.check_output(
58 ' '.join(cmd)).decode('utf-8', errors='ignore')
Sébastien Blin1f915762020-08-03 13:27:42 -040059 if output:
60 return output.splitlines()[0]
61 else:
62 return
63
64
65def findMSBuild():
66 filename = 'MSBuild.exe'
67 for root, _, files in os.walk(findVSLatestDir() + r'\\MSBuild'):
68 if filename in files:
69 return os.path.join(root, filename)
70
71
72def getVSEnv(arch='x64', platform='', version=''):
73 env_cmd = 'set path=%path:"=% && ' + \
74 getVSEnvCmd(arch, platform, version) + ' && set'
75 p = subprocess.Popen(env_cmd,
76 shell=True,
77 stdout=subprocess.PIPE)
78 stdout, _ = p.communicate()
79 out = stdout.decode('utf-8', errors='ignore').split("\r\n")[5:-1]
80 return dict(s.split('=', 1) for s in out)
81
Andreas Traczyk1b259072020-08-10 10:22:07 -040082
Sébastien Blin1f915762020-08-03 13:27:42 -040083def getVSEnvCmd(arch='x64', platform='', version=''):
84 vcEnvInit = [findVSLatestDir() + r'\VC\Auxiliary\Build\"vcvarsall.bat']
85 if platform != '':
86 args = [arch, platform, version]
87 else:
88 args = [arch, version]
89 if args:
90 vcEnvInit.extend(args)
91 vcEnvInit = 'call \"' + ' '.join(vcEnvInit)
92 return vcEnvInit
93
Andreas Traczyk1b259072020-08-10 10:22:07 -040094
Sébastien Blin1f915762020-08-03 13:27:42 -040095def build_project(msbuild, msbuild_args, proj, env_vars):
96 args = []
97 args.extend(msbuild_args)
98 args.append(proj)
99 cmd = [msbuild]
100 cmd.extend(args)
101 if (execute_cmd(cmd, True, env_vars)):
102 print("Build failed when building ", proj)
103 sys.exit(1)
104
Andreas Traczyk1b259072020-08-10 10:22:07 -0400105
Sébastien Blin1f915762020-08-03 13:27:42 -0400106def replace_vs_prop(filename, prop, val):
107 p = re.compile(r'(?s)<' + prop + r'\s?.*?>(.*?)<\/' + prop + r'>')
108 val = r'<' + prop + r'>' + val + r'</' + prop + r'>'
109 with fileinput.FileInput(filename, inplace=True) as file:
110 for line in file:
111 print(re.sub(p, val, line), end='')
112
Andreas Traczyk1b259072020-08-10 10:22:07 -0400113
Yang Wang929bc9b2020-08-13 15:00:43 -0400114def deps(arch, toolset, qtver):
Sébastien Blin1f915762020-08-03 13:27:42 -0400115 print('Deps Qt Client Release|' + arch)
116
117 # Fetch QRencode
118 print('Generate QRencode')
119 apply_cmd = "git apply --reject --ignore-whitespace --whitespace=fix"
120 qrencode_path = 'qrencode-win32'
121 if (os.path.isdir(qrencode_path)):
122 os.system('rmdir qrencode-win32 /s /q')
123 if (execute_cmd("git clone https://github.com/BlueDragon747/qrencode-win32.git", True)):
124 print("Git clone failed when cloning from https://github.com/BlueDragon747/qrencode-win32.git")
125 sys.exit(1)
126 if(execute_cmd("cd qrencode-win32 && git checkout d6495a2aa74d058d54ae0f1b9e9e545698de66ce && " + apply_cmd + ' ..\\qrencode-win32.patch', True)):
Andreas Traczyk1b259072020-08-10 10:22:07 -0400127 print("qrencode-win32 set up error")
Sébastien Blin1f915762020-08-03 13:27:42 -0400128 sys.exit(1)
129
130 print('Building qrcodelib')
Andreas Traczyk1b259072020-08-10 10:22:07 -0400131 build(arch, '', '', 'Release-Lib',
132 '\\qrencode-win32\\qrencode-win32\\vc8\\qrcodelib\\qrcodelib.vcxproj', qtver, False)
133
Sébastien Blin1f915762020-08-03 13:27:42 -0400134
135def build(arch, toolset, sdk_version, config_str, project_path_under_current_path, qtver, force_option=True):
Andreas Traczykb1465cf2020-08-13 12:55:47 -0400136 print("Building with Qt " + qtver)
137
Sébastien Blin1f915762020-08-03 13:27:42 -0400138 configuration_type = 'StaticLibrary'
139
Andreas Traczyk512168c2020-08-17 16:54:40 -0400140 qtFolderDir = "msvc2019_64"
Sébastien Blin1f915762020-08-03 13:27:42 -0400141
Andreas Traczyk512168c2020-08-17 16:54:40 -0400142 vs_env_vars = {}
143 vs_env_vars.update(getVSEnv())
Sébastien Blin1f915762020-08-03 13:27:42 -0400144
Andreas Traczyk512168c2020-08-17 16:54:40 -0400145 qmake_cmd = "C:\\Qt\\" + qtver + "\\" + qtFolderDir + "\\bin\\qmake.exe"
Sébastien Blin1f915762020-08-03 13:27:42 -0400146 if (config_str == 'Release'):
147 print('Generating project using qmake ' + config_str + '|' + arch)
Andreas Traczyk512168c2020-08-17 16:54:40 -0400148 if(execute_cmd(qmake_cmd + " -tp vc jami-qt.pro -o jami-qt.vcxproj", False, vs_env_vars)):
Sébastien Blin1f915762020-08-03 13:27:42 -0400149 print("Qmake vcxproj file generate error")
150 sys.exit(1)
151 configuration_type = 'Application'
152 elif (config_str == 'Beta'):
153 print('Generating project using qmake ' + config_str + '|' + arch)
Andreas Traczyk512168c2020-08-17 16:54:40 -0400154 if(execute_cmd(qmake_cmd + " -tp vc jami-qt.pro -o jami-qt.vcxproj CONFIG+=Beta", False, vs_env_vars)):
155 print("Beta: Qmake vcxproj file generate error")
Sébastien Blin1f915762020-08-03 13:27:42 -0400156 sys.exit(1)
157 config_str = 'Release'
158 configuration_type = 'Application'
159 elif (config_str == 'ReleaseCompile'):
160 print('Generating project using qmake ' + config_str + '|' + arch)
Andreas Traczyk512168c2020-08-17 16:54:40 -0400161 if(execute_cmd(qmake_cmd + " -tp vc jami-qt.pro -o jami-qt.vcxproj CONFIG+=ReleaseCompile", False, vs_env_vars)):
Sébastien Blin1f915762020-08-03 13:27:42 -0400162 print("ReleaseCompile: Qmake vcxproj file generate error")
163 sys.exit(1)
164 config_str = 'Release'
165
166 # Note: If project is configured to Beta or ReleaseCompile, the configuration name is still release,
167 # but will be outputted into x64/Beta folder (for Beta Only)
168
169 print('Building projects in ' + config_str + '|' + arch)
Sébastien Blin1f915762020-08-03 13:27:42 -0400170 this_dir = os.path.dirname(os.path.realpath(__file__))
171 qt_client_proj_path = this_dir + project_path_under_current_path
172
173 msbuild = findMSBuild()
174 if not os.path.isfile(msbuild):
175 raise IOError('msbuild.exe not found. path=' + msbuild)
176 msbuild_args = [
177 '/nologo',
178 '/verbosity:minimal',
179 '/maxcpucount:' + str(multiprocessing.cpu_count()),
180 '/p:Platform=' + arch,
181 '/p:Configuration=' + config_str,
182 '/p:ConfigurationType=' + configuration_type,
183 '/p:useenv=true']
184 if (toolset != ''):
185 msbuild_args.append('/p:PlatformToolset=' + toolset)
186 if (force_option):
187 # force toolset
188 replace_vs_prop(qt_client_proj_path,
189 'PlatformToolset',
190 toolset)
191 # force unicode
192 replace_vs_prop(qt_client_proj_path,
193 'CharacterSet',
194 'Unicode')
195 # force sdk_version
196 replace_vs_prop(qt_client_proj_path,
197 'WindowsTargetPlatformVersion',
198 sdk_version)
199
200 build_project(msbuild, msbuild_args, qt_client_proj_path, vs_env_vars)
201
Andreas Traczyk1b259072020-08-10 10:22:07 -0400202
Sébastien Blin1f915762020-08-03 13:27:42 -0400203def parse_args():
204 ap = argparse.ArgumentParser(description="Windows Jami-lrc build tool")
205 ap.add_argument(
206 '-b', '--build', action='store_true',
207 help='Build Qt Client')
208 ap.add_argument(
209 '-a', '--arch', default='x64',
210 help='Sets the build architecture')
211 ap.add_argument(
212 '-d', '--deps', action='store_true',
213 help='Build Deps for Qt Client')
214 ap.add_argument(
215 '-bt', '--beta', action='store_true',
216 help='Build Qt Client in Beta Config')
217 ap.add_argument(
218 '-c', '--releasecompile', action='store_true',
219 help='Build Qt Client in ReleaseCompile Config')
220 ap.add_argument(
221 '-s', '--sdk', default=win_sdk_default, type=str,
222 help='Use specified windows sdk version')
223 ap.add_argument(
224 '-t', '--toolset', default=win_toolset_default, type=str,
225 help='Use specified platform toolset version')
226 ap.add_argument(
Andreas Traczykb1465cf2020-08-13 12:55:47 -0400227 '-q', '--qtver', default='5.15.0',
Sébastien Blin1f915762020-08-03 13:27:42 -0400228 help='Sets the version of Qmake')
229
230 parsed_args = ap.parse_args()
231
232 return parsed_args
233
234
235def main():
236 if not host_is_64bit:
237 print('These scripts will only run on a 64-bit Windows system for now!')
238 sys.exit(1)
239
240 if int(getLatestVSVersion()) < 15:
241 print('These scripts require at least Visual Studio v15 2017!')
242 sys.exit(1)
243
244 parsed_args = parse_args()
245
246 if parsed_args.deps:
Yang Wang929bc9b2020-08-13 15:00:43 -0400247 deps(parsed_args.arch, parsed_args.toolset, parsed_args.qtver)
Sébastien Blin1f915762020-08-03 13:27:42 -0400248
249 if parsed_args.build:
Andreas Traczyk1b259072020-08-10 10:22:07 -0400250 build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
251 'Release', '\\jami-qt.vcxproj', parsed_args.qtver)
Sébastien Blin1f915762020-08-03 13:27:42 -0400252
253 if parsed_args.beta:
Andreas Traczyk1b259072020-08-10 10:22:07 -0400254 build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
255 'Beta', '\\jami-qt.vcxproj', parsed_args.qtver)
Sébastien Blin1f915762020-08-03 13:27:42 -0400256
257 if parsed_args.releasecompile:
Andreas Traczyk1b259072020-08-10 10:22:07 -0400258 build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
259 'ReleaseCompile', '\\jami-qt.vcxproj', parsed_args.qtver)
260
Sébastien Blin1f915762020-08-03 13:27:42 -0400261
262if __name__ == '__main__':
263 main()