RedPanda-CPP/addon/compiler_hint/windows_domain.tl

418 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

global function apiVersion(): ApiVersion
return {
kind = "compiler_hint",
major = 0,
minor = 2,
}
end
local gnuArchMap: {string:string} = {
i386 = "i686",
x86_64 = "x86_64",
arm64 = "aarch64",
}
local profileNameMap: {string:{string:string}} = {
release = {
en_US = "release",
pt_BR = "lançamento",
zh_CN = "发布",
zh_TW = "發佈",
},
debug = {
en_US = "debug",
pt_BR = "depuração",
zh_CN = "调试",
zh_TW = "偵錯",
},
debugWithAsan = {
en_US = "debug with ASan",
pt_BR = "depuração com ASan",
zh_CN = "ASan 调试",
zh_TW = "ASan 偵錯",
},
}
local function nameGeneratorMingwGcc(lang: string, arch: string, profile: string, isUtf8: boolean): string
local template: {string:string} = {
en_US = "MinGW GCC %1 in %2, %3",
pt_BR = "GCC MinGW %1 em %2, %3",
zh_CN = "%2 MinGW GCC %1%3",
zh_TW = "%2 MinGW GCC %1%3",
}
local systemCodePage: {string:string} = {
en_US = "system code page",
pt_Br = "página de código do sistema",
zh_CN = "系统代码页",
zh_TW = "系統代碼頁",
}
return C_Util.format(
template[lang] or template.en_US,
gnuArchMap[arch],
isUtf8 and "UTF-8" or systemCodePage[lang] or systemCodePage.en_US,
profileNameMap[profile][lang] or profileNameMap[profile].en_US
)
end
local function nameGeneratorClang(lang: string, arch: string, profile: string, isMingw: boolean): string
local template: {string:string} = {
en_US = "%1 Clang %2, %3",
pt_BR = "Clang %2 %1, %3",
zh_CN = "%1 Clang %2%3",
zh_TW = "%1 Clang %2%3",
}
local msvcCompatible: {string:string} = {
en_US = "MSVC-compatible",
pt_BR = "compatível com MSVC",
zh_CN = "兼容 MSVC 的",
zh_TW = "相容 MSVC 的",
}
return C_Util.format(
template[lang] or template.en_US,
isMingw and "LLVM-MinGW" or msvcCompatible[lang] or msvcCompatible.en_US,
gnuArchMap[arch],
profileNameMap[profile][lang] or profileNameMap[profile].en_US
)
end
local function mergeCompilerSet(compilerSet: CompilerHint.CompilerSet, other: CompilerHint.CompilerSet)
local c = compilerSet as {string:any}
local o = other as {string:any}
for k, v in pairs(o) do
c[k] = v
end
end
local record Programs
cCompiler: string
cxxCompiler: string
make: string
debugger: string
debugServer: string
resourceCompiler: string
binDirs: {string}
libDirs: {string} | nil
end
local record Config
arch: string
isAnsi: boolean | nil
isClang: boolean | nil
customCompileParams: {string} | nil
customLinkParams: {string} | nil
end
local function generateConfig(
nameGen: (function (arch: string, profile: string): string),
programs: Programs,
config: Config
): CompilerHint.CompilerSet, CompilerHint.CompilerSet, CompilerHint.CompilerSet
local commonOptions : CompilerHint.CompilerSet = {
cCompiler = programs.cCompiler,
cxxCompiler = programs.cxxCompiler,
debugger = programs.debugger,
debugServer = programs.debugServer,
make = programs.make,
resourceCompiler = programs.resourceCompiler,
binDirs = programs.binDirs,
compilerType = config.isClang and "Clang" or "GCC_UTF8",
preprocessingSuffix = ".i",
compilationProperSuffix = ".s",
assemblingSuffix = ".o",
executableSuffix = ".exe",
compilationStage = 3,
ccCmdOptUsePipe = "on",
ccCmdOptWarningAll = "on",
ccCmdOptWarningExtra = "on",
ccCmdOptCheckIsoConformance = "on",
}
if programs.libDirs then
commonOptions.libDirs = programs.libDirs
end
if config.isAnsi then
commonOptions.execCharset = "SYSTEM"
end
if config.customCompileParams then
commonOptions.customCompileParams = config.customCompileParams
end
if config.customLinkParams then
commonOptions.customLinkParams = config.customLinkParams
end
local release: CompilerHint.CompilerSet = {
name = nameGen(config.arch, "release"),
staticLink = true,
linkCmdOptStripExe = "on",
ccCmdOptOptimize = "2",
}
local debug_: CompilerHint.CompilerSet = {
name = nameGen(config.arch, "debug"),
ccCmdOptDebugInfo = "on",
}
local debugWithAsan: CompilerHint.CompilerSet = {
name = nameGen(config.arch, "debugWithAsan"),
ccCmdOptDebugInfo = "on",
ccCmdOptAddressSanitizer = "address",
}
mergeCompilerSet(release, commonOptions)
mergeCompilerSet(debug_, commonOptions)
mergeCompilerSet(debugWithAsan, commonOptions)
return release, debug_, debugWithAsan
end
global function main(): CompilerHint
local appArch = C_System.appArch()
local libexecDir = C_System.appLibexecDir()
local lang = C_Desktop.language()
local supportedAppArches = C_System.supportedAppArchList()
local compilerList = {}
local noSearch = {}
local preferCompiler = 0
local function checkAndAddMingw(arch: string)
local binDir: string
local libDir: string
local excludeBinDir: string
if arch == "i386" then
binDir = libexecDir .. "/mingw32/bin" -- must match case because Windows filesystem can be case sensitive
libDir = libexecDir .. "/mingw32/i686-w64-mingw32/lib"
excludeBinDir = libexecDir .. "/MinGW32/bin" -- workaround for path check
elseif arch == "x86_64" then
binDir = libexecDir .. "/mingw64/bin"
libDir = libexecDir .. "/mingw64/x86_64-w64-mingw32/lib"
excludeBinDir = libexecDir .. "/MinGW64/bin"
else
return
end
if not C_FileSystem.isExecutable(binDir .. "/gcc.exe") then
return
end
local programs: Programs = {
cCompiler = binDir .. "/gcc.exe",
cxxCompiler = binDir .. "/g++.exe",
make = binDir .. "/mingw32-make.exe",
debugger = binDir .. "/gdb.exe",
debugServer = binDir .. "/gdbserver.exe",
resourceCompiler = binDir .. "/windres.exe",
binDirs = {binDir},
}
if C_FileSystem.exists(libDir .. "/libutf8.a") then
local release, debug_, _ = generateConfig(
function (arch_: string, profile: string): string
return nameGeneratorMingwGcc(lang, arch_, profile, true)
end,
programs,
{
arch = arch,
customLinkParams = {"-Wl,--whole-archive", "-lutf8", "-Wl,--no-whole-archive"},
}
)
table.insert(compilerList, release)
table.insert(compilerList, debug_)
if preferCompiler == 0 then
preferCompiler = 2
end
end
do
local release, debug_, _ = generateConfig(
function (arch_: string, profile: string): string
return nameGeneratorMingwGcc(lang, arch_, profile, false)
end,
programs,
{
arch = arch,
isAnsi = true,
}
)
table.insert(compilerList, release)
table.insert(compilerList, debug_)
if preferCompiler == 0 then
preferCompiler = 2
end
end
table.insert(noSearch, excludeBinDir)
end
local function checkAndAddClang()
if not C_FileSystem.isExecutable(libexecDir .. "/llvm-mingw/bin/clang.exe") then
return
end
local binDir = libexecDir .. "/llvm-mingw/bin"
local appTriplet = gnuArchMap[appArch] .. "-w64-mingw32"
local appDllDir = libexecDir .. "/llvm-mingw/" .. appTriplet .. "/bin"
do
-- appArch is always debuggable
local programs: Programs = {
cCompiler = binDir .. "/" .. appTriplet .. "-clang.exe",
cxxCompiler = binDir .. "/" .. appTriplet .. "-clang++.exe",
make = binDir .. "/mingw32-make.exe",
debugger = binDir .. "/lldb-mi.exe",
debugServer = binDir .. "/lldb-server.exe",
resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe",
binDirs = {binDir, appDllDir},
}
local release, debug_, debugWithAsan = generateConfig(
function (arch_: string, profile: string): string
return nameGeneratorClang(lang, arch_, profile, true)
end,
programs,
{
arch = appArch,
isClang = true,
}
)
table.insert(compilerList, release)
table.insert(compilerList, debug_)
if appArch ~= "arm64" then
table.insert(compilerList, debugWithAsan)
if preferCompiler == 0 then
preferCompiler = 3
end
else
if preferCompiler == 0 then
preferCompiler = 2
end
end
end
for _, foreignArch in ipairs(supportedAppArches) do
local gnuArch = gnuArchMap[foreignArch]
if foreignArch ~= appArch and gnuArch ~= nil then
local foreignTriplet = gnuArch .. "-w64-mingw32"
local foreignDllDir = libexecDir .. "/llvm-mingw/" .. foreignTriplet .. "/bin"
local programs: Programs = {
cCompiler = binDir .. "/" .. foreignTriplet .. "-clang.exe",
cxxCompiler = binDir .. "/" .. foreignTriplet .. "-clang++.exe",
make = binDir .. "/mingw32-make.exe",
debugger = binDir .. "/lldb-mi.exe",
debugServer = binDir .. "/lldb-server.exe",
resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe",
binDirs = {binDir, foreignDllDir},
}
local release, _, _ = generateConfig(
function (arch_: string, profile: string): string
return nameGeneratorClang(lang, arch_, profile, true)
end,
programs,
{
arch = foreignArch,
isClang = true,
}
)
table.insert(compilerList, release)
end
end
table.insert(noSearch, binDir)
local llvmOrgPath = C_System.readRegistry([[Software\LLVM\LLVM]], "") or C_System.readRegistry([[Software\Wow6432Node\LLVM\LLVM]], "")
if not llvmOrgPath then
return
end
local llvmOrgBinDir = llvmOrgPath .. "/bin"
do
local msvcTriplet = gnuArchMap[appArch] .. "-pc-windows-msvc"
local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib"
local programs: Programs = {
cCompiler = llvmOrgBinDir .. "/clang.exe",
cxxCompiler = llvmOrgBinDir .. "/clang++.exe",
make = binDir .. "/mingw32-make.exe",
debugger = binDir .. "/lldb-mi.exe",
debugServer = binDir .. "/lldb-server.exe",
resourceCompiler = binDir .. "/" .. appTriplet .. "-windres.exe",
binDirs = {llvmOrgBinDir},
libDirs = {libDir},
}
local release, debug_, _ = generateConfig(
function (arch: string, profile: string): string
return nameGeneratorClang(lang, arch, profile, false)
end,
programs,
{
arch = appArch,
customCompileParams = {
"-target", msvcTriplet,
"-fms-extensions",
"-fms-compatibility",
"-fdelayed-template-parsing",
},
customLinkParams = {
"-target", msvcTriplet,
},
isClang = true,
}
)
table.insert(compilerList, release)
table.insert(compilerList, debug_)
end
for _, foreignArch in ipairs(supportedAppArches) do
local gnuArch = gnuArchMap[foreignArch]
if foreignArch ~= appArch and gnuArch ~= nil then
local foreignTriplet = gnuArch .. "-w64-mingw32"
local msvcTriplet = gnuArchMap[foreignArch] .. "-pc-windows-msvc"
local libDir = libexecDir .. "/llvm-mingw/" .. msvcTriplet .. "/lib"
local programs: Programs = {
cCompiler = llvmOrgBinDir .. "/clang.exe",
cxxCompiler = llvmOrgBinDir .. "/clang++.exe",
make = binDir .. "/mingw32-make.exe",
debugger = binDir .. "/lldb-mi.exe",
debugServer = binDir .. "/lldb-server.exe",
resourceCompiler = binDir .. "/" .. foreignTriplet .. "-windres.exe",
binDirs = {llvmOrgBinDir},
libDirs = {libDir},
}
local release, _, _ = generateConfig(
function (arch: string, profile: string): string
return nameGeneratorClang(lang, arch, profile, false)
end,
programs,
{
arch = foreignArch,
customCompileParams = {
"-target", msvcTriplet,
"-fms-extensions",
"-fms-compatibility",
"-fdelayed-template-parsing",
},
customLinkParams = {
"-target", msvcTriplet,
},
isClang = true,
}
)
table.insert(compilerList, release)
end
end
table.insert(noSearch, llvmOrgBinDir)
end
if appArch == "x86_64" then
checkAndAddMingw("x86_64")
checkAndAddMingw("i386")
checkAndAddClang()
elseif appArch == "arm64" then
checkAndAddClang()
checkAndAddMingw("x86_64")
checkAndAddMingw("i386")
else
checkAndAddMingw("i386")
checkAndAddClang()
end
local result = {
compilerList = compilerList,
noSearch = noSearch,
preferCompiler = preferCompiler,
}
return result
end