2023-07-18 13:26:20 +08:00
|
|
|
import { execRoot } from "admina"
|
|
|
|
import { execa } from "execa"
|
|
|
|
import { addPath } from "../utils/env/addEnv"
|
|
|
|
import { hasNala, isPackageInstalled, setupAptPack } from "../utils/setup/setupAptPack"
|
|
|
|
import { InstallationInfo } from "../utils/setup/setupBin"
|
|
|
|
import { promises } from "fs"
|
|
|
|
import { info } from "console"
|
2023-08-22 11:21:34 +08:00
|
|
|
import { DEFAULT_TIMEOUT } from "../tool"
|
2023-07-18 13:26:20 +08:00
|
|
|
const { readFile, writeFile, chmod } = promises
|
|
|
|
|
|
|
|
export async function setupLLVMApt(majorVersion: number): Promise<InstallationInfo> {
|
|
|
|
// TODO for older versions, this also includes the minor version
|
|
|
|
const installationFolder = `/usr/lib/llvm-${majorVersion}`
|
|
|
|
|
|
|
|
await setupAptPack([{ name: "curl" }])
|
|
|
|
await execa("curl", ["-LJO", "https://apt.llvm.org/llvm.sh"], { cwd: "/tmp" })
|
|
|
|
const neededPackages = await patchAptLLVMScript("/tmp/llvm.sh", "/tmp/llvm-setup-cpp.sh")
|
|
|
|
await setupAptPack(neededPackages)
|
|
|
|
await chmod("/tmp/llvm-setup-cpp.sh", "755")
|
|
|
|
await execRoot("bash", ["/tmp/llvm-setup-cpp.sh", `${majorVersion}`, "all"], {
|
|
|
|
stdio: "inherit",
|
|
|
|
shell: true,
|
2023-08-22 11:21:34 +08:00
|
|
|
timeout: DEFAULT_TIMEOUT,
|
2023-07-18 13:26:20 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
await addPath(`${installationFolder}/bin`)
|
|
|
|
|
|
|
|
return {
|
|
|
|
installDir: `${installationFolder}`,
|
|
|
|
binDir: `${installationFolder}/bin`,
|
|
|
|
bin: `${installationFolder}/bin/clang++`,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function patchAptLLVMScript(path: string, target_path: string) {
|
|
|
|
let script = await readFile(path, "utf-8")
|
|
|
|
|
2023-08-22 10:29:23 +08:00
|
|
|
script = debugScript(script)
|
2023-07-18 13:26:20 +08:00
|
|
|
script = nonInteractiveScript(script)
|
|
|
|
script = await removeConflictingPAckages(script)
|
|
|
|
script = useNalaScript(script)
|
|
|
|
|
|
|
|
await writeFile(target_path, script)
|
|
|
|
|
|
|
|
// the packages needed by the script
|
|
|
|
return [{ name: "lsb-release" }, { name: "wget" }, { name: "software-properties-common" }, { name: "gnupg" }]
|
|
|
|
}
|
2023-08-22 10:29:23 +08:00
|
|
|
|
|
|
|
function debugScript(script: string) {
|
|
|
|
if (!process.env.NODE_DEBUG) {
|
|
|
|
return script.replace(/set -eux/g, "set -eu")
|
|
|
|
}
|
|
|
|
return script
|
|
|
|
}
|
|
|
|
|
|
|
|
function nonInteractiveScript(script: string) {
|
2023-07-18 13:26:20 +08:00
|
|
|
// make the scirpt non-interactive and fix broken packages
|
2023-08-22 10:29:23 +08:00
|
|
|
return script.replace(
|
2023-07-18 13:26:20 +08:00
|
|
|
/add-apt-repository "\${REPO_NAME}"/g,
|
|
|
|
// eslint-disable-next-line no-template-curly-in-string
|
2023-07-25 04:20:04 +08:00
|
|
|
'add-apt-repository -y "${REPO_NAME}"',
|
2023-07-18 13:26:20 +08:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
async function removeConflictingPAckages(givenScript: string) {
|
|
|
|
// fix conflicts between libclang-rt and libclang
|
|
|
|
let script = givenScript.replace(
|
|
|
|
/apt-get install -y/g,
|
2023-07-25 04:20:04 +08:00
|
|
|
'apt-get install -o Dpkg::Options::="--force-overwrite" -y --fix-broken',
|
2023-07-18 13:26:20 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// check if these are installed and if so, remove them from the script as they conflict
|
|
|
|
const conflictingPackages = ["libc++-$LLVM_VERSION-dev", "libc++abi-$LLVM_VERSION-dev", "libunwind-$LLVM_VERSION-dev"]
|
|
|
|
await Promise.all(
|
|
|
|
conflictingPackages.map(async (pack) => {
|
|
|
|
const installingPack = pack.replace("$LLVM_VERSION", "*")
|
|
|
|
if (await isPackageInstalled(installingPack)) {
|
|
|
|
info(`Removing conflicting package ${installingPack}`)
|
|
|
|
script = script.replace(pack, "")
|
|
|
|
}
|
2023-07-25 04:20:04 +08:00
|
|
|
}),
|
2023-07-18 13:26:20 +08:00
|
|
|
)
|
|
|
|
return script
|
|
|
|
}
|
|
|
|
|
|
|
|
function useNalaScript(script: string) {
|
|
|
|
// use nala if it is available
|
|
|
|
if (hasNala()) {
|
|
|
|
return script.replace(/apt-get/g, "nala")
|
|
|
|
}
|
|
|
|
return script
|
|
|
|
}
|