-
Andreas Traczyk authored
This patch prevents client build failure on systems without the specific build toolchain path in the system or user path environment variable. It so happens that qmake needs the paths for the ms build toolchain, so we pass them to the executing subprocess. Gitlab: #581 Change-Id: Id5dcaead487d0c128c9fb04ca22d79438531b0c0
Andreas Traczyk authoredThis patch prevents client build failure on systems without the specific build toolchain path in the system or user path environment variable. It so happens that qmake needs the paths for the ms build toolchain, so we pass them to the executing subprocess. Gitlab: #581 Change-Id: Id5dcaead487d0c128c9fb04ca22d79438531b0c0
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
make-client.py 8.69 KiB
import tempfile
import re
import sys
import os
import subprocess
import platform
import argparse
import multiprocessing
import fileinput
import re
# vs help
win_sdk_default = '10.0.16299.0'
win_toolset_default = 'v142'
vs_where_path = os.path.join(
os.environ['ProgramFiles(x86)'], 'Microsoft Visual Studio', 'Installer', 'vswhere.exe'
)
host_is_64bit = (False, True)[platform.machine().endswith('64')]
def execute_cmd(cmd, with_shell=False, env_vars={}):
if(bool(env_vars)):
p = subprocess.Popen(cmd, shell=with_shell,
stdout=sys.stdout,
env=env_vars)
else:
p = subprocess.Popen(cmd, shell=with_shell)
_, _ = p.communicate()
return p.returncode
def getLatestVSVersion():
args = [
'-latest',
'-products *',
'-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
'-property installationVersion'
]
cmd = [vs_where_path] + args
output = subprocess.check_output(' '.join(cmd)).decode('utf-8')
if output:
return output.splitlines()[0].split('.')[0]
else:
return
def findVSLatestDir():
args = [
'-latest',
'-products *',
'-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64',
'-property installationPath'
]
cmd = [vs_where_path] + args
output = subprocess.check_output(
' '.join(cmd)).decode('utf-8', errors='ignore')
if output:
return output.splitlines()[0]
else:
return
def findMSBuild():
filename = 'MSBuild.exe'
for root, _, files in os.walk(findVSLatestDir() + r'\\MSBuild'):
if filename in files:
return os.path.join(root, filename)
def getVSEnv(arch='x64', platform='', version=''):
env_cmd = 'set path=%path:"=% && ' + \
getVSEnvCmd(arch, platform, version) + ' && set'
p = subprocess.Popen(env_cmd,
shell=True,
stdout=subprocess.PIPE)
stdout, _ = p.communicate()
out = stdout.decode('utf-8', errors='ignore').split("\r\n")[5:-1]
return dict(s.split('=', 1) for s in out)
def getVSEnvCmd(arch='x64', platform='', version=''):
vcEnvInit = [findVSLatestDir() + r'\VC\Auxiliary\Build\"vcvarsall.bat']
if platform != '':
args = [arch, platform, version]
else:
args = [arch, version]
if args:
vcEnvInit.extend(args)
vcEnvInit = 'call \"' + ' '.join(vcEnvInit)
return vcEnvInit
def build_project(msbuild, msbuild_args, proj, env_vars):
args = []
args.extend(msbuild_args)
args.append(proj)
cmd = [msbuild]
cmd.extend(args)
if (execute_cmd(cmd, True, env_vars)):
print("Build failed when building ", proj)
sys.exit(1)
def replace_vs_prop(filename, prop, val):
p = re.compile(r'(?s)<' + prop + r'\s?.*?>(.*?)<\/' + prop + r'>')
val = r'<' + prop + r'>' + val + r'</' + prop + r'>'
with fileinput.FileInput(filename, inplace=True) as file:
for line in file:
print(re.sub(p, val, line), end='')
def deps(arch, toolset, qtver):
print('Deps Qt Client Release|' + arch)
# Fetch QRencode
print('Generate QRencode')
apply_cmd = "git apply --reject --ignore-whitespace --whitespace=fix"
qrencode_path = 'qrencode-win32'
if (os.path.isdir(qrencode_path)):
os.system('rmdir qrencode-win32 /s /q')
if (execute_cmd("git clone https://github.com/BlueDragon747/qrencode-win32.git", True)):
print("Git clone failed when cloning from https://github.com/BlueDragon747/qrencode-win32.git")
sys.exit(1)
if(execute_cmd("cd qrencode-win32 && git checkout d6495a2aa74d058d54ae0f1b9e9e545698de66ce && " + apply_cmd + ' ..\\qrencode-win32.patch', True)):
print("qrencode-win32 set up error")
sys.exit(1)
print('Building qrcodelib')
build(arch, '', '', 'Release-Lib',
'\\qrencode-win32\\qrencode-win32\\vc8\\qrcodelib\\qrcodelib.vcxproj', qtver, False)
def build(arch, toolset, sdk_version, config_str, project_path_under_current_path, qtver, force_option=True):
print("Building with Qt " + qtver)
configuration_type = 'StaticLibrary'
qtFolderDir = "msvc2019_64"
vs_env_vars = {}
vs_env_vars.update(getVSEnv())
qmake_cmd = "C:\\Qt\\" + qtver + "\\" + qtFolderDir + "\\bin\\qmake.exe"
if (config_str == 'Release'):
print('Generating project using qmake ' + config_str + '|' + arch)
if(execute_cmd(qmake_cmd + " -tp vc jami-qt.pro -o jami-qt.vcxproj", False, vs_env_vars)):
print("Qmake vcxproj file generate error")
sys.exit(1)
configuration_type = 'Application'
elif (config_str == 'Beta'):
print('Generating project using qmake ' + config_str + '|' + arch)
if(execute_cmd(qmake_cmd + " -tp vc jami-qt.pro -o jami-qt.vcxproj CONFIG+=Beta", False, vs_env_vars)):
print("Beta: Qmake vcxproj file generate error")
sys.exit(1)
config_str = 'Release'
configuration_type = 'Application'
elif (config_str == 'ReleaseCompile'):
print('Generating project using qmake ' + config_str + '|' + arch)
if(execute_cmd(qmake_cmd + " -tp vc jami-qt.pro -o jami-qt.vcxproj CONFIG+=ReleaseCompile", False, vs_env_vars)):
print("ReleaseCompile: Qmake vcxproj file generate error")
sys.exit(1)
config_str = 'Release'
# Note: If project is configured to Beta or ReleaseCompile, the configuration name is still release,
# but will be outputted into x64/Beta folder (for Beta Only)
print('Building projects in ' + config_str + '|' + arch)
this_dir = os.path.dirname(os.path.realpath(__file__))
qt_client_proj_path = this_dir + project_path_under_current_path
msbuild = findMSBuild()
if not os.path.isfile(msbuild):
raise IOError('msbuild.exe not found. path=' + msbuild)
msbuild_args = [
'/nologo',
'/verbosity:minimal',
'/maxcpucount:' + str(multiprocessing.cpu_count()),
'/p:Platform=' + arch,
'/p:Configuration=' + config_str,
'/p:ConfigurationType=' + configuration_type,
'/p:useenv=true']
if (toolset != ''):
msbuild_args.append('/p:PlatformToolset=' + toolset)
if (force_option):
# force toolset
replace_vs_prop(qt_client_proj_path,
'PlatformToolset',
toolset)
# force unicode
replace_vs_prop(qt_client_proj_path,
'CharacterSet',
'Unicode')
# force sdk_version
replace_vs_prop(qt_client_proj_path,
'WindowsTargetPlatformVersion',
sdk_version)
build_project(msbuild, msbuild_args, qt_client_proj_path, vs_env_vars)
def parse_args():
ap = argparse.ArgumentParser(description="Windows Jami-lrc build tool")
ap.add_argument(
'-b', '--build', action='store_true',
help='Build Qt Client')
ap.add_argument(
'-a', '--arch', default='x64',
help='Sets the build architecture')
ap.add_argument(
'-d', '--deps', action='store_true',
help='Build Deps for Qt Client')
ap.add_argument(
'-bt', '--beta', action='store_true',
help='Build Qt Client in Beta Config')
ap.add_argument(
'-c', '--releasecompile', action='store_true',
help='Build Qt Client in ReleaseCompile Config')
ap.add_argument(
'-s', '--sdk', default=win_sdk_default, type=str,
help='Use specified windows sdk version')
ap.add_argument(
'-t', '--toolset', default=win_toolset_default, type=str,
help='Use specified platform toolset version')
ap.add_argument(
'-q', '--qtver', default='5.15.0',
help='Sets the version of Qmake')
parsed_args = ap.parse_args()
return parsed_args
def main():
if not host_is_64bit:
print('These scripts will only run on a 64-bit Windows system for now!')
sys.exit(1)
if int(getLatestVSVersion()) < 15:
print('These scripts require at least Visual Studio v15 2017!')
sys.exit(1)
parsed_args = parse_args()
if parsed_args.deps:
deps(parsed_args.arch, parsed_args.toolset, parsed_args.qtver)
if parsed_args.build:
build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
'Release', '\\jami-qt.vcxproj', parsed_args.qtver)
if parsed_args.beta:
build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
'Beta', '\\jami-qt.vcxproj', parsed_args.qtver)
if parsed_args.releasecompile:
build(parsed_args.arch, parsed_args.toolset, parsed_args.sdk,
'ReleaseCompile', '\\jami-qt.vcxproj', parsed_args.qtver)
if __name__ == '__main__':
main()