Files
2026-07-13 12:44:08 +08:00

125 lines
3.2 KiB
JavaScript

import fs from 'node:fs'
import path from 'node:path'
import { CPUArchitectures } from '@/types'
import {
CMAKE_PATH,
CMAKE_INSTALL_PATH,
CMAKE_BIN_PATH,
CMAKE_MANIFEST_PATH,
CMAKE_VERSION
} from '@/constants'
import { FileHelper } from '@/helpers/file-helper'
import { SystemHelper } from '@/helpers/system-helper'
import { createSetupStatus } from './setup-status'
/**
* Download and set up Leon-managed CMake
* 1. Resolve the pinned version from versions.json
* 2. Download the matching Linux archive for the current architecture
* 3. Extract it into bin/cmake/cmake/
* 4. Always use this CMake binary for local source builds
*/
const { cpuArchitecture: CPU_ARCH } = SystemHelper.getInformation()
function readManifest() {
if (!fs.existsSync(CMAKE_MANIFEST_PATH)) {
return null
}
try {
return JSON.parse(fs.readFileSync(CMAKE_MANIFEST_PATH, 'utf8'))
} catch {
return null
}
}
async function cleanInstallDirectory() {
await fs.promises.mkdir(CMAKE_PATH, { recursive: true })
const entries = await fs.promises.readdir(CMAKE_PATH, {
withFileTypes: true
})
await Promise.all(
entries
.filter((entry) => entry.name !== 'versions.json')
.map((entry) =>
fs.promises.rm(path.join(CMAKE_PATH, entry.name), {
recursive: true,
force: true
})
)
)
}
function getDownloadURL() {
if (CPU_ARCH === CPUArchitectures.X64) {
return `https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz`
}
if (CPU_ARCH === CPUArchitectures.ARM64) {
return `https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-aarch64.tar.gz`
}
throw new Error(`Unsupported Linux architecture for CMake: ${CPU_ARCH}`)
}
export default async function setupCMake() {
if (!SystemHelper.isLinux()) {
return
}
const status = createSetupStatus('Downloading and setting up CMake...').start()
const manifest = readManifest()
if (manifest?.version === CMAKE_VERSION && fs.existsSync(CMAKE_BIN_PATH)) {
status.succeed(`CMake: ${CMAKE_VERSION}`)
return
}
const archivePath = path.join(CMAKE_PATH, `cmake-${CMAKE_VERSION}.tar.gz`)
await cleanInstallDirectory()
try {
status.pause()
await FileHelper.downloadFile(getDownloadURL(), archivePath, {
cliProgress: true,
parallelStreams: 3,
skipExisting: false
})
status.text = 'Installing CMake...'
status.start()
await FileHelper.extractArchive(archivePath, CMAKE_INSTALL_PATH, {
stripComponents: 1
})
if (!fs.existsSync(CMAKE_BIN_PATH)) {
throw new Error(`Cannot find CMake binary at "${CMAKE_BIN_PATH}"`)
}
await Promise.all([
fs.promises.rm(archivePath, { force: true }),
FileHelper.createManifestFile(CMAKE_MANIFEST_PATH, 'cmake', CMAKE_VERSION, {
os: SystemHelper.getInformation().type,
architecture: SystemHelper.getInformation().cpuArchitecture
})
])
status.succeed(`CMake: ${CMAKE_VERSION}`)
} catch (error) {
await fs.promises.rm(archivePath, { force: true })
if (status.isSpinning) {
status.fail('Failed to set up CMake')
}
throw new Error(`Failed to set up CMake: ${error}`)
}
}