@@ -10,39 +10,80 @@ import path from "path"
10
10
import { warning , info } from "../utils/io/io"
11
11
import { isGitHubCI } from "../utils/env/isci"
12
12
import { 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
+ }
13
58
14
59
// 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
17
62
switch ( process . platform ) {
18
63
case "win32" : {
19
64
if ( arch === "arm" || arch === "arm64" ) {
20
65
await setupChocoPack ( "gcc-arm-embedded" , version )
21
66
}
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 )
31
72
}
32
73
break
33
74
}
34
75
case "darwin" : {
35
- binDir = setupBrewPack ( "gcc" , version ) . binDir
76
+ installationInfo = setupBrewPack ( "gcc" , version )
36
77
break
37
78
}
38
79
case "linux" : {
39
80
if ( arch === "x64" ) {
40
81
setupAptPack ( "gcc" , version , [ "ppa:ubuntu-toolchain-r/test" ] )
41
- binDir = setupAptPack ( "g++" , version , [ ] ) . binDir
82
+ installationInfo = setupAptPack ( "g++" , version , [ ] )
42
83
} else {
43
84
info ( `Install g++-multilib because gcc for ${ arch } was requested` )
44
85
setupAptPack ( "gcc-multilib" , version , [ "ppa:ubuntu-toolchain-r/test" ] )
45
- binDir = setupAptPack ( "g++-multilib" , version , [ ] ) . binDir
86
+ installationInfo = setupAptPack ( "g++-multilib" , version , [ ] )
46
87
}
47
88
break
48
89
}
@@ -61,8 +102,26 @@ export async function setupGcc(version: string, _setupDir: string, arch: string)
61
102
throw new Error ( `Unsupported platform for ${ arch } ` )
62
103
}
63
104
}
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
+ }
64
124
if ( binDir !== undefined ) {
65
- await activateGcc ( version , binDir )
66
125
return { binDir }
67
126
}
68
127
return undefined
0 commit comments