fix: fix gcc/g++ paths on Fedora/Arch

This commit is contained in:
Amin Yahyaabadi 2025-02-27 02:48:19 -08:00
parent 1c96aae406
commit a9764989af
8 changed files with 91 additions and 76 deletions

View File

@ -5,7 +5,6 @@ RUN node /usr/lib/setup-cpp/setup-cpp.js \
--compiler gcc && \
# cleanup
dnf clean all && \
rm -rf /tmp/* && \
ls /usr/bin/g++-14
rm -rf /tmp/*
ENTRYPOINT ["/bin/bash"]

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

@ -102,7 +102,10 @@ export async function installCompiler(
}
} catch (err) {
error(err as string | Error)
errorMessages.push(`Failed to install the ${compiler} ${version}`)
if (err instanceof Error) {
error(err.stack ?? "")
}
errorMessages.push(`Failed to install the ${compiler} compiler ${version}`)
}
if (installationInfo !== null) {

View File

@ -2,11 +2,12 @@ import path from "path"
import { fileURLToPath } from "url"
import ciInfo from "ci-info"
const { GITHUB_ACTIONS } = ciInfo
import { error, info, warning } from "ci-log"
import { error, warning } from "ci-log"
import { addEnv } from "envosman"
import { execa } from "execa"
import { readdir } from "fs/promises"
import { pathExists } from "path-exists"
import { addExeExt } from "patha"
import semverCoerce from "semver/functions/coerce"
import semverMajor from "semver/functions/major"
import { addUpdateAlternativesToRc, installAptPack } from "setup-apt"
@ -19,7 +20,7 @@ import { isUbuntu } from "../utils/env/isUbuntu.js"
import type { InstallationInfo } from "../utils/setup/setupBin.js"
import { setupDnfPack } from "../utils/setup/setupDnfPack.js"
import { setupPacmanPack } from "../utils/setup/setupPacmanPack.js"
import { compareVersion } from "../utils/setup/version.js"
import { compareVersion, semverCoerceIfInvalid } from "../utils/setup/version.js"
import { addGccLoggingMatcher } from "./gccMatcher.js"
import { setupMingw } from "./mingw.js"
@ -140,42 +141,23 @@ async function activateGcc(givenVersion: string, binDir: string, priority: numbe
const promises: Promise<void>[] = []
{
// 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 binVersion = getGccBinVersion(givenVersion)
const majorVersion = semverMajor(semverCoerce(version) ?? version)
if (majorVersion >= 5) {
const gccPath = await findGccExe("gcc", binDir, binVersion)
const gxxPath = await findGccExe("g++", binDir, binVersion)
promises.push(
addEnv("CC", gccPath, rcOptions),
addEnv("CXX", gxxPath, rcOptions),
)
if (isUbuntu()) {
promises.push(
addEnv("CC", `${binDir}/gcc-${majorVersion}`, rcOptions),
addEnv("CXX", `${binDir}/g++-${majorVersion}`, rcOptions),
addUpdateAlternativesToRc("cc", gccPath, rcOptions, priority),
addUpdateAlternativesToRc("cxx", gxxPath, rcOptions, priority),
addUpdateAlternativesToRc("gcc", gccPath, rcOptions, priority),
addUpdateAlternativesToRc("g++", gxxPath, rcOptions, priority),
)
if (isUbuntu()) {
promises.push(
addUpdateAlternativesToRc("cc", `${binDir}/gcc-${majorVersion}`, rcOptions, priority),
addUpdateAlternativesToRc("cxx", `${binDir}/g++-${majorVersion}`, rcOptions, priority),
addUpdateAlternativesToRc("gcc", `${binDir}/gcc-${majorVersion}`, rcOptions, priority),
addUpdateAlternativesToRc("g++", `${binDir}/g++-${majorVersion}`, rcOptions, priority),
)
}
} else {
promises.push(
addEnv("CC", `${binDir}/gcc-${version}`, rcOptions),
addEnv("CXX", `${binDir}/g++-${version}`, rcOptions),
)
if (isUbuntu()) {
promises.push(
addUpdateAlternativesToRc("cc", `${binDir}/gcc-${version}`, rcOptions, priority),
addUpdateAlternativesToRc("cxx", `${binDir}/g++-${version}`, rcOptions, priority),
addUpdateAlternativesToRc("gcc", `${binDir}/gcc-${version}`, rcOptions, priority),
addUpdateAlternativesToRc("g++", `${binDir}/g++-${version}`, rcOptions, priority),
)
}
}
}
@ -199,29 +181,61 @@ async function activateGcc(givenVersion: string, binDir: string, priority: numbe
await Promise.all(promises)
}
async function getGccCmdVersion(binDir: string, givenVersion: string) {
// TODO get the version from the package manager
/**
* Get the version string used in the gcc exe name
*/
function getGccBinVersion(givenVersion: string) {
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(
const coerced = semverCoerceIfInvalid(givenVersion)
const majorVersion = semverMajor(coerced)
return majorVersion >= 5 ? `${majorVersion}` : givenVersion
} catch {
// ignore
return givenVersion
}
}
async function findGccExe(variant: "gcc" | "g++", binDir: string, binVersion: string) {
if (await pathExists(`${binDir}/${variant}-${binVersion}`)) {
return addExeExt(`${binDir}/${variant}-${binVersion}`)
}
// try to find the gcc exe in the bin dir
if (binVersion !== "") {
const gccExeRegex = new RegExp(`^${variant}-?(.*)(\\.exe)?$`)
const files = (await readdir(binDir))
.filter((file) => gccExeRegex.test(file))
.sort(
(exe1, exe2) => {
const version1 = exe1.match(/^gcc-?(.*)(\.exe)?$/)?.[1] ?? ""
const version2 = exe2.match(/^gcc-?(.*)(\.exe)?$/)?.[1] ?? ""
return compareVersion(version1, version2)
const version1 = exe1.match(gccExeRegex)?.[1] ?? ""
const version2 = exe2.match(gccExeRegex)?.[1] ?? ""
try {
return compareVersion(version1, version2)
} catch {
return 0
}
},
)
for (const file of files) {
if (file.startsWith("gcc")) {
gccExe = `${binDir}/${file}`
break
}
for (const file of files) {
const gccExe = `${binDir}/${file}`
/* eslint-disable-next-line no-await-in-loop */
if (file.includes(binVersion) || (await getGccCmdVersion(gccExe)) === binVersion) {
return addExeExt(gccExe)
}
}
}
if (await pathExists(`${binDir}/${variant}`)) {
return addExeExt(`${binDir}/${variant}`)
}
return addExeExt(variant)
}
async function getGccCmdVersion(gccExe: string) {
// TODO get the version from the package manager
try {
const { stdout: versionStdout } = await execa(gccExe, ["--version"], { stdio: "pipe" })
// gcc-11 (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
@ -235,9 +249,8 @@ async function getGccCmdVersion(binDir: string, givenVersion: string) {
}
warning(`Failed to parse gcc version from: ${versionStdout}`)
return givenVersion
} catch (err) {
error(`Failed to get gcc version: ${err}`)
return givenVersion
}
return undefined
}

View File

@ -21,22 +21,22 @@ export async function setupDnfPack(packages: DnfPackage[]): Promise<Installation
}
async function getDnfArg(name: string, version: string | undefined) {
if (version !== undefined && version !== "") {
// check if name-version is available
const { stdout } = await execa("dnf", ["search", "-q", `${name}-${version}`])
if (stdout.trim() !== "") {
return `${name}-${version}`
} else {
// try with ${name}${version}
// eslint-disable-next-line @typescript-eslint/no-shadow
const { stdout } = await execa("dnf", ["search", "-q", `${name}${version}`])
if (stdout.trim() !== "") {
return `${name}${version}`
}
warning(`Failed to install ${name} ${version} via dnf, trying without version`)
}
if (version === undefined || version === "") {
return name
}
// check if name-version is available
const { stdout: nameDashVersionSearch } = await execa("dnf", ["search", "-q", `${name}-${version}`])
if (nameDashVersionSearch.trim() !== "") {
return `${name}-${version}`
}
// try with ${name}${version}
const { stdout: nameVersionSearch } = await execa("dnf", ["search", "-q", `${name}${version}`])
if (nameVersionSearch.trim() !== "") {
return `${name}${version}`
}
warning(`Failed to install ${name} ${version} via dnf, trying without version`)
return name
}