feat: support installing llvm via apt on Ubuntu

This commit is contained in:
Amin Yahyaabadi 2023-07-15 21:46:28 -07:00
parent 46dc266a3e
commit 70a091c663
10 changed files with 121 additions and 68 deletions

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

@ -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": {

View File

@ -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

View File

@ -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
}

View File

@ -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"