2018-11-08 10:24:30 +03:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#-*- coding: ascii -*-
|
|
|
|
|
|
|
|
# ShaderConductor
|
|
|
|
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
# Licensed under the MIT License.
|
|
|
|
|
2018-11-10 06:54:16 +03:00
|
|
|
import multiprocessing, os, platform, subprocess, sys
|
2018-11-08 10:24:30 +03:00
|
|
|
|
2018-11-15 09:53:48 +03:00
|
|
|
def LogError(message):
|
|
|
|
print("[E] %s" % message)
|
|
|
|
sys.stdout.flush()
|
|
|
|
if 0 == sys.platform.find("win"):
|
|
|
|
pauseCmd = "pause"
|
|
|
|
else:
|
|
|
|
pauseCmd = "read"
|
|
|
|
subprocess.call(pauseCmd, shell = True)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
def LogInfo(message):
|
|
|
|
print("[I] %s" % message)
|
|
|
|
sys.stdout.flush()
|
|
|
|
|
|
|
|
def LogWarning(message):
|
|
|
|
print("[W] %s" % message)
|
|
|
|
sys.stdout.flush()
|
|
|
|
|
2018-11-08 10:24:30 +03:00
|
|
|
def FindProgramFilesFolder():
|
|
|
|
env = os.environ
|
|
|
|
if "64bit" == platform.architecture()[0]:
|
|
|
|
if "ProgramFiles(x86)" in env:
|
2018-11-09 20:30:34 +03:00
|
|
|
programFilesFolder = env["ProgramFiles(x86)"]
|
2018-11-08 10:24:30 +03:00
|
|
|
else:
|
2018-11-09 20:30:34 +03:00
|
|
|
programFilesFolder = "C:\Program Files (x86)"
|
2018-11-08 10:24:30 +03:00
|
|
|
else:
|
|
|
|
if "ProgramFiles" in env:
|
2018-11-09 20:30:34 +03:00
|
|
|
programFilesFolder = env["ProgramFiles"]
|
2018-11-08 10:24:30 +03:00
|
|
|
else:
|
2018-11-09 20:30:34 +03:00
|
|
|
programFilesFolder = "C:\Program Files"
|
|
|
|
return programFilesFolder
|
2018-11-08 10:24:30 +03:00
|
|
|
|
2019-04-22 04:52:25 +03:00
|
|
|
def FindVS2017OrUpFolder(programFilesFolder, vsVersion, vsName):
|
2018-11-09 20:30:34 +03:00
|
|
|
tryVswhereLocation = programFilesFolder + "\\Microsoft Visual Studio\\Installer\\vswhere.exe"
|
|
|
|
if os.path.exists(tryVswhereLocation):
|
|
|
|
vsLocation = subprocess.check_output([tryVswhereLocation,
|
2018-11-08 10:24:30 +03:00
|
|
|
"-latest",
|
|
|
|
"-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
|
|
|
"-property", "installationPath",
|
2019-04-22 04:52:25 +03:00
|
|
|
"-version", "[%d.0,%d.0)" % (vsVersion, vsVersion + 1),
|
2018-11-08 10:24:30 +03:00
|
|
|
"-prerelease"]).decode().split("\r\n")[0]
|
2018-11-09 20:30:34 +03:00
|
|
|
tryFolder = vsLocation + "\\VC\\Auxiliary\\Build\\"
|
|
|
|
tryVcvarsall = "VCVARSALL.BAT"
|
|
|
|
if os.path.exists(tryFolder + tryVcvarsall):
|
|
|
|
return tryFolder
|
2018-11-08 10:24:30 +03:00
|
|
|
else:
|
2019-04-22 04:52:25 +03:00
|
|
|
names = ("Preview", vsName)
|
2018-11-08 10:24:30 +03:00
|
|
|
skus = ("Community", "Professional", "Enterprise")
|
|
|
|
for name in names:
|
|
|
|
for sku in skus:
|
2018-11-09 20:30:34 +03:00
|
|
|
tryFolder = programFilesFolder + "\\Microsoft Visual Studio\\%s\\%s\\VC\\Auxiliary\\Build\\" % (name, sku)
|
|
|
|
tryVcvarsall = "VCVARSALL.BAT"
|
|
|
|
if os.path.exists(tryFolder + tryVcvarsall):
|
|
|
|
return tryFolder
|
2019-04-22 04:52:25 +03:00
|
|
|
LogError("Could NOT find VS%s.\n" % vsName)
|
2018-11-08 10:24:30 +03:00
|
|
|
return ""
|
|
|
|
|
2019-04-22 04:52:25 +03:00
|
|
|
def FindVS2019Folder(programFilesFolder):
|
|
|
|
return FindVS2017OrUpFolder(programFilesFolder, 16, "2019")
|
|
|
|
|
|
|
|
def FindVS2017Folder(programFilesFolder):
|
|
|
|
return FindVS2017OrUpFolder(programFilesFolder, 15, "2017")
|
|
|
|
|
2018-11-27 11:31:30 +03:00
|
|
|
def FindVS2015Folder(programFilesFolder):
|
|
|
|
env = os.environ
|
|
|
|
if "VS140COMNTOOLS" in env:
|
|
|
|
return env["VS140COMNTOOLS"] + "..\\..\\VC\\"
|
|
|
|
else:
|
|
|
|
tryFolder = programFilesFolder + "\\Microsoft Visual Studio 14.0\\VC\\"
|
|
|
|
tryVcvarsall = "VCVARSALL.BAT"
|
|
|
|
if os.path.exists(tryFolder + tryVcvarsall):
|
|
|
|
return tryFolder
|
|
|
|
else:
|
|
|
|
LogError("Could NOT find VS2015.\n")
|
|
|
|
|
2018-11-15 09:53:48 +03:00
|
|
|
class BatchCommand:
|
|
|
|
def __init__(self, hostPlatform):
|
|
|
|
self.commands = []
|
|
|
|
self.hostPlatform = hostPlatform
|
|
|
|
|
|
|
|
def AddCommand(self, cmd):
|
|
|
|
self.commands += [cmd]
|
|
|
|
|
|
|
|
def Execute(self):
|
|
|
|
batchFileName = "scBuild."
|
|
|
|
if "win" == self.hostPlatform:
|
|
|
|
batchFileName += "bat"
|
|
|
|
else:
|
|
|
|
batchFileName += "sh"
|
|
|
|
batchFile = open(batchFileName, "w")
|
|
|
|
batchFile.writelines([cmd_line + "\n" for cmd_line in self.commands])
|
|
|
|
batchFile.close()
|
|
|
|
if "win" == self.hostPlatform:
|
|
|
|
retCode = subprocess.call(batchFileName, shell = True)
|
|
|
|
else:
|
|
|
|
subprocess.call("chmod 777 " + batchFileName, shell = True)
|
|
|
|
retCode = subprocess.call("./" + batchFileName, shell = True)
|
|
|
|
os.remove(batchFileName)
|
|
|
|
return retCode
|
|
|
|
|
2020-05-02 08:22:41 +03:00
|
|
|
def Build(hostPlatform, hostArch, buildSys, compiler, arch, configuration, tblgenMode, tblgenPath):
|
2018-11-09 20:30:34 +03:00
|
|
|
originalDir = os.path.abspath(os.curdir)
|
|
|
|
|
2018-11-08 10:24:30 +03:00
|
|
|
if not os.path.exists("Build"):
|
|
|
|
os.mkdir("Build")
|
2018-11-09 20:30:34 +03:00
|
|
|
|
|
|
|
multiConfig = (buildSys.find("vs") == 0)
|
|
|
|
|
2018-12-01 09:51:58 +03:00
|
|
|
buildDir = "Build/%s-%s-%s-%s" % (buildSys, hostPlatform, compiler, arch)
|
2020-04-30 09:11:17 +03:00
|
|
|
if (not multiConfig) or (configuration == "clangformat"):
|
2018-11-09 20:30:34 +03:00
|
|
|
buildDir += "-%s" % configuration;
|
|
|
|
if not os.path.exists(buildDir):
|
|
|
|
os.mkdir(buildDir)
|
|
|
|
os.chdir(buildDir)
|
|
|
|
buildDir = os.path.abspath(os.curdir)
|
|
|
|
|
2020-05-02 08:22:41 +03:00
|
|
|
tblgenOptions = ""
|
|
|
|
if (tblgenPath != None):
|
|
|
|
tblgenOptions = " -DCLANG_TABLEGEN=\"%s\" -DLLVM_TABLEGEN=\"%s\"" % tblgenPath
|
|
|
|
|
2018-11-10 06:54:16 +03:00
|
|
|
parallel = multiprocessing.cpu_count()
|
|
|
|
|
2018-11-15 09:53:48 +03:00
|
|
|
batCmd = BatchCommand(hostPlatform)
|
|
|
|
if hostPlatform == "win":
|
2018-11-27 11:31:30 +03:00
|
|
|
programFilesFolder = FindProgramFilesFolder()
|
2019-04-22 04:52:25 +03:00
|
|
|
if (buildSys == "vs2019") or ((buildSys == "ninja") and (compiler == "vc142")):
|
|
|
|
vsFolder = FindVS2019Folder(programFilesFolder)
|
|
|
|
elif (buildSys == "vs2017") or ((buildSys == "ninja") and (compiler == "vc141")):
|
2018-11-27 11:31:30 +03:00
|
|
|
vsFolder = FindVS2017Folder(programFilesFolder)
|
|
|
|
elif (buildSys == "vs2015") or ((buildSys == "ninja") and (compiler == "vc140")):
|
|
|
|
vsFolder = FindVS2015Folder(programFilesFolder)
|
2018-11-15 09:53:48 +03:00
|
|
|
if "x64" == arch:
|
|
|
|
vcOption = "amd64"
|
2019-07-14 10:16:04 +03:00
|
|
|
vcArch = "x64"
|
2018-11-15 09:53:48 +03:00
|
|
|
elif "x86" == arch:
|
|
|
|
vcOption = "x86"
|
2019-07-14 10:16:04 +03:00
|
|
|
vcArch = "Win32"
|
|
|
|
elif "arm64" == arch:
|
|
|
|
vcOption = "amd64_arm64"
|
|
|
|
vcArch = "ARM64"
|
|
|
|
elif "arm" == arch:
|
|
|
|
vcOption = "amd64_arm"
|
|
|
|
vcArch = "ARM"
|
2018-11-15 09:53:48 +03:00
|
|
|
else:
|
|
|
|
LogError("Unsupported architecture.\n")
|
2018-11-27 11:31:30 +03:00
|
|
|
vcToolset = ""
|
2019-04-22 04:52:25 +03:00
|
|
|
if (buildSys == "vs2019") and (compiler == "vc141"):
|
|
|
|
vcOption += " -vcvars_ver=14.1"
|
|
|
|
vcToolset = "v141,"
|
|
|
|
elif ((buildSys == "vs2019") or (buildSys == "vs2017")) and (compiler == "vc140"):
|
2018-11-27 11:31:30 +03:00
|
|
|
vcOption += " -vcvars_ver=14.0"
|
|
|
|
vcToolset = "v140,"
|
|
|
|
batCmd.AddCommand("@call \"%sVCVARSALL.BAT\" %s" % (vsFolder, vcOption))
|
2018-11-15 09:53:48 +03:00
|
|
|
batCmd.AddCommand("@cd /d \"%s\"" % buildDir)
|
2018-11-09 20:30:34 +03:00
|
|
|
if (buildSys == "ninja"):
|
2018-11-15 09:53:48 +03:00
|
|
|
if hostPlatform == "win":
|
|
|
|
batCmd.AddCommand("set CC=cl.exe")
|
|
|
|
batCmd.AddCommand("set CXX=cl.exe")
|
2020-04-30 09:11:17 +03:00
|
|
|
if (configuration == "clangformat"):
|
|
|
|
options = "-DSC_CLANGFORMAT=\"ON\""
|
|
|
|
else:
|
2020-05-02 08:22:41 +03:00
|
|
|
options = "-DCMAKE_BUILD_TYPE=\"%s\" -DSC_ARCH_NAME=\"%s\" %s" % (configuration, arch, tblgenOptions)
|
2020-04-30 09:11:17 +03:00
|
|
|
batCmd.AddCommand("cmake -G Ninja %s ../../" % options)
|
2020-05-02 08:22:41 +03:00
|
|
|
if tblgenMode:
|
|
|
|
batCmd.AddCommand("ninja clang-tblgen -j%d" % parallel)
|
|
|
|
batCmd.AddCommand("ninja llvm-tblgen -j%d" % parallel)
|
|
|
|
else:
|
|
|
|
batCmd.AddCommand("ninja -j%d" % parallel)
|
2018-11-09 20:30:34 +03:00
|
|
|
else:
|
2019-04-22 04:52:25 +03:00
|
|
|
if buildSys == "vs2019":
|
|
|
|
generator = "\"Visual Studio 16\""
|
|
|
|
elif buildSys == "vs2017":
|
2018-11-27 11:31:30 +03:00
|
|
|
generator = "\"Visual Studio 15\""
|
|
|
|
elif buildSys == "vs2015":
|
|
|
|
generator = "\"Visual Studio 14\""
|
2020-04-30 09:11:17 +03:00
|
|
|
if (configuration == "clangformat"):
|
|
|
|
cmake_options = "-DSC_CLANGFORMAT=\"ON\""
|
|
|
|
msbuild_options = ""
|
|
|
|
else:
|
2020-05-02 08:22:41 +03:00
|
|
|
cmake_options = "-T %shost=x64 -A %s %s" % (vcToolset, vcArch, tblgenOptions)
|
2020-04-30 09:11:17 +03:00
|
|
|
msbuild_options = "/m:%d /v:m /p:Configuration=%s,Platform=%s" % (parallel, configuration, vcArch)
|
|
|
|
batCmd.AddCommand("cmake -G %s %s ../../" % (generator, cmake_options))
|
2020-05-02 08:22:41 +03:00
|
|
|
if tblgenMode:
|
|
|
|
batCmd.AddCommand("MSBuild External\\DirectXShaderCompiler\\tools\\clang\\utils\\TableGen\\clang-tblgen.vcxproj /nologo %s" % msbuild_options)
|
|
|
|
batCmd.AddCommand("MSBuild External\\DirectXShaderCompiler\\utils\\TableGen\\llvm-tblgen.vcxproj /nologo %s" % msbuild_options)
|
|
|
|
else:
|
|
|
|
batCmd.AddCommand("MSBuild ALL_BUILD.vcxproj /nologo %s" % msbuild_options)
|
2018-11-15 09:53:48 +03:00
|
|
|
if batCmd.Execute() != 0:
|
|
|
|
LogError("Build failed.\n")
|
2018-11-09 20:30:34 +03:00
|
|
|
|
|
|
|
os.chdir(originalDir)
|
2020-05-02 08:22:41 +03:00
|
|
|
|
|
|
|
tblGenPath = buildDir + "/External/DirectXShaderCompiler"
|
|
|
|
if multiConfig:
|
|
|
|
tblGenPath += "/" + configuration
|
|
|
|
tblGenPath += "/bin/"
|
|
|
|
clangTblgenPath = tblGenPath + "clang-tblgen"
|
|
|
|
llvmTblGenPath = tblGenPath + "llvm-tblgen"
|
|
|
|
if (hostPlatform == "win"):
|
|
|
|
clangTblgenPath += ".exe"
|
|
|
|
llvmTblGenPath += ".exe"
|
|
|
|
return (clangTblgenPath, llvmTblGenPath)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
hostPlatform = sys.platform
|
|
|
|
if 0 == hostPlatform.find("win"):
|
|
|
|
hostPlatform = "win"
|
|
|
|
elif 0 == hostPlatform.find("linux"):
|
|
|
|
hostPlatform = "linux"
|
|
|
|
elif 0 == hostPlatform.find("darwin"):
|
|
|
|
hostPlatform = "osx"
|
|
|
|
|
|
|
|
hostArch = platform.machine()
|
|
|
|
if (hostArch == "AMD64") or (hostArch == "x86_64"):
|
|
|
|
hostArch = "x64"
|
|
|
|
elif (hostArch == "i386"):
|
|
|
|
hostArch = "x86"
|
|
|
|
elif (hostArch == "ARM64"):
|
|
|
|
hostArch = "arm64"
|
|
|
|
else:
|
|
|
|
LogError("Unknown host architecture %s.\n" % hostArch)
|
|
|
|
|
|
|
|
argc = len(sys.argv);
|
|
|
|
if (argc > 1):
|
|
|
|
buildSys = sys.argv[1]
|
|
|
|
else:
|
|
|
|
if hostPlatform == "win":
|
|
|
|
buildSys = "vs2019"
|
|
|
|
else:
|
|
|
|
buildSys = "ninja"
|
|
|
|
if (argc > 2):
|
|
|
|
compiler = sys.argv[2]
|
|
|
|
else:
|
|
|
|
if buildSys == "vs2019":
|
|
|
|
compiler = "vc142"
|
|
|
|
elif buildSys == "vs2017":
|
|
|
|
compiler = "vc141"
|
|
|
|
elif buildSys == "vs2015":
|
|
|
|
compiler = "vc140"
|
|
|
|
else:
|
|
|
|
compiler = "gcc"
|
|
|
|
if (argc > 3):
|
|
|
|
arch = sys.argv[3]
|
|
|
|
else:
|
|
|
|
arch = "x64"
|
|
|
|
if (argc > 4):
|
|
|
|
configuration = sys.argv[4]
|
|
|
|
else:
|
|
|
|
configuration = "Release"
|
|
|
|
|
|
|
|
tblgenPath = None
|
|
|
|
if (configuration != "clangformat") and (hostArch != arch) and (not ((hostArch == "x64") and (arch == "x86"))):
|
|
|
|
# Cross compiling:
|
|
|
|
# Generate a project with host architecture, build clang-tblgen and llvm-tblgen, and keep the path of clang-tblgen and llvm-tblgen
|
|
|
|
tblgenPath = Build(hostPlatform, hostArch, buildSys, compiler, hostArch, configuration, True, None)
|
|
|
|
|
|
|
|
Build(hostPlatform, hostArch, buildSys, compiler, arch, configuration, False, tblgenPath)
|