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"
2022-06-30 00:06:35 +08:00
import { setupPacmanPack } from "../utils/setup/setupPacmanPack"
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-08-21 06:38:51 +08:00
import { join , addExeExt } from "patha"
2022-08-08 16:22:28 +08:00
import { warning , info } from "ci-log"
2022-08-08 09:48:41 +08:00
import ciDetect from "@npmcli/ci-detect"
2022-05-21 06:58:11 +08:00
import { InstallationInfo , PackageInfo , setupBin } from "../utils/setup/setupBin"
import { extract7Zip } from "../utils/setup/extract"
2022-06-30 10:06:33 +08:00
import { isArch } from "../utils/env/isArch"
2022-06-30 11:52:25 +08:00
import { isUbuntu } from "../utils/env/isUbuntu"
2022-07-11 07:34:56 +08:00
import { hasDnf } from "../utils/env/hasDnf"
import { setupDnfPack } from "../utils/setup/setupDnfPack"
2022-05-21 06:58:11 +08:00
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-11-21 08:25:37 +08:00
"12" : { releaseName : "12.2.0-14.0.6-10.0.0-ucrt-r2" , fileSuffix : "12.2.0-mingw-w64ucrt-10.0.0-r2" } ,
"12.2.0-ucrt" : { releaseName : "12.2.0-14.0.6-10.0.0-ucrt-r2" , fileSuffix : "12.2.0-mingw-w64ucrt-10.0.0-r2" } ,
"12.2.0-msvcrt" : { releaseName : "12.2.0-14.0.6-10.0.0-msvcrt-r2" , fileSuffix : "12.2.0-mingw-w64msvcrt-10.0.0-r2" } ,
2022-06-10 03:02:41 +08:00
"12.1.0-ucrt" : { releaseName : "12.1.0-14.0.4-10.0.0-ucrt-r2" , fileSuffix : "12.1.0-mingw-w64ucrt-10.0.0-r2" } ,
2022-08-09 02:50:49 +08:00
"12.1.0-msvcrt" : {
releaseName : "12.1.0-14.0.6-10.0.0-msvcrt-r3" ,
fileSuffix : "12.1.0-llvm-14.0.6-mingw-w64msvcrt-10.0.0-r3" ,
} ,
2022-05-21 07:28:35 +08:00
"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-08-21 06:38:51 +08:00
binFileName : addExeExt ( "g++" ) ,
2022-05-21 06:58:11 +08:00
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-11-21 13:26:31 +08:00
installationInfo = await 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-06-30 10:06:33 +08:00
if ( isArch ( ) ) {
2022-06-30 00:06:35 +08:00
installationInfo = setupPacmanPack ( "gcc" , version )
2022-07-11 07:34:56 +08:00
} else if ( hasDnf ( ) ) {
installationInfo = setupDnfPack ( "gcc" , version )
2022-07-11 09:57:45 +08:00
setupDnfPack ( "gcc-c++" , version )
setupDnfPack ( "libstdc++-devel" , undefined )
2022-07-11 08:39:21 +08:00
} else if ( isUbuntu ( ) ) {
2022-07-28 10:07:30 +08:00
await setupAptPack ( "gcc" , version , [ "ppa:ubuntu-toolchain-r/test" ] )
installationInfo = await setupAptPack ( "g++" , version , [ ] )
2022-06-30 00:06:35 +08:00
}
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-06-30 10:06:33 +08:00
if ( isArch ( ) ) {
2022-06-30 00:06:35 +08:00
setupPacmanPack ( "gcc-multilib" , version )
2022-07-11 08:39:21 +08:00
} else if ( isUbuntu ( ) ) {
2022-07-28 10:07:30 +08:00
await setupAptPack ( "gcc-multilib" , version , [ "ppa:ubuntu-toolchain-r/test" ] )
2022-06-30 00:06:35 +08:00
}
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-08-21 06:38:51 +08:00
promises . push ( addEnv ( "CC" , addExeExt ( ` ${ binDir } /gcc ` ) ) , addEnv ( "CXX" , addExeExt ( ` ${ 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
2022-06-30 11:52:25 +08:00
if ( isUbuntu ( ) ) {
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
2022-06-30 11:52:25 +08:00
if ( isUbuntu ( ) ) {
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
2022-08-08 10:13:40 +08:00
if ( ciDetect ( ) === "github-actions" ) {
2022-02-12 08:58:50 +08:00
addGccLoggingMatcher ( )
}
2022-05-13 09:39:47 +08:00
await Promise . all ( promises )
2022-02-12 08:58:50 +08:00
}
function addGccLoggingMatcher() {
2022-08-21 06:38:51 +08:00
const matcherPath = join ( __dirname , "gcc_matcher.json" )
2022-02-12 08:58:50 +08:00
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
}