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. - Error message with an empty file wrongly says that a ")" is expected.
- Support any expressions for constants. - Support any expressions for constants.
- Name analysis should fail if there are undefined symbols. - 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 childProcess from 'node:child_process'
import process from 'process' import process from 'process'
import os from 'os' import os from 'os'
import { Buffer } from 'node:buffer'
// Define constants. // Define constants.
const tmp = path.resolve('./build/tools') const tmp = path.resolve('./build/tools')
const target = 'riscv32-unknown-linux-gnu' const target = 'riscv32-unknown-linux-gnu'
const build = 'x86_64-slackware-linux'
const baseDirectory = path.resolve('./tools') const baseDirectory = path.resolve('./tools')
const busyboxVersion = '1.36.1' const busyboxVersion = '1.36.1'
const kernelVersion = '5.15.158' const kernelVersion = '5.15.158'
const gccVersion = '13.2.0' const gccVersion = '14.1.0'
const binutilsVersion = '2.42' const binutilsVersion = '2.42'
const glibcVersion = '2.39' 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) { function createImage (rootfs) {
const rootExt4 = path.join(tmp, 'rootfs.ext4') 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 }) 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( const sourceDirectory = await downloadAndUnarchive(
new URL(`https://ftp.gnu.org/gnu/glibc/glibc-${glibcVersion}.tar.xz`) new URL(`https://ftp.gnu.org/gnu/glibc/glibc-${glibcVersion}.tar.xz`)
) )
@ -120,7 +145,7 @@ async function buildGlibc (sysroot, rootfs) {
'--prefix=/usr', '--prefix=/usr',
'--libdir=/usr/lib', '--libdir=/usr/lib',
`--host=${target}`, `--host=${target}`,
`--build=${build}`, `--build=${options.build}`,
`--enable-kernel=${kernelVersion}`, `--enable-kernel=${kernelVersion}`,
`--with-headers=${path.join(rootfs, 'usr/include')}`, `--with-headers=${path.join(rootfs, 'usr/include')}`,
'--disable-nscd' '--disable-nscd'
@ -166,9 +191,9 @@ async function buildCrossBinutils (sysroot) {
return sourceDirectory return sourceDirectory
} }
async function buildGCC1 (sysroot, rootfs) { async function buildGCC1 (sysroot, rootfs, options) {
const sourceDirectory = await downloadAndUnarchive( 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'); const cwd = path.join(path.dirname(sourceDirectory), 'build-gcc');
await fs.mkdir(cwd) await fs.mkdir(cwd)
@ -201,8 +226,8 @@ async function buildGCC1 (sysroot, rootfs) {
'--with-newlib', '--with-newlib',
'--without-headers', '--without-headers',
`--target=${target}`, `--target=${target}`,
`--build=${build}`, `--build=${options.build}`,
`--host=${build}` `--host=${options.build}`
] ]
const flags = '-O2 -fPIC' const flags = '-O2 -fPIC'
const env = { const env = {
@ -222,14 +247,14 @@ async function buildGCC1 (sysroot, rootfs) {
return sourceDirectory return sourceDirectory
} }
async function buildBinutils (sourceDirectory, sysroot, rootfs) { async function buildBinutils (sourceDirectory, sysroot, rootfs, options) {
const cwd = path.join(path.dirname(sourceDirectory), 'build-binutils'); const cwd = path.join(path.dirname(sourceDirectory), 'build-binutils');
await fs.rm(cwd, { recursive: true, force: true }) await fs.rm(cwd, { recursive: true, force: true })
await fs.mkdir(cwd) await fs.mkdir(cwd)
const configureOptions = [ const configureOptions = [
'--prefix=/usr', '--prefix=/usr',
`--build=${build}`, `--build=${options.build}`,
`--host=${target}`, `--host=${target}`,
`--with-build-sysroot=${rootfs}`, `--with-build-sysroot=${rootfs}`,
'--disable-nls', '--disable-nls',
@ -253,7 +278,7 @@ async function buildBinutils (sourceDirectory, sysroot, rootfs) {
return sourceDirectory return sourceDirectory
} }
async function buildGCC2 (sourceDirectory, sysroot, rootfs) { async function buildGCC2 (sourceDirectory, sysroot, rootfs, options) {
const cwd = path.join(path.dirname(sourceDirectory), 'build-gcc'); const cwd = path.join(path.dirname(sourceDirectory), 'build-gcc');
await fs.rm(cwd, { recursive: true, force: true }) await fs.rm(cwd, { recursive: true, force: true })
await fs.mkdir(cwd) await fs.mkdir(cwd)
@ -276,8 +301,8 @@ async function buildGCC2 (sourceDirectory, sysroot, rootfs) {
'--with-default-libstdcxx-abi=new', '--with-default-libstdcxx-abi=new',
'--disable-nls', '--disable-nls',
`--target=${target}`, `--target=${target}`,
`--build=${build}`, `--build=${options.build}`,
`--host=${build}` `--host=${options.build}`
] ]
const flags = '-O2 -fPIC' const flags = '-O2 -fPIC'
const env = { const env = {
@ -295,7 +320,7 @@ async function buildGCC2 (sourceDirectory, sysroot, rootfs) {
childProcess.execFileSync('make', ['install'], { stdio: 'inherit', env, cwd }) 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'); const cwd = path.join(path.dirname(sourceDirectory), 'build-gcc');
await fs.rm(cwd, { recursive: true, force: true }) await fs.rm(cwd, { recursive: true, force: true })
await fs.mkdir(cwd) await fs.mkdir(cwd)
@ -318,7 +343,7 @@ async function buildGCC3 (sourceDirectory, sysroot, rootfs) {
'--with-default-libstdcxx-abi=new', '--with-default-libstdcxx-abi=new',
'--disable-nls', '--disable-nls',
`--target=${target}`, `--target=${target}`,
`--build=${build}`, `--build=${options.build}`,
`--host=${target}` `--host=${target}`
] ]
const flags = '-O2 -fPIC' const flags = '-O2 -fPIC'
@ -351,23 +376,27 @@ async function createRoot (rootfs) {
const sysroot = path.join(tmp, 'sysroot') const sysroot = path.join(tmp, 'sysroot')
const rootfs = path.join(tmp, 'rootfs') const rootfs = path.join(tmp, 'rootfs')
const options = {
build: await findBuildTarget()
}
for (const targetDirectory of [tmp, sysroot, rootfs]) { for (const targetDirectory of [tmp, sysroot, rootfs]) {
await fs.rm(targetDirectory, { recursive: true, force: true }) await fs.rm(targetDirectory, { recursive: true, force: true })
await fs.mkdir(targetDirectory) await fs.mkdir(targetDirectory)
} }
const binutilsSource = await buildCrossBinutils(sysroot) const binutilsSource = await buildCrossBinutils(sysroot)
const gccSource = await buildGCC1(sysroot, rootfs) const gccSource = await buildGCC1(sysroot, rootfs, options)
const kernelImage = await buildKernel(sysroot, rootfs) const kernelImage = await buildKernel(sysroot, rootfs)
await buildGlibc(sysroot, rootfs) await buildGlibc(sysroot, rootfs, options)
await buildBinutils(binutilsSource, sysroot, rootfs) await buildBinutils(binutilsSource, sysroot, rootfs, options)
await buildGCC2(gccSource, sysroot, rootfs) await buildGCC2(gccSource, sysroot, rootfs, options)
buildInit (sysroot) buildInit (sysroot)
await buildBusyBox(sysroot, rootfs) await buildBusyBox(sysroot, rootfs)
await createRoot(rootfs) await createRoot(rootfs)
await buildGCC3(gccSource, sysroot, rootfs) await buildGCC3(gccSource, sysroot, rootfs, options)
createImage(rootfs) createImage(rootfs)
console.log(kernelImage) console.log(kernelImage)