mirror of https://github.com/aminya/setup-cpp
feat: support installing llvm via apt on Ubuntu
This commit is contained in:
parent
46dc266a3e
commit
70a091c663
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
|
@ -151,7 +151,8 @@
|
||||||
],
|
],
|
||||||
"alias": {
|
"alias": {
|
||||||
"electron": false,
|
"electron": false,
|
||||||
"patha": "patha/dist/index.node.mjs"
|
"patha": "patha/dist/index.node.mjs",
|
||||||
|
"admina": "admina/dist/index.mjs"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"overrides": {
|
"overrides": {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { InstallationInfo, setupBin } from "../utils/setup/setupBin"
|
||||||
import { semverCoerceIfInvalid } from "../utils/setup/version"
|
import { semverCoerceIfInvalid } from "../utils/setup/version"
|
||||||
import { setupMacOSSDK } from "../macos-sdk/macos-sdk"
|
import { setupMacOSSDK } from "../macos-sdk/macos-sdk"
|
||||||
import { addEnv } from "../utils/env/addEnv"
|
import { addEnv } from "../utils/env/addEnv"
|
||||||
import { setupAptPack, updateAptAlternatives } from "../utils/setup/setupAptPack"
|
import { hasNala, setupAptPack, updateAptAlternatives } from "../utils/setup/setupAptPack"
|
||||||
import { info, warning } from "ci-log"
|
import { info, warning } from "ci-log"
|
||||||
|
|
||||||
import { GITHUB_ACTIONS } from "ci-info"
|
import { GITHUB_ACTIONS } from "ci-info"
|
||||||
|
@ -14,7 +14,9 @@ import { isUbuntu } from "../utils/env/isUbuntu"
|
||||||
import { getLLVMPackageInfo } from "./llvm_url"
|
import { getLLVMPackageInfo } from "./llvm_url"
|
||||||
import { ubuntuVersion } from "../utils/env/ubuntu_version"
|
import { ubuntuVersion } from "../utils/env/ubuntu_version"
|
||||||
import { pathExists } from "path-exists"
|
import { pathExists } from "path-exists"
|
||||||
import { ExecaReturnValue } from "execa"
|
import { ExecaReturnValue, execa } from "execa"
|
||||||
|
import { readFileSync, writeFileSync } from "fs"
|
||||||
|
import { execRootSync } from "admina"
|
||||||
|
|
||||||
export async function setupLLVM(version: string, setupDir: string, arch: string): Promise<InstallationInfo> {
|
export async function setupLLVM(version: string, setupDir: string, arch: string): Promise<InstallationInfo> {
|
||||||
const installationInfo = await setupLLVMWithoutActivation(version, setupDir, arch)
|
const installationInfo = await setupLLVMWithoutActivation(version, setupDir, arch)
|
||||||
|
@ -24,16 +26,58 @@ export async function setupLLVM(version: string, setupDir: string, arch: string)
|
||||||
|
|
||||||
let installedDeps = false
|
let installedDeps = false
|
||||||
|
|
||||||
async function setupLLVMWithoutActivation(version: string, setupDir: string, arch: string) {
|
async function setupLLVMOnly(version: string, setupDir: string, arch: string) {
|
||||||
const installationInfoPromise = setupBin("llvm", version, getLLVMPackageInfo, setupDir, arch)
|
try {
|
||||||
|
if (isUbuntu()) {
|
||||||
|
const coeredVersion = semverCoerceIfInvalid(version)
|
||||||
|
const majorVersion = parseInt(coeredVersion.split(".")[0], 10)
|
||||||
|
const installationFolder = `/usr/lib/llvm-${majorVersion}` // TODO for older versions, this also includes the minor version
|
||||||
|
|
||||||
let depsPromise: Promise<void>
|
await setupAptPack([{ name: "curl" }])
|
||||||
|
await execa("curl", ["-LJO", "https://apt.llvm.org/llvm.sh"], { cwd: "/tmp" })
|
||||||
|
|
||||||
|
let script = readFileSync("/tmp/llvm.sh", "utf-8")
|
||||||
|
// make the scirpt non-interactive and fix broken packages
|
||||||
|
script = script
|
||||||
|
.replace(
|
||||||
|
/add-apt-repository "\${REPO_NAME}"/g,
|
||||||
|
// eslint-disable-next-line no-template-curly-in-string
|
||||||
|
'add-apt-repository -y "${REPO_NAME}"'
|
||||||
|
)
|
||||||
|
.replace(/apt-get install -y/g, "apt-get install -y --fix-broken")
|
||||||
|
// use nala if it is available
|
||||||
|
if (hasNala()) {
|
||||||
|
script = script.replace(/apt-get/g, "nala")
|
||||||
|
}
|
||||||
|
writeFileSync("/tmp/llvm-setup-cpp.sh", script)
|
||||||
|
|
||||||
|
execRootSync("chmod", ["+x", "/tmp/llvm-setup-cpp.sh"])
|
||||||
|
execRootSync("bash", ["/tmp/setup-cpp-llvm.sh"], {
|
||||||
|
stdio: "inherit",
|
||||||
|
shell: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
installDir: `/usr/lib/${installationFolder}`,
|
||||||
|
binDir: `/usr/bin`,
|
||||||
|
version,
|
||||||
|
} as InstallationInfo
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
info(`Failed to install llvm via system package manager ${err}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return setupBin("llvm", version, getLLVMPackageInfo, setupDir, arch)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setupLLVMWithoutActivation(version: string, setupDir: string, arch: string) {
|
||||||
|
const installationInfoPromise = setupLLVMOnly(version, setupDir, arch)
|
||||||
|
|
||||||
|
let depsPromise: Promise<void> = Promise.resolve()
|
||||||
if (!installedDeps) {
|
if (!installedDeps) {
|
||||||
depsPromise = setupLLVMDeps(arch, version)
|
depsPromise = setupLLVMDeps(arch, version)
|
||||||
// eslint-disable-next-line require-atomic-updates
|
// eslint-disable-next-line require-atomic-updates
|
||||||
installedDeps = true
|
installedDeps = true
|
||||||
} else {
|
|
||||||
depsPromise = Promise.resolve()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// install LLVM and its dependencies in parallel
|
// install LLVM and its dependencies in parallel
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { dirname } from "patha"
|
||||||
import which from "which"
|
import which from "which"
|
||||||
import { isUbuntu } from "../utils/env/isUbuntu"
|
import { isUbuntu } from "../utils/env/isUbuntu"
|
||||||
import { execRootSync } from "admina"
|
import { execRootSync } from "admina"
|
||||||
import { addAptKeyViaDownload, setupAptPack } from "../utils/setup/setupAptPack"
|
import { addAptKeyViaDownload, hasNala, setupAptPack } from "../utils/setup/setupAptPack"
|
||||||
|
|
||||||
let binDir: string | undefined
|
let binDir: string | undefined
|
||||||
|
|
||||||
|
@ -45,3 +45,10 @@ export async function setupNala(version: string, _setupDir: string, _arch: strin
|
||||||
|
|
||||||
return { binDir }
|
return { binDir }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function bashWithNala(script: string) {
|
||||||
|
if (hasNala()) {
|
||||||
|
return `apt-get() { nala $@; }; export -f apt-get; ${script}; unset -f apt-get`
|
||||||
|
}
|
||||||
|
return script
|
||||||
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@ import { InstallationInfo } from "./setupBin"
|
||||||
import { execRoot, execRootSync } from "admina"
|
import { execRoot, execRootSync } from "admina"
|
||||||
import { GITHUB_ACTIONS } from "ci-info"
|
import { GITHUB_ACTIONS } from "ci-info"
|
||||||
import { addEnv, cpprc_path, setupCppInProfile } from "../env/addEnv"
|
import { addEnv, cpprc_path, setupCppInProfile } from "../env/addEnv"
|
||||||
import which from "which"
|
|
||||||
import { pathExists } from "path-exists"
|
import { pathExists } from "path-exists"
|
||||||
import { promises as fsPromises } from "fs"
|
import { promises as fsPromises } from "fs"
|
||||||
const { appendFile } = fsPromises
|
const { appendFile } = fsPromises
|
||||||
import { execa } from "execa"
|
import { execa } from "execa"
|
||||||
import escapeRegex from "escape-string-regexp"
|
import escapeRegex from "escape-string-regexp"
|
||||||
import { warning, info } from "ci-log"
|
import { warning, info } from "ci-log"
|
||||||
|
import which from "which"
|
||||||
|
|
||||||
/* eslint-disable require-atomic-updates */
|
/* eslint-disable require-atomic-updates */
|
||||||
let didUpdate: boolean = false
|
let didUpdate: boolean = false
|
||||||
|
@ -82,9 +82,13 @@ async function getAptArg(name: string, version: string | undefined) {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function hasNala() {
|
||||||
|
return which.sync("nala", { nothrow: true }) !== null
|
||||||
|
}
|
||||||
|
|
||||||
function getApt() {
|
function getApt() {
|
||||||
let apt: string
|
let apt: string
|
||||||
if (which.sync("nala", { nothrow: true }) !== null) {
|
if (hasNala()) {
|
||||||
apt = "nala"
|
apt = "nala"
|
||||||
} else {
|
} else {
|
||||||
apt = "apt-get"
|
apt = "apt-get"
|
||||||
|
|
Loading…
Reference in New Issue