Merge pull request #277 from aminya/mingw [skip ci]

This commit is contained in:
Amin Yahyaabadi 2024-09-03 15:11:21 -07:00 committed by GitHub
commit b923ad9bbd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 551 additions and 143 deletions

View File

@ -9,7 +9,8 @@
"**/.venv/",
"**/.*cache/",
"coverage/",
"**/coverage/"
"**/coverage/",
"**/github_brechtsanders_winlibs_mingw.json"
],
"ignoreUnknown": true
},

View File

@ -11,6 +11,7 @@ ignorePaths:
- "**/node_modules/"
- .vscode/extensions.json
- patches/*.patch
- "**/github_brechtsanders_winlibs_mingw.json"
words:
- aarch
- aminya

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -37,6 +37,7 @@
"./.cache/",
"**/build",
"**/dist",
"**/github_brechtsanders_winlibs_mingw.json",
"dev/cpp_vcpkg_project"
],
"plugins": [

View File

@ -33,9 +33,7 @@
"build.modern": "shx cp -r ./dist/actions/* ./dist/modern",
"bump": "ncu -u -x numerous,execa,prettier,@types/node,eslint,@types/eslint && pnpm update && pnpx typesync && pnpm run clean",
"clean": "shx rm -rf ./dist ./packages/*/dist ./exe ./.parcel-cache && shx mkdir -p ./dist/legacy ./dist/actions ./dist/modern ",
"copy.matchers": "run-p copy.matchers.legacy copy.matchers.actions",
"copy.matchers.legacy": "shx cp ./src/gcc/gcc_matcher.json ./dist/legacy/ && shx cp ./src/msvc/msvc_matcher.json ./dist/legacy/ && shx cp ./src/python/python_matcher.json ./dist/legacy/ && shx cp ./src/llvm/llvm_matcher.json ./dist/legacy/",
"copy.matchers.actions": "shx cp ./src/gcc/gcc_matcher.json ./dist/actions/ && shx cp ./src/msvc/msvc_matcher.json ./dist/actions/ && shx cp ./src/python/python_matcher.json ./dist/actions/ && shx cp ./src/llvm/llvm_matcher.json ./dist/actions/",
"copy.matchers": "shx cp ./src/*/*.json ./dist/legacy/ && shx cp ./dist/legacy/*.json ./dist/actions",
"dev.parcel": "cross-env NODE_ENV=development parcel watch",
"dev.packages": "turbo dev",
"dev": "run-p dev.packages dev.parcel",
@ -67,6 +65,12 @@
"@babel/plugin-transform-private-methods": "^7.25.4",
"@biomejs/biome": "^1.8.3",
"@iarna/toml": "^2.2.5",
"@octokit/core": "^6.1.2",
"@octokit/openapi-types": "^22.2.0",
"@octokit/plugin-paginate-rest": "^11.3.3",
"@octokit/plugin-rest-endpoint-methods": "^13.2.4",
"@octokit/rest": "^21.0.2",
"@octokit/types": "^13.5.0",
"@shockpkg/archive-files": "github:aminya/archive-files#54ec59fad46aca736ac6feb6c7bb526528141b9d",
"@swc/jest": "^0.2.36",
"@types/cross-spawn": "^6.0.6",
@ -115,6 +119,7 @@
"prettier-config-atomic": "^4.0.0",
"readme-md-generator": "^1.0.0",
"retry-as-promised": "^7.0.4",
"safe-stable-stringify": "^2.5.0",
"semver": "7.6.3",
"setup-apt": "workspace:*",
"setup-brew": "workspace:*",

View File

@ -1,11 +1,11 @@
import { join } from "path"
import { info } from "ci-log"
/* eslint-disable require-atomic-updates */
import { execaSync } from "execa"
import which from "which"
import type { InstallationInfo } from "./InstallationInfo.js"
import { getBrewBinDir, setupBrew } from "./install.js"
/* eslint-disable require-atomic-updates */
let hasBrew = false
export type BrewPackOptions = {

View File

@ -40,6 +40,24 @@ importers:
'@iarna/toml':
specifier: ^2.2.5
version: 2.2.5
'@octokit/core':
specifier: ^6.1.2
version: 6.1.2
'@octokit/openapi-types':
specifier: ^22.2.0
version: 22.2.0
'@octokit/plugin-paginate-rest':
specifier: ^11.3.3
version: 11.3.3(@octokit/core@6.1.2)
'@octokit/plugin-rest-endpoint-methods':
specifier: ^13.2.4
version: 13.2.4(@octokit/core@6.1.2)
'@octokit/rest':
specifier: ^21.0.2
version: 21.0.2
'@octokit/types':
specifier: ^13.5.0
version: 13.5.0
'@shockpkg/archive-files':
specifier: github:aminya/archive-files#54ec59fad46aca736ac6feb6c7bb526528141b9d
version: https://codeload.github.com/aminya/archive-files/tar.gz/54ec59fad46aca736ac6feb6c7bb526528141b9d
@ -184,6 +202,9 @@ importers:
retry-as-promised:
specifier: ^7.0.4
version: 7.0.4
safe-stable-stringify:
specifier: ^2.5.0
version: 2.5.0
semver:
specifier: 7.6.3
version: 7.6.3
@ -1227,6 +1248,58 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@octokit/auth-token@5.1.1':
resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==}
engines: {node: '>= 18'}
'@octokit/core@6.1.2':
resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==}
engines: {node: '>= 18'}
'@octokit/endpoint@10.1.1':
resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==}
engines: {node: '>= 18'}
'@octokit/graphql@8.1.1':
resolution: {integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==}
engines: {node: '>= 18'}
'@octokit/openapi-types@22.2.0':
resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==}
'@octokit/plugin-paginate-rest@11.3.3':
resolution: {integrity: sha512-o4WRoOJZlKqEEgj+i9CpcmnByvtzoUYC6I8PD2SA95M+BJ2x8h7oLcVOg9qcowWXBOdcTRsMZiwvM3EyLm9AfA==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=6'
'@octokit/plugin-request-log@5.3.1':
resolution: {integrity: sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=6'
'@octokit/plugin-rest-endpoint-methods@13.2.4':
resolution: {integrity: sha512-gusyAVgTrPiuXOdfqOySMDztQHv6928PQ3E4dqVGEtOvRXAKRbJR4b1zQyniIT9waqaWk/UDaoJ2dyPr7Bk7Iw==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=6'
'@octokit/request-error@6.1.4':
resolution: {integrity: sha512-VpAhIUxwhWZQImo/dWAN/NpPqqojR6PSLgLYAituLM6U+ddx9hCioFGwBr5Mi+oi5CLeJkcAs3gJ0PYYzU6wUg==}
engines: {node: '>= 18'}
'@octokit/request@9.1.3':
resolution: {integrity: sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==}
engines: {node: '>= 18'}
'@octokit/rest@21.0.2':
resolution: {integrity: sha512-+CiLisCoyWmYicH25y1cDfCrv41kRSvTq6pPWtRroRJzhsCZWZyCqGyI8foJT5LmScADSwRAnr/xo+eewL04wQ==}
engines: {node: '>= 18'}
'@octokit/types@13.5.0':
resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==}
'@parcel/bundler-default@2.12.0':
resolution: {integrity: sha512-3ybN74oYNMKyjD6V20c9Gerdbh7teeNvVMwIoHIQMzuIFT6IGX53PyOLlOKRLbjxMc0TMimQQxIt2eQqxR5LsA==}
engines: {node: '>= 12.0.0', parcel: ^2.12.0}
@ -2122,6 +2195,9 @@ packages:
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
before-after-hook@3.0.2:
resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==}
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
@ -4800,6 +4876,10 @@ packages:
resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==}
engines: {node: '>= 0.4'}
safe-stable-stringify@2.5.0:
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
engines: {node: '>=10'}
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
@ -5300,6 +5380,9 @@ packages:
unist-util-stringify-position@4.0.0:
resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
universal-user-agent@7.0.2:
resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==}
universalify@2.0.1:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
@ -6509,6 +6592,67 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.17.1
'@octokit/auth-token@5.1.1': {}
'@octokit/core@6.1.2':
dependencies:
'@octokit/auth-token': 5.1.1
'@octokit/graphql': 8.1.1
'@octokit/request': 9.1.3
'@octokit/request-error': 6.1.4
'@octokit/types': 13.5.0
before-after-hook: 3.0.2
universal-user-agent: 7.0.2
'@octokit/endpoint@10.1.1':
dependencies:
'@octokit/types': 13.5.0
universal-user-agent: 7.0.2
'@octokit/graphql@8.1.1':
dependencies:
'@octokit/request': 9.1.3
'@octokit/types': 13.5.0
universal-user-agent: 7.0.2
'@octokit/openapi-types@22.2.0': {}
'@octokit/plugin-paginate-rest@11.3.3(@octokit/core@6.1.2)':
dependencies:
'@octokit/core': 6.1.2
'@octokit/types': 13.5.0
'@octokit/plugin-request-log@5.3.1(@octokit/core@6.1.2)':
dependencies:
'@octokit/core': 6.1.2
'@octokit/plugin-rest-endpoint-methods@13.2.4(@octokit/core@6.1.2)':
dependencies:
'@octokit/core': 6.1.2
'@octokit/types': 13.5.0
'@octokit/request-error@6.1.4':
dependencies:
'@octokit/types': 13.5.0
'@octokit/request@9.1.3':
dependencies:
'@octokit/endpoint': 10.1.1
'@octokit/request-error': 6.1.4
'@octokit/types': 13.5.0
universal-user-agent: 7.0.2
'@octokit/rest@21.0.2':
dependencies:
'@octokit/core': 6.1.2
'@octokit/plugin-paginate-rest': 11.3.3(@octokit/core@6.1.2)
'@octokit/plugin-request-log': 5.3.1(@octokit/core@6.1.2)
'@octokit/plugin-rest-endpoint-methods': 13.2.4(@octokit/core@6.1.2)
'@octokit/types@13.5.0':
dependencies:
'@octokit/openapi-types': 22.2.0
'@parcel/bundler-default@2.12.0(@parcel/core@2.12.0(@swc/helpers@0.5.13))(@swc/helpers@0.5.13)':
dependencies:
'@parcel/diagnostic': 2.12.0
@ -7852,6 +7996,8 @@ snapshots:
base64-js@1.5.1: {}
before-after-hook@3.0.2: {}
binary-extensions@2.3.0:
optional: true
@ -11119,6 +11265,8 @@ snapshots:
es-errors: 1.3.0
is-regex: 1.1.4
safe-stable-stringify@2.5.0: {}
safer-buffer@2.1.2: {}
sax@1.4.1: {}
@ -11652,6 +11800,8 @@ snapshots:
dependencies:
'@types/unist': 3.0.3
universal-user-agent@7.0.2: {}
universalify@2.0.1: {}
update-browserslist-db@1.1.0(browserslist@4.23.3):

