2022-03-12 09:32:28 +08:00
import { addPath , addEnv } from "../utils/env/addEnv"
2021-09-17 04:13:55 +08:00
import { existsSync } from "fs"
2022-04-19 14:34:18 +08:00
import { setupAptPack , updateAptAlternatives } from "../utils/setup/setupAptPack"
2021-09-16 22:03:54 +08:00
import { setupBrewPack } from "../utils/setup/setupBrewPack"
import { setupChocoPack } from "../utils/setup/setupChocoPack"
2021-09-17 05:47:49 +08:00
import semverMajor from "semver/functions/major"
2021-09-17 07:02:18 +08:00
import semverCoerce from "semver/functions/coerce"
2021-11-22 01:06:16 +08:00
import { setupMacOSSDK } from "../macos-sdk/macos-sdk"
2022-02-12 08:58:50 +08:00
import path from "path"
2022-05-21 07:28:35 +08:00
import { warning , info } from "../utils/io/io"
2022-02-12 08:58:50 +08:00
import { isGitHubCI } from "../utils/env/isci"
2022-05-13 09:42:49 +08:00
import { addBinExtension } from "../utils/extension/extension"
2022-05-21 06:58:11 +08:00
import { InstallationInfo , PackageInfo , setupBin } from "../utils/setup/setupBin"
import { extract7Zip } from "../utils/setup/extract"
interface MingwInfo {
2022-05-21 07:28:35 +08:00
releaseName : string
fileSuffix : string
2022-05-21 06:58:11 +08:00
}
2022-05-21 07:28:35 +08:00
// https://github.com/brechtsanders/winlibs_mingw/releases
2022-05-21 06:58:11 +08:00
const GccToMingwInfo = {
2022-05-21 07:28:35 +08:00
"12" : { releaseName : "12.1.0-10.0.0-msvcrt-r1" , fileSuffix : "12.1.0-mingw-w64msvcrt-10.0.0-r1" } ,
"12.1.0-msvcrt" : { releaseName : "12.1.0-10.0.0-msvcrt-r1" , fileSuffix : "12.1.0-mingw-w64msvcrt-10.0.0-r1" } ,
"11" : { releaseName : "11.3.0-14.0.3-10.0.0-ucrt-r3" , fileSuffix : "11.3.0-mingw-w64ucrt-10.0.0-r3" } ,
"11.3.0-ucrt" : { releaseName : "11.3.0-14.0.3-10.0.0-ucrt-r3" , fileSuffix : "11.3.0-mingw-w64ucrt-10.0.0-r3" } ,
"11.3.0-msvcrt" : { releaseName : "11.3.0-14.0.3-10.0.0-msvcrt-r3" , fileSuffix : "11.3.0-mingw-w64msvcrt-10.0.0-r3" } ,
"11.2.0-ucrt" : { releaseName : "11.2.0-9.0.0-ucrt-r5" , fileSuffix : "11.2.0-mingw-w64ucrt-9.0.0-r5" } ,
"11.2.0-msvcrt" : { releaseName : "11.2.0-9.0.0-msvcrt-r5" , fileSuffix : "11.2.0-mingw-w64msvcrt-9.0.0-r5" } ,
"10" : { releaseName : "10.3.0-12.0.0-9.0.0-r2" , fileSuffix : "10.3.0-llvm-12.0.0-mingw-w64-9.0.0-r2" } ,
"10.3.0" : { releaseName : "10.3.0-12.0.0-9.0.0-r2" , fileSuffix : "10.3.0-llvm-12.0.0-mingw-w64-9.0.0-r2" } ,
"10.2.0" : { releaseName : "10.2.0-7.0.0-r4" , fileSuffix : "10.2.0-llvm-10.0.1-mingw-w64-7.0.0-r4" } ,
"9" : { releaseName : "9.4.0-9.0.0-r1" , fileSuffix : "9.4.0-mingw-w64-9.0.0-r1" } ,
"9.4.0" : { releaseName : "9.4.0-9.0.0-r1" , fileSuffix : "9.4.0-mingw-w64-9.0.0-r1" } ,
2022-05-21 06:58:11 +08:00
} as Record < string , MingwInfo | undefined >
function getGccPackageInfo ( version : string , platform : NodeJS.Platform , arch : string ) : PackageInfo {
switch ( platform ) {
case "win32" : {
const mingwInfo = GccToMingwInfo [ version ]
if ( mingwInfo === undefined ) {
throw new Error ( ` mingw version ${ version } is not supported ` )
}
const mingwArch = arch === "ia32" ? "i686" : "x86_64"
2022-05-21 07:28:35 +08:00
const exceptionModel : "seh" | "dwarf" = "seh" // SEH is native windows exception model https://github.com/brechtsanders/winlibs_mingw/issues/4#issuecomment-599296483
2022-05-21 06:58:11 +08:00
return {
2022-05-21 08:07:25 +08:00
binRelativeDir : "bin/" ,
2022-05-21 06:58:11 +08:00
binFileName : addBinExtension ( "g++" ) ,
extractedFolderName : "mingw64" ,
extractFunction : extract7Zip ,
2022-05-21 07:28:35 +08:00
url : ` https://github.com/brechtsanders/winlibs_mingw/releases/download/ ${ mingwInfo . releaseName } /winlibs- ${ mingwArch } -posix- ${ exceptionModel } -gcc- ${ mingwInfo . fileSuffix } .7z ` ,
2022-05-21 06:58:11 +08:00
}
}
default :
throw new Error ( ` Unsupported platform ' ${ platform } ' ` )
}
}
2021-09-16 22:03:54 +08:00
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2022-05-21 06:58:11 +08:00
export async function setupGcc ( version : string , setupDir : string , arch : string ) {
let installationInfo : InstallationInfo | undefined
2021-09-16 22:03:54 +08:00
switch ( process . platform ) {
case "win32" : {
if ( arch === "arm" || arch === "arm64" ) {
2021-09-16 22:19:56 +08:00
await setupChocoPack ( "gcc-arm-embedded" , version )
2021-09-16 22:03:54 +08:00
}
2022-05-21 06:58:11 +08:00
try {
installationInfo = await setupBin ( "g++" , version , getGccPackageInfo , setupDir , arch )
} catch ( err ) {
2022-05-21 07:28:35 +08:00
info ( ` Failed to download g++ binary. ${ err } . Falling back to chocolatey. ` )
2022-05-21 06:58:11 +08:00
installationInfo = await setupChocoMingw ( version , arch )
}
2021-09-17 05:47:49 +08:00
break
2021-09-16 22:03:54 +08:00
}
case "darwin" : {
2022-05-21 06:58:11 +08:00
installationInfo = setupBrewPack ( "gcc" , version )
2021-09-17 05:47:49 +08:00
break
2021-09-16 22:03:54 +08:00
}
case "linux" : {
if ( arch === "x64" ) {
2022-05-03 13:12:53 +08:00
setupAptPack ( "gcc" , version , [ "ppa:ubuntu-toolchain-r/test" ] )
2022-05-21 06:58:11 +08:00
installationInfo = setupAptPack ( "g++" , version , [ ] )
2021-09-17 06:00:14 +08:00
} else {
2021-09-17 06:17:32 +08:00
info ( ` Install g++-multilib because gcc for ${ arch } was requested ` )
2022-05-03 13:12:53 +08:00
setupAptPack ( "gcc-multilib" , version , [ "ppa:ubuntu-toolchain-r/test" ] )
2022-05-21 06:58:11 +08:00
installationInfo = setupAptPack ( "g++-multilib" , version , [ ] )
2021-09-16 22:03:54 +08:00
}
2021-09-17 05:47:49 +08:00
break
2021-09-16 22:03:54 +08:00
}
2021-12-07 16:53:22 +08:00
// TODO support bare-metal (need to support passing it as the input)
2021-09-16 22:03:54 +08:00
// TODO support abi
// case "none": {
// if (arch === "arm" || arch === "arm64") {
2021-12-07 16:53:22 +08:00
// return setupAptPack("gcc-arm-none-eabi", version, [
2021-12-07 20:16:31 +08:00
// "ppa:ubuntu-toolchain-r/test",
2021-12-07 16:53:22 +08:00
// ])
2021-09-16 22:03:54 +08:00
// } else {
// throw new Error(`Unsupported platform for ${arch}`)
// }
// }
default : {
throw new Error ( ` Unsupported platform for ${ arch } ` )
}
}
2022-05-21 06:58:11 +08:00
if ( installationInfo !== undefined ) {
await activateGcc ( version , installationInfo . binDir )
return installationInfo
2021-09-17 05:47:49 +08:00
}
return undefined
2021-09-16 22:03:54 +08:00
}
2021-09-20 20:25:41 +08:00
2022-05-21 06:58:11 +08:00
async function setupChocoMingw ( version : string , arch : string ) : Promise < InstallationInfo | undefined > {
2022-05-21 06:19:19 +08:00
await setupChocoPack ( "mingw" , version )
let binDir : string | undefined
if ( arch === "x64" && existsSync ( "C:/tools/mingw64/bin" ) ) {
binDir = "C:/tools/mingw64/bin"
await addPath ( binDir )
} else if ( arch === "ia32" && existsSync ( "C:/tools/mingw32/bin" ) ) {
binDir = "C:/tools/mingw32/bin"
await addPath ( binDir )
} else if ( existsSync ( ` ${ process . env . ChocolateyInstall ? ? "C:/ProgramData/chocolatey" } /bin/g++.exe ` ) ) {
binDir = ` ${ process . env . ChocolateyInstall ? ? "C:/ProgramData/chocolatey" } /bin `
}
2022-05-21 06:58:11 +08:00
if ( binDir !== undefined ) {
return { binDir }
}
return undefined
2022-05-21 06:19:19 +08:00
}
2021-11-22 01:06:16 +08:00
async function activateGcc ( version : string , binDir : string ) {
2022-05-13 09:39:47 +08:00
const promises : Promise < void > [ ] = [ ]
// Setup gcc as the compiler
2021-09-20 20:25:41 +08:00
// TODO
// const ld = process.env.LD_LIBRARY_PATH ?? ""
// const dyld = process.env.DYLD_LIBRARY_PATH ?? ""
2022-05-13 09:39:47 +08:00
// promises.push(
// addEnv("LD_LIBRARY_PATH", `${installDir}/lib${path.delimiter}${ld}`),
// addEnv("DYLD_LIBRARY_PATH", `${installDir}/lib${path.delimiter}${dyld}`),
// addEnv("CPATH", `${installDir}/lib/gcc/${majorVersion}/include`),
// addEnv("LDFLAGS", `-L${installDir}/lib`),
// addEnv("CPPFLAGS", `-I${installDir}/include`)
// )
2021-09-20 20:25:41 +08:00
if ( process . platform === "win32" ) {
2022-05-13 09:42:49 +08:00
promises . push ( addEnv ( "CC" , addBinExtension ( ` ${ binDir } /gcc ` ) ) , addEnv ( "CXX" , addBinExtension ( ` ${ binDir } /g++ ` ) ) )
2021-09-20 20:25:41 +08:00
} else {
2021-12-07 20:16:31 +08:00
const majorVersion = semverMajor ( semverCoerce ( version ) ? ? version )
if ( majorVersion >= 5 ) {
2022-05-13 09:39:47 +08:00
promises . push ( addEnv ( "CC" , ` ${ binDir } /gcc- ${ majorVersion } ` ) , addEnv ( "CXX" , ` ${ binDir } /g++- ${ majorVersion } ` ) )
2022-04-19 14:34:18 +08:00
if ( process . platform === "linux" ) {
2022-05-13 09:39:47 +08:00
updateAptAlternatives ( "cc" , ` ${ binDir } /gcc- ${ majorVersion } ` )
updateAptAlternatives ( "cxx" , ` ${ binDir } /g++- ${ majorVersion } ` )
updateAptAlternatives ( "gcc" , ` ${ binDir } /gcc- ${ majorVersion } ` )
updateAptAlternatives ( "g++" , ` ${ binDir } /g++- ${ majorVersion } ` )
2022-04-19 14:34:18 +08:00
}
2021-12-07 20:16:31 +08:00
} else {
2022-05-13 09:39:47 +08:00
promises . push ( addEnv ( "CC" , ` ${ binDir } /gcc- ${ version } ` ) , addEnv ( "CXX" , ` ${ binDir } /g++- ${ version } ` ) )
2022-04-19 14:34:18 +08:00
if ( process . platform === "linux" ) {
2022-05-13 09:39:47 +08:00
updateAptAlternatives ( "cc" , ` ${ binDir } /gcc- ${ version } ` )
updateAptAlternatives ( "cxx" , ` ${ binDir } /g++- ${ version } ` )
updateAptAlternatives ( "gcc" , ` ${ binDir } /gcc- ${ version } ` )
updateAptAlternatives ( "g++" , ` ${ binDir } /g++- ${ version } ` )
2022-04-19 14:34:18 +08:00
}
2021-12-07 20:16:31 +08:00
}
2021-09-20 20:25:41 +08:00
}
2021-11-22 01:06:16 +08:00
2022-05-13 09:39:47 +08:00
promises . push ( setupMacOSSDK ( ) )
2022-02-12 08:58:50 +08:00
if ( isGitHubCI ( ) ) {
addGccLoggingMatcher ( )
}
2022-05-13 09:39:47 +08:00
await Promise . all ( promises )
2022-02-12 08:58:50 +08:00
}
function addGccLoggingMatcher() {
const matcherPath = path . join ( __dirname , "gcc_matcher.json" )
if ( ! existsSync ( matcherPath ) ) {
return warning ( "the gcc_matcher.json file does not exist in the same folder as setup_cpp.js" )
}
info ( ` ::add-matcher:: ${ matcherPath } ` )
2021-09-20 20:25:41 +08:00
}