Determine the build target automatically

This commit is contained in:
Eugen Wissner 2024-05-20 01:42:56 +02:00
parent ebd68d7878
commit 189b2e6054
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
2 changed files with 49 additions and 23 deletions

3
TODO
View File

@ -13,6 +13,3 @@
- Error message with an empty file wrongly says that a ")" is expected.
- Support any expressions for constants.
- Name analysis should fail if there are undefined symbols.
# Toolchain
- Try to guess the build platform (x86_64-slackware-linux is hard coded).

View File

@ -3,19 +3,44 @@ import path from 'node:path'
import childProcess from 'node:child_process'
import process from 'process'
import os from 'os'
import { Buffer } from 'node:buffer'
// Define constants.
const tmp = path.resolve('./build/tools')
const target = 'riscv32-unknown-linux-gnu'
const build = 'x86_64-slackware-linux'
const baseDirectory = path.resolve('./tools')
const busyboxVersion = '1.36.1'
const kernelVersion = '5.15.158'
const gccVersion = '13.2.0'
const gccVersion = '14.1.0'
const binutilsVersion = '2.42'
const glibcVersion = '2.39'
function findBuildTarget () {
const env = {
LANG: 'en_US.UTF-8'
}
const gccV = childProcess.spawn('gcc', ['--verbose'], { stdio: ['ignore', 'ignore', 'pipe'], env })
const buffers = []
gccV.stderr.on('data', function (data) {
buffers.push(data)
})
return new Promise(function (resolve, reject) {
gccV.on('exit', function () {
const [_, target] = Buffer.concat(buffers)
.toString()
.split('\n')
.find(line => line.startsWith('Target: '))
.split(' ')
resolve(target)
})
})
}
function createImage (rootfs) {
const rootExt4 = path.join(tmp, 'rootfs.ext4')
@ -112,7 +137,7 @@ async function buildInit (sysroot) {
childProcess.execFileSync('riscv32-unknown-linux-gnu-g++', compilerArguments, { stdio: 'inherit', env })
}
async function buildGlibc (sysroot, rootfs) {
async function buildGlibc (sysroot, rootfs, options) {
const sourceDirectory = await downloadAndUnarchive(
new URL(`https://ftp.gnu.org/gnu/glibc/glibc-${glibcVersion}.tar.xz`)
)
@ -120,7 +145,7 @@ async function buildGlibc (sysroot, rootfs) {
'--prefix=/usr',
'--libdir=/usr/lib',
`--host=${target}`,
`--build=${build}`,
`--build=${options.build}`,
`--enable-kernel=${kernelVersion}`,
`--with-headers=${path.join(rootfs, 'usr/include')}`,
'--disable-nscd'
@ -166,9 +191,9 @@ async function buildCrossBinutils (sysroot) {
return sourceDirectory
}
async function buildGCC1 (sysroot, rootfs) {
async function buildGCC1 (sysroot, rootfs, options) {
const sourceDirectory = await downloadAndUnarchive(
new URL(`https://download.dlackware.com/slackware/slackware64-current/source/d/gcc/gcc-${gccVersion}.tar.xz`)
new URL(`https://gcc.gnu.org/pub/gcc/releases/gcc-${gccVersion}/gcc-${gccVersion}.tar.xz`)
)
const cwd = path.join(path.dirname(sourceDirectory), 'build-gcc');
await fs.mkdir(cwd)
@ -201,8 +226,8 @@ async function buildGCC1 (sysroot, rootfs) {
'--with-newlib',
'--without-headers',
`--target=${target}`,
`--build=${build}`,
`--host=${build}`
`--build=${options.build}`,
`--host=${options.build}`
]
const flags = '-O2 -fPIC'
const env = {
@ -222,14 +247,14 @@ async function buildGCC1 (sysroot, rootfs) {
return sourceDirectory
}
async function buildBinutils (sourceDirectory, sysroot, rootfs) {
async function buildBinutils (sourceDirectory, sysroot, rootfs, options) {
const cwd = path.join(path.dirname(sourceDirectory), 'build-binutils');
await fs.rm(cwd, { recursive: true, force: true })
await fs.mkdir(cwd)
const configureOptions = [
'--prefix=/usr',
`--build=${build}`,
`--build=${options.build}`,
`--host=${target}`,
`--with-build-sysroot=${rootfs}`,
'--disable-nls',
@ -253,7 +278,7 @@ async function buildBinutils (sourceDirectory, sysroot, rootfs) {
return sourceDirectory
}
async function buildGCC2 (sourceDirectory, sysroot, rootfs) {
async function buildGCC2 (sourceDirectory, sysroot, rootfs, options) {
const cwd = path.join(path.dirname(sourceDirectory), 'build-gcc');
await fs.rm(cwd, { recursive: true, force: true })
await fs.mkdir(cwd)
@ -276,8 +301,8 @@ async function buildGCC2 (sourceDirectory, sysroot, rootfs) {
'--with-default-libstdcxx-abi=new',
'--disable-nls',
`--target=${target}`,
`--build=${build}`,
`--host=${build}`
`--build=${options.build}`,
`--host=${options.build}`
]
const flags = '-O2 -fPIC'
const env = {
@ -295,7 +320,7 @@ async function buildGCC2 (sourceDirectory, sysroot, rootfs) {
childProcess.execFileSync('make', ['install'], { stdio: 'inherit', env, cwd })
}
async function buildGCC3 (sourceDirectory, sysroot, rootfs) {
async function buildGCC3 (sourceDirectory, sysroot, rootfs, options) {
const cwd = path.join(path.dirname(sourceDirectory), 'build-gcc');
await fs.rm(cwd, { recursive: true, force: true })
await fs.mkdir(cwd)
@ -318,7 +343,7 @@ async function buildGCC3 (sourceDirectory, sysroot, rootfs) {
'--with-default-libstdcxx-abi=new',
'--disable-nls',
`--target=${target}`,
`--build=${build}`,
`--build=${options.build}`,
`--host=${target}`
]
const flags = '-O2 -fPIC'
@ -351,23 +376,27 @@ async function createRoot (rootfs) {
const sysroot = path.join(tmp, 'sysroot')
const rootfs = path.join(tmp, 'rootfs')
const options = {
build: await findBuildTarget()
}
for (const targetDirectory of [tmp, sysroot, rootfs]) {
await fs.rm(targetDirectory, { recursive: true, force: true })
await fs.mkdir(targetDirectory)
}
const binutilsSource = await buildCrossBinutils(sysroot)
const gccSource = await buildGCC1(sysroot, rootfs)
const gccSource = await buildGCC1(sysroot, rootfs, options)
const kernelImage = await buildKernel(sysroot, rootfs)
await buildGlibc(sysroot, rootfs)
await buildBinutils(binutilsSource, sysroot, rootfs)
await buildGCC2(gccSource, sysroot, rootfs)
await buildGlibc(sysroot, rootfs, options)
await buildBinutils(binutilsSource, sysroot, rootfs, options)
await buildGCC2(gccSource, sysroot, rootfs, options)
buildInit (sysroot)
await buildBusyBox(sysroot, rootfs)
await createRoot(rootfs)
await buildGCC3(gccSource, sysroot, rootfs)
await buildGCC3(gccSource, sysroot, rootfs, options)
createImage(rootfs)
console.log(kernelImage)