View File

@ -1,6 +1,7 @@
import { execaSync } from "execa"
import { chmod } from "fs/promises"
import { addExeExt, join } from "patha"
import { isUbuntu } from "../../utils/env/isUbuntu.js"
import { ubuntuVersion } from "../../utils/env/ubuntu_version.js"
import { cleanupTmpDir, setupTmpDir, testBin } from "../../utils/tests/test-helpers.js"
import { getVersion } from "../../versions/versions.js"
@ -14,13 +15,40 @@ describe("setup-gcc", () => {
})
it("should setup gcc", async () => {
const version = getVersion("gcc", undefined, await ubuntuVersion())
const ubuntuVersionOutput = await ubuntuVersion()
const version = getVersion("gcc", undefined, ubuntuVersionOutput)
const installInfo = await setupGcc(version, directory, process.arch)
let gpp = "g++"
if (process.platform !== "win32") {
gpp = `g++-${version}`
if (isUbuntu()) {
const ubuntuMajorVersion = ubuntuVersionOutput?.[0]
// https://packages.ubuntu.com/search?keywords=gcc
switch (ubuntuMajorVersion) {
case 26:
case 25:
gpp = "g++-14"
break
case 24:
case 23:
gpp = "g++-13"
break
case 22:
case 21:
gpp = "g++-11"
break
case 20:
gpp = "g++-9"
break
default: {
// ignore
}
}
} else if (process.platform === "darwin") {
// https://formulae.brew.sh/formula/gcc
// As of 3, Sep, 2024
gpp = "g++-14"
}
await testBin(gpp, ["--version"], installInfo?.binDir)
expect(process.env.CC?.includes("gcc")).toBeTruthy()

14
src/gcc/assets-list.ts Normal file
View File

@ -0,0 +1,14 @@
import { saveGitHubAssetList } from "../utils/github/fetch-assets.ts"
/**
* Generate the list of all releases of a GitHub repository and save it to a json file
*/
async function main() {
// https://github.com/brechtsanders/winlibs_mingw/releases
await saveGitHubAssetList("brechtsanders", "winlibs_mingw", "./src/gcc/github_brechtsanders_winlibs_mingw.json")
}
main().catch((err) => {
console.error(err)
process.exit(1)
})

View File

@ -1,8 +1,9 @@
import { addEnv, addPath } from "envosman"
import { GITHUB_ACTIONS } from "ci-info"
import { info, warning } from "ci-log"
import type { ExecaReturnValue } from "execa"
import { error, info, warning } from "ci-log"
import { type ExecaReturnValue, execa } from "execa"
import { readdir } from "fs/promises"
import { pathExists } from "path-exists"
import { addExeExt, join } from "patha"
import semverCoerce from "semver/functions/coerce"
@ -14,64 +15,39 @@ import { setupMacOSSDK } from "../macos-sdk/macos-sdk.js"
import { hasDnf } from "../utils/env/hasDnf.js"
import { isArch } from "../utils/env/isArch.js"
import { isUbuntu } from "../utils/env/isUbuntu.js"
import { loadGitHubAssetList, matchAsset } from "../utils/github/load-assets.js"
import { extract7Zip } from "../utils/setup/extract.js"
import { type InstallationInfo, type PackageInfo, setupBin } from "../utils/setup/setupBin.js"
import { setupChocoPack } from "../utils/setup/setupChocoPack.js"
import { setupDnfPack } from "../utils/setup/setupDnfPack.js"
import { setupPacmanPack } from "../utils/setup/setupPacmanPack.js"
import { compareVersion } from "../utils/setup/version.js"
interface MingwInfo {
releaseName: string
fileSuffix: string
}
// https://github.com/brechtsanders/winlibs_mingw/releases
const GccToMingwInfo = {
"13": { releaseName: "13.2.0-16.0.6-11.0.0-ucrt-r1", fileSuffix: "13.2.0-mingw-w64ucrt-11.0.0-r1" },
"13.2-ucrt": { releaseName: "13.2.0-16.0.6-11.0.0-ucrt-r1", fileSuffix: "13.2.0-mingw-w64ucrt-11.0.0-r1" },
"13.2-ucrt-mcf": { releaseName: "13.2.0mcf-16.0.6-11.0.1-ucrt-r2", fileSuffix: "13.2.0-mingw-w64ucrt-11.0.1-r2" },
"13.2-msvcrt": { releaseName: "13.2.0-16.0.6-11.0.1-msvcrt-r1", fileSuffix: "13.2.0-mingw-w64msvcrt-11.0.1-r1" },
"13.1-ucrt": { releaseName: "13.1.0posix-16.0.3-11.0.0-ucrt-r1", fileSuffix: "13.1.0-mingw-w64ucrt-11.0.0-r1" },
"13.1-msvcrt": { releaseName: "13.1.0posix-16.0.3-11.0.0-msvcrt-r1", fileSuffix: "13.1.0-mingw-w64msvcrt-11.0.0-r1" },
"12": { releaseName: "12.3.0-16.0.4-11.0.0-ucrt-r1", fileSuffix: "12.3.0-mingw-w64ucrt-11.0.0-r1" },
"12.3.0-ucrt": { releaseName: "12.3.0-16.0.4-11.0.0-ucrt-r1", fileSuffix: "12.3.0-mingw-w64ucrt-11.0.0-r1" },
"12.3.0-msvcrt": { releaseName: "12.3.0-16.0.4-11.0.0-msvcrt-r1", fileSuffix: "12.3.0-mingw-w64msvcrt-11.0.0-r1" },
"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" },
"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" },
"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",
},
"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.5.0-11.0.1-msvcrt-r1", fileSuffix: "10.5.0-mingw-w64msvcrt-11.0.1-r1" },
"10.5.0-msvcrt": { releaseName: "10.5.0-11.0.1-msvcrt-r1", fileSuffix: "10.5.0-mingw-w64msvcrt-11.0.1-r1" },
"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" },
} as Record<string, MingwInfo | undefined>
function getGccPackageInfo(version: string, platform: NodeJS.Platform, arch: string): PackageInfo {
async function getGccPackageInfo(version: string, platform: NodeJS.Platform, arch: string): Promise<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"
const exceptionModel: "seh" | "dwarf" = "seh" // SEH is native windows exception model https://github.com/brechtsanders/winlibs_mingw/issues/4#issuecomment-599296483
const mingwAssets = await loadGitHubAssetList(
join(__dirname, "github_brechtsanders_winlibs_mingw.json"),
)
const asset = matchAsset(
mingwAssets,
{
version,
arch: arch === "x64"
? "x86_64"
: arch === "ia32"
? "i386"
: arch,
filterName: (name) => name.endsWith(".7z"),
},
)
return {
binRelativeDir: "bin/",
binFileName: addExeExt("g++"),
extractedFolderName: "mingw64",
extractFunction: extract7Zip,
url:
`https://github.com/brechtsanders/winlibs_mingw/releases/download/${mingwInfo.releaseName}/winlibs-${mingwArch}-posix-${exceptionModel}-gcc-${mingwInfo.fileSuffix}.7z`,
url: `https://github.com/brechtsanders/winlibs_mingw/releases/download/${asset.tag}/${asset.name}`,
}
}
default:
@ -79,7 +55,6 @@ function getGccPackageInfo(version: string, platform: NodeJS.Platform, arch: str
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function setupGcc(version: string, setupDir: string, arch: string, priority: number = 40) {
let installationInfo: InstallationInfo | undefined
switch (process.platform) {
@ -110,32 +85,44 @@ export async function setupGcc(version: string, setupDir: string, arch: string,
{ name: "libstdc++-devel" },
])
} else if (isUbuntu()) {
installationInfo = await installAptPack([
{
name: "gcc",
version,
repository: "ppa:ubuntu-toolchain-r/test",
key: { key: "1E9377A2BA9EF27F", fileName: "ubuntu-toolchain-r-test.gpg" },
},
{
name: "g++",
version,
repository: "ppa:ubuntu-toolchain-r/test",
key: { key: "1E9377A2BA9EF27F", fileName: "ubuntu-toolchain-r-test.gpg" },
},
])
if (version === "") {
// the default version
installationInfo = await installAptPack([{ name: "gcc" }, { name: "g++" }])
} else {
// add the PPA for access to more versions
installationInfo = await installAptPack([
{
name: "gcc",
version,
repository: "ppa:ubuntu-toolchain-r/test",
key: { key: "1E9377A2BA9EF27F", fileName: "ubuntu-toolchain-r-test.gpg" },
},
{
name: "g++",
version,
repository: "ppa:ubuntu-toolchain-r/test",
key: { key: "1E9377A2BA9EF27F", fileName: "ubuntu-toolchain-r-test.gpg" },
},
])
}
}
} else {
info(`Install g++-multilib because gcc for ${arch} was requested`)
if (isArch()) {
await setupPacmanPack("gcc-multilib", version)
installationInfo = await setupPacmanPack("gcc-multilib", version)
} else if (isUbuntu()) {
await installAptPack([{
name: "gcc-multilib",
version,
repository: "ppa:ubuntu-toolchain-r/test",
key: { key: "1E9377A2BA9EF27F", fileName: "ubuntu-toolchain-r-test.gpg" },
}])
if (version === "") {
// the default version
installationInfo = await installAptPack([{ name: "gcc-multilib" }])
} else {
// add the PPA for access to more versions
installationInfo = await installAptPack([{
name: "gcc-multilib",
version,
repository: "ppa:ubuntu-toolchain-r/test",
key: { key: "1E9377A2BA9EF27F", fileName: "ubuntu-toolchain-r-test.gpg" },
}])
}
}
}
break
@ -221,7 +208,7 @@ async function setupChocoMingw(version: string, arch: string): Promise<Installat
return undefined
}
async function activateGcc(version: string, binDir: string, priority: number = 40) {
async function activateGcc(givenVersion: string, binDir: string, priority: number = 40) {
const promises: Promise<void | ExecaReturnValue<string>>[] = []
// Setup gcc as the compiler
@ -242,6 +229,13 @@ async function activateGcc(version: string, binDir: string, priority: number = 4
addEnv("CXX", addExeExt(`${binDir}/g++`), rcOptions),
)
} else {
// if version is empty, get the version from the gcc command
let version = givenVersion
if (givenVersion === "") {
version = await getGccCmdVersion(binDir, version)
info(`Using gcc version ${version}`)
}
const majorVersion = semverMajor(semverCoerce(version) ?? version)
if (majorVersion >= 5) {
promises.push(
@ -283,6 +277,49 @@ async function activateGcc(version: string, binDir: string, priority: number = 4
await Promise.all(promises)
}
async function getGccCmdVersion(binDir: string, givenVersion: string) {
// TODO get the version from the package manager
try {
let gccExe = "gcc"
if (await pathExists(`${binDir}/gcc`)) {
gccExe = `${binDir}/gcc`
} else {
// try to find the gcc exe in the bin dir
const files = (await readdir(binDir)).sort(
(exe1, exe2) => {
const version1 = exe1.match(/^gcc-?(.*)(\.exe)?$/)?.[1] || ""
const version2 = exe2.match(/^gcc-?(.*)(\.exe)?$/)?.[1] || ""
return compareVersion(version1, version2)
},
)
for (const file of files) {
if (file.startsWith("gcc")) {
gccExe = `${binDir}/${file}`
break
}
}
}
const { stdout: versionStdout } = await execa(gccExe, ["--version"], { stdio: "pipe" })
// gcc-11 (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
// gcc-12 (Homebrew GCC 12.4.0) 12.4.0
// gcc (Ubuntu 13.1.0-8ubuntu1~22.04) 13.1.0
const versionMatch = (versionStdout as string).match(/gcc.* \(.*\) ([\d.]+)/)
if (versionMatch !== null) {
return versionMatch[1]
}
warning(`Failed to parse gcc version from: ${versionStdout}`)
return givenVersion
} catch (err) {
error(`Failed to get gcc version: ${err}`)
return givenVersion
}
}
async function addGccLoggingMatcher() {
const matcherPath = join(__dirname, "gcc_matcher.json")
if (!(await pathExists(matcherPath))) {

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,80 @@
import { Octokit } from "@octokit/rest"
import { writeFile } from "fs/promises"
import JsonStringify from "safe-stable-stringify"
import { compareVersion } from "../setup/version.ts"
import type { Assets } from "./load-assets.ts"
/**
* Get the list of all releases of a GitHub repository
* @param owner The owner of the repository
* @param repo The name of the repository
* @param prerelease Whether to include prereleases
*/
async function fetchGitHubAssetList(owner: string, repo: string, prerelease = false) {
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
})
const assets: Assets = {}
for (let page = 1; page !== 101; page++) {
console.log(`Fetching page ${page}`)
try {
/* eslint-disable no-await-in-loop */
const res = await octokit.repos.listReleases({
owner,
repo,
per_page: 100, // maximum supported by GitHub API
page,
})
if (res.data.length === 0) {
break
}
for (const release of res.data) {
if (release.draft) {
continue
}
if (!prerelease && release.prerelease) {
continue
}
if (!(release.tag_name in assets)) {
assets[release.tag_name] = []
}
const assets_ref = assets[release.tag_name]
for (const asset of release.assets) {
assets_ref.push(asset.name)
}
}
} catch (err) {
console.error(err)
break
}
}
return assets
}
/**
* Save the list of all releases of a GitHub repository to a json file
*/
export async function saveGitHubAssetList(
owner: string,
repo: string,
path: string,
) {
const assets = await fetchGitHubAssetList(owner, repo)
const jsonStringify = JsonStringify.configure({
deterministic: compareVersion,
})
const data = jsonStringify(assets)
// write the assets to a json file
await writeFile(path, data)
}

View File

@ -0,0 +1,80 @@
import { readFile } from "fs/promises"
/**
* The list of assets of a GitHub release
* @key tag The tag of the release
* @value assets The names of the assets of the release
*/
export type Assets = Record<string, string[]>
export async function loadGitHubAssetList(path: string): Promise<Assets> {
const data = await readFile(path, "utf-8")
return JSON.parse(data)
}
type MatchAssetOpts = {
version: string
arch?: string
filterTag?: (version: string) => boolean
filterName?: (asset: string) => boolean
}
/**
* Match the asset that matches the version and arch
*/
export function matchAsset(
assets: Assets,
opts: MatchAssetOpts,
): { tag: string; name: string } {
// get the list of versions
let tags = Object.keys(assets)
// filter the versions
if (opts.filterTag !== undefined) {
tags = tags.filter(opts.filterTag)
}
if (tags.length === 0) {
throw new Error(`no tag found for version ${opts.version}`)
}
// find the first tag that starts with the version
// loop over the versions starting with the latest
let tag: string | undefined
for (const mingwVersion of tags) {
if (mingwVersion.startsWith(opts.version)) {
tag = mingwVersion
break
}
}
if (tag === undefined) {
throw new Error(`version ${opts.version} is not supported`)
}
// get the list of assets
let matchedNames = assets[tag]
// filter the assets
if (opts.filterName !== undefined) {
matchedNames = matchedNames.filter(opts.filterName)
}
if (matchedNames.length === 0) {
throw new Error(`no asset found for version ${opts.version} and arch ${opts.arch}`)
}
// use the first asset if the arch is not specified
if (opts.arch === undefined) {
return { tag, name: matchedNames[0] }
}
// find the asset that matches the arch
for (const name of matchedNames) {
// search each asset name for the arch
if (name.includes(opts.arch)) {
return { tag, name }
}
}
throw new Error(`arch ${opts.arch} could not be found among ${JSON.stringify(matchedNames)}`)
}

View File

@ -147,3 +147,15 @@ export function addVPrefix(version: string) {
}
return version
}
export function compareVersion(tag1: string, tag2: string) {
const v1 = semverCoerce(tag1)
const v2 = semverCoerce(tag2)
if (v1 !== null && v2 !== null) {
// put the latest version first
return v2.compare(v1)
}
// if the tags are not semver, compare them as strings, putting the latest tag first
return tag2.localeCompare(tag1)
}

View File

@ -30,8 +30,10 @@ export const DefaultVersions: Record<string, string | undefined> = {
kcov: "42", // https://github.com/SimonKagstrom/kcov/releases
task: "3.38.0", // https://github.com/go-task/task/releases
doxygen: isArch() ? "1.11.0-4" : "1.11.0", // https://www.doxygen.nl/download.html // https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=doxygen // https://formulae.brew.sh/formula/doxygen // https://archlinux.org/packages/extra/x86_64/doxygen/
gcc: isArch() ? "13.2.1-3" : "13", // https://github.com/brechtsanders/winlibs_mingw/releases and // https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=gcc
// mingw: isArch() ? "12.2.0-1" : "8", // https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=mingw-w64 // https://archlinux.org/packages/extra/x86_64/mingw-w64-gcc/
gcc: process.platform === "win32"
? "14.2.0posix-18.1.8-12.0.0-ucrt-r1"
: "", // use the default version on Ubuntu, Fedora, Arch, macOS, etc.
// mingw: isArch() ? "12.2.0-1" : "8", // https://archlinux.org/packages/extra/x86_64/mingw-w64-gcc/
powershell: "7.4.5", // https://github.com/PowerShell/PowerShell/releases/tag/v7.4.5
}
@ -44,14 +46,7 @@ export const MinVersions: Record<string, string | undefined> = {
// - the newer ubuntu versions use the first entry (e.g. v20),
// - the older ones use ""
export const DefaultLinuxVersion: Record<string, Record<number, string> | undefined> = {
gcc: {
24: "13",
22: "13",
20: "11",
18: "11",
16: "11",
14: "11",
},
// https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=mingw-w64
mingw: {
24: "8.0.0-1",
22: "8.0.0-1",

View File

@ -7,7 +7,7 @@ export function getVersion(name: string, version: string | undefined, osVersion:
if (isVersionDefault(version) && process.platform === "linux" && osVersion !== null && name in DefaultLinuxVersion) {
return getDefaultLinuxVersion(osVersion, DefaultLinuxVersion[name]!)
} else if (isVersionDefault(version) && name in DefaultVersions) {
return DefaultVersions[name]!
return DefaultVersions[name] ?? ""
} else if (version === "true") {
return ""
}