UNPKG

setup-cpp

Version:

Install all the tools required for building and testing C++/C projects.

117 lines (107 loc) 4.15 kB
import { join } from "path" import { endGroup, startGroup } from "@actions/core" import { error, info } from "ci-log" import semverValid from "semver/functions/valid" import { getSuccessMessage } from "./cli-options.js" import { setupGcc } from "./gcc/gcc.js" import { setupMingw } from "./gcc/mingw.js" import { activateGcovGCC, activateGcovLLVM } from "./gcovr/gcovr.js" import { setupAppleClang } from "./llvm/apple-clang.js" import { setupLLVM } from "./llvm/llvm.js" import { setupMSVC } from "./msvc/msvc.js" import { appleClangSetups, gccSetups, llvmSetups, mingwSetups, msvcSetups } from "./tool.js" import type { InstallationInfo } from "./utils/setup/setupBin.js" import { getVersion } from "./versions/versions.js" export type CompilerInfo = { compiler: string version: string | undefined } /** * Match version patterns like: * - Standard versions: digit.digit.digit * - Semver with pre-release: digit.digit.digit-alpha.1 * - Semver with build metadata: digit.digit.digit+build.123 * - MSVC style: digit.digit.digit.digit * - Year versions: 2015, 2017, etc. */ const versionPattern = /[.-]((?:\d{4}|\d+(?:\.\d+)*(?:-[\w.-]+)?(?:\+[\w.-]+)?)$)/ /** * Detecting the compiler version by looking for a version-like pattern. * Supports compiler names that contain hyphens and various version formats. * * @param compilerAndVersion - The compiler and version string * @returns The compiler and version * * @nothrow It doesn't throw any error, but it logs the error if it fails to parse the compiler info */ export function getCompilerInfo(compilerAndVersion: string): CompilerInfo { try { const match = compilerAndVersion.match(versionPattern) if (match === null) { return { compiler: compilerAndVersion, version: undefined } } const version = match[1] const compiler = compilerAndVersion.slice(0, match.index).replace(/[.-]$/, "") // Only check semver for non-year versions if (!version.match(/^\d{4}$/) && semverValid(version) === null) { info(`Non-semver version format: ${version}`) } return { compiler, version } } catch (err) { error(`Failed to parse the compiler info ${compilerAndVersion}: ${err}`) return { compiler: compilerAndVersion, version: undefined } } } /** Installing the specified compiler */ export async function installCompiler( compiler: string, version: string | undefined, osVersion: number[] | null, setupCppDir: string, arch: string, successMessages: string[], errorMessages: string[], ) { let installationInfo: InstallationInfo | undefined | void | null // null means the compiler is not supported try { // install the compiler. We allow some aliases for the compiler name startGroup(`Installing ${compiler} ${version ?? ""}`) if (compiler in llvmSetups) { installationInfo = await setupLLVM( getVersion("llvm", version, osVersion), join(setupCppDir, "llvm"), arch, ) await activateGcovLLVM() } else if (compiler in gccSetups) { const gccVersion = getVersion("gcc", version, osVersion) installationInfo = await setupGcc(gccVersion, join(setupCppDir, "gcc"), arch) await activateGcovGCC(gccVersion) } else if (compiler in mingwSetups) { const gccVersion = getVersion("mingw", version, osVersion) installationInfo = await setupMingw(gccVersion, join(setupCppDir, "gcc"), arch) await activateGcovGCC(gccVersion) } else if (compiler in msvcSetups) { installationInfo = await setupMSVC( getVersion("msvc", version, osVersion), join(setupCppDir, "msvc"), arch, ) } else if (compiler in appleClangSetups) { await setupAppleClang() } else { installationInfo = null errorMessages.push(`Unsupported compiler ${compiler}`) } } catch (err) { error(err as string | Error) if (err instanceof Error) { error(err.stack ?? "") } errorMessages.push(`Failed to install the ${compiler} compiler ${version}`) } if (installationInfo !== null) { successMessages.push(getSuccessMessage(compiler, installationInfo)) } endGroup() }