Skip to content

Commit 5e9dd36

Browse files
committed
feat: support runtime, thread, and exception model on MinGW windows
1 parent 1e3ecc0 commit 5e9dd36

File tree

6 files changed

+83
-6
lines changed

6 files changed

+83
-6
lines changed

dist/legacy/setup-cpp.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/legacy/setup-cpp.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/modern/setup-cpp.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/modern/setup-cpp.mjs.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gcc/mingw.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { info } from "ci-log"
55
import { addEnv, addPath } from "envosman"
66
import { pathExists } from "path-exists"
77
import { addExeExt } from "patha"
8+
import semverCoerce from "semver/functions/coerce.js"
9+
import semverSatisfies from "semver/functions/satisfies.js"
810
import { installAptPack } from "setup-apt"
911
import { rcOptions } from "../cli-options.js"
1012
import { loadAssetList, matchAsset } from "../utils/asset/load-assets.js"
@@ -102,13 +104,45 @@ export async function getMinGWPackageInfo(
102104
ia32: "i386",
103105
} as Record<string, string | undefined>
104106

107+
// extract the base version by coercing the version
108+
const versionCoerce = semverCoerce(version)
109+
if (versionCoerce === null) {
110+
throw new Error(`Invalid MinGW version requested '${version}'`)
111+
}
112+
113+
const runtime = extractMinGWRuntime(version)
114+
const threadModel = extractMinGWThreadModel(version)
115+
const exceptionModel = extractMingwExceptionModel(version)
116+
105117
const asset = matchAsset(
106118
mingwAssets,
107119
{
108120
version,
109121
keywords: [
110122
mingwArchMap[arch] ?? arch,
111123
],
124+
filterName: (assetName) => {
125+
const assetRuntime = extractMinGWRuntime(assetName)
126+
const assetThreadModel = extractMinGWThreadModel(assetName)
127+
const assetExceptionModel = extractMingwExceptionModel(assetName)
128+
129+
return (runtime === undefined || runtime === assetRuntime)
130+
&& (threadModel === undefined || threadModel === assetThreadModel)
131+
&& (assetExceptionModel === undefined || assetExceptionModel === exceptionModel)
132+
},
133+
versionSatisfies: (assetVersion) => {
134+
// extract the base version by coercing the version
135+
const assetCoerce = semverCoerce(assetVersion)
136+
if (assetCoerce === null) {
137+
throw new Error(`Invalid MinGW asset version: '${assetVersion}'`)
138+
}
139+
140+
// if the asset version is satisfied by the version
141+
// and the runtime and thread model match or not specified
142+
return semverSatisfies(assetCoerce, `^${versionCoerce}`)
143+
&& (runtime === undefined || runtime === extractMinGWRuntime(assetVersion))
144+
&& (threadModel === undefined || threadModel === extractMinGWThreadModel(assetVersion))
145+
},
112146
},
113147
)
114148

@@ -125,6 +159,50 @@ export async function getMinGWPackageInfo(
125159
}
126160
}
127161

162+
/**
163+
* Extract the runtime used by the MinGW asset/version
164+
* @param input The input to extract the runtime from
165+
*
166+
* @example
167+
* extractMinGWRuntime("14.2.0posix-18.1.8-12.0.0-ucrt-r1") // "ucrt"
168+
* extractMinGWRuntime("10.5.0-11.0.1-msvcrt-r2") // "msvcrt"
169+
* extractMinGWRuntime("11.1.0-12.0.0-9.0.0-r1") // undefined
170+
*/
171+
function extractMinGWRuntime(input: string) {
172+
const match = input.match(/(ucrt|msvcrt)/)
173+
return match !== null ? match[1] : undefined
174+
}
175+
176+
/**
177+
* Extract the thread model used by the MinGW asset/version
178+
* @param input The input to extract the thread model from
179+
*
180+
* @example
181+
* extractMinGWThreadModel("14.2.0posix-18.1.8-12.0.0-ucrt-r1") // "posix"
182+
* extractMinGWThreadModel("14.2.0mcf-12.0.0-ucrt-r1") // "mcf"
183+
* extractMinGWThreadModel("10.5.0-11.0.1-msvcrt-r2") // undefined
184+
* extractMinGWThreadModel("11.1.0-12.0.0-9.0.0-r1") // undefined
185+
*/
186+
function extractMinGWThreadModel(input: string) {
187+
const match = input.match(/(posix|mcf)/)
188+
return match !== null ? match[1] : undefined
189+
}
190+
191+
/**
192+
* Extract the exception model used by the MinGW asset/version
193+
*
194+
* @param input The input to extract the exception model from
195+
*
196+
* @example
197+
* extractMingwExceptionModel("14.2.0posix-18.1.8-12.0.0-ucrt-r1") // "seh"
198+
* extractMingwExceptionModel("14.2.0mcf-12.0.0-ucrt-r1") // undefined
199+
* extractMingwExceptionModel("10.5.0-11.0.1-msvcrt-r2") // "dwarf"
200+
*/
201+
function extractMingwExceptionModel(input: string) {
202+
const match = input.match(/(seh|dwarf)/)
203+
return match !== null ? match[1] : undefined
204+
}
205+
128206
async function activateMinGW(binDir: string) {
129207
const promises: Promise<void>[] = []
130208

src/utils/asset/load-assets.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,11 @@ export type MatchAssetOpts = {
3838
/**
3939
* Custom version compare function
4040
* @param candidate The candidate version
41-
* @param version The version to compare against
4241
* @returns true if the candidate version satisfies the version
4342
*
4443
* @default semverSatisfies
4544
*/
46-
versionSatisfies?: (candidate: string, version: string) => boolean
45+
versionSatisfies?: (candidate: string) => boolean
4746
/**
4847
* Custom tag filter and map function
4948
* @param tag The tag to filter and map

0 commit comments

Comments
 (0)