@@ -10,39 +10,80 @@ import path from "path"
1010import { warning , info } from "../utils/io/io"
1111import { isGitHubCI } from "../utils/env/isci"
1212import { addBinExtension } from "../utils/extension/extension"
13+ import { InstallationInfo , PackageInfo , setupBin } from "../utils/setup/setupBin"
14+ import { extract7Zip } from "../utils/setup/extract"
15+
16+ interface MingwInfo {
17+ releaseName : string
18+ fileSuffix : string
19+ }
20+
21+ // https://github.com/brechtsanders/winlibs_mingw/releases
22+ const GccToMingwInfo = {
23+ "12" : { releaseName : "12.1.0-10.0.0-msvcrt-r1" , fileSuffix : "12.1.0-mingw-w64msvcrt-10.0.0-r1" } ,
24+ "12.1.0-msvcrt" : { releaseName : "12.1.0-10.0.0-msvcrt-r1" , fileSuffix : "12.1.0-mingw-w64msvcrt-10.0.0-r1" } ,
25+ "11" : { releaseName : "11.3.0-14.0.3-10.0.0-ucrt-r3" , fileSuffix : "11.3.0-mingw-w64ucrt-10.0.0-r3" } ,
26+ "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" } ,
27+ "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" } ,
28+ "11.2.0-ucrt" : { releaseName : "11.2.0-9.0.0-ucrt-r5" , fileSuffix : "11.2.0-mingw-w64ucrt-9.0.0-r5" } ,
29+ "11.2.0-msvcrt" : { releaseName : "11.2.0-9.0.0-msvcrt-r5" , fileSuffix : "11.2.0-mingw-w64msvcrt-9.0.0-r5" } ,
30+ "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" } ,
31+ "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" } ,
32+ "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" } ,
33+ "9" : { releaseName : "9.4.0-9.0.0-r1" , fileSuffix : "9.4.0-mingw-w64-9.0.0-r1" } ,
34+ "9.4.0" : { releaseName : "9.4.0-9.0.0-r1" , fileSuffix : "9.4.0-mingw-w64-9.0.0-r1" } ,
35+ } as Record < string , MingwInfo | undefined >
36+
37+ function getGccPackageInfo ( version : string , platform : NodeJS . Platform , arch : string ) : PackageInfo {
38+ switch ( platform ) {
39+ case "win32" : {
40+ const mingwInfo = GccToMingwInfo [ version ]
41+ if ( mingwInfo === undefined ) {
42+ throw new Error ( `mingw version ${ version } is not supported` )
43+ }
44+ const mingwArch = arch === "ia32" ? "i686" : "x86_64"
45+ const exceptionModel : "seh" | "dwarf" = "seh" // SEH is native windows exception model https://github.com/brechtsanders/winlibs_mingw/issues/4#issuecomment-599296483
46+ return {
47+ binRelativeDir : "bin/" ,
48+ binFileName : addBinExtension ( "g++" ) ,
49+ extractedFolderName : "mingw64" ,
50+ extractFunction : extract7Zip ,
51+ url : `https://github.com/brechtsanders/winlibs_mingw/releases/download/${ mingwInfo . releaseName } /winlibs-${ mingwArch } -posix-${ exceptionModel } -gcc-${ mingwInfo . fileSuffix } .7z` ,
52+ }
53+ }
54+ default :
55+ throw new Error ( `Unsupported platform '${ platform } '` )
56+ }
57+ }
1358
1459// eslint-disable-next-line @typescript-eslint/no-unused-vars
15- export async function setupGcc ( version : string , _setupDir : string , arch : string ) {
16- let binDir : string | undefined
60+ export async function setupGcc ( version : string , setupDir : string , arch : string ) {
61+ let installationInfo : InstallationInfo | undefined
1762 switch ( process . platform ) {
1863 case "win32" : {
1964 if ( arch === "arm" || arch === "arm64" ) {
2065 await setupChocoPack ( "gcc-arm-embedded" , version )
2166 }
22- await setupChocoPack ( "mingw" , version )
23- if ( arch === "x64" && existsSync ( "C:/tools/mingw64/bin" ) ) {
24- binDir = "C:/tools/mingw64/bin"
25- await addPath ( binDir )
26- } else if ( arch === "ia32" && existsSync ( "C:/tools/mingw32/bin" ) ) {
27- binDir = "C:/tools/mingw32/bin"
28- await addPath ( binDir )
29- } else if ( existsSync ( `${ process . env . ChocolateyInstall ?? "C:/ProgramData/chocolatey" } /bin/g++.exe` ) ) {
30- binDir = `${ process . env . ChocolateyInstall ?? "C:/ProgramData/chocolatey" } /bin`
67+ try {
68+ installationInfo = await setupBin ( "g++" , version , getGccPackageInfo , setupDir , arch )
69+ } catch ( err ) {
70+ info ( `Failed to download g++ binary. ${ err } . Falling back to chocolatey.` )
71+ installationInfo = await setupChocoMingw ( version , arch )
3172 }
3273 break
3374 }
3475 case "darwin" : {
35- binDir = setupBrewPack ( "gcc" , version ) . binDir
76+ installationInfo = setupBrewPack ( "gcc" , version )
3677 break
3778 }
3879 case "linux" : {
3980 if ( arch === "x64" ) {
4081 setupAptPack ( "gcc" , version , [ "ppa:ubuntu-toolchain-r/test" ] )
41- binDir = setupAptPack ( "g++" , version , [ ] ) . binDir
82+ installationInfo = setupAptPack ( "g++" , version , [ ] )
4283 } else {
4384 info ( `Install g++-multilib because gcc for ${ arch } was requested` )
4485 setupAptPack ( "gcc-multilib" , version , [ "ppa:ubuntu-toolchain-r/test" ] )
45- binDir = setupAptPack ( "g++-multilib" , version , [ ] ) . binDir
86+ installationInfo = setupAptPack ( "g++-multilib" , version , [ ] )
4687 }
4788 break
4889 }
@@ -61,8 +102,26 @@ export async function setupGcc(version: string, _setupDir: string, arch: string)
61102 throw new Error ( `Unsupported platform for ${ arch } ` )
62103 }
63104 }
105+ if ( installationInfo !== undefined ) {
106+ await activateGcc ( version , installationInfo . binDir )
107+ return installationInfo
108+ }
109+ return undefined
110+ }
111+
112+ async function setupChocoMingw ( version : string , arch : string ) : Promise < InstallationInfo | undefined > {
113+ await setupChocoPack ( "mingw" , version )
114+ let binDir : string | undefined
115+ if ( arch === "x64" && existsSync ( "C:/tools/mingw64/bin" ) ) {
116+ binDir = "C:/tools/mingw64/bin"
117+ await addPath ( binDir )
118+ } else if ( arch === "ia32" && existsSync ( "C:/tools/mingw32/bin" ) ) {
119+ binDir = "C:/tools/mingw32/bin"
120+ await addPath ( binDir )
121+ } else if ( existsSync ( `${ process . env . ChocolateyInstall ?? "C:/ProgramData/chocolatey" } /bin/g++.exe` ) ) {
122+ binDir = `${ process . env . ChocolateyInstall ?? "C:/ProgramData/chocolatey" } /bin`
123+ }
64124 if ( binDir !== undefined ) {
65- await activateGcc ( version , binDir )
66125 return { binDir }
67126 }
68127 return undefined
0 commit comments