I've spent a fair amount of time on this and in the end I will be sticking with plain Makefiles.
I did some benchmarks and found that at the scale my project is right now, a no-change build takes the same time with Ninja and Make. A build from scratch is actually slower with Meson because it needs to generate the build files and it's all implemented in python. This seems to be consistent with benchmarks available on the Internet.
The complexity of my Makefiles and Meson build files are about the same. But Makefiles are one less dependency and far more flexible.
Here are some of the meson files I built for posterity and anyone looking in to Meson in the future. Note: this doesn't address the crti/crtn/crtbegin/crtend link order, see posts above for a possible solution using a link script.
Cross-file for EFI bootloader:
Code: Select all
[binaries]
c = ['x86_64-rainbow-elf-gcc', '-fpic', '-mno-red-zone']
cpp = ['x86_64-rainbow-elf-gcc', '-fpic', '-mno-red-zone']
ar = 'x86_64-rainbow-elf-ar'
objcopy = 'x86_64-rainbow-elf-objcopy'
strip = 'x86_64-rainbow-elf-strip'
[host_machine]
system = 'rainbow'
cpu_family = 'x86'
cpu = 'x86_64'
endian = 'little'
[built-in options]
cpp_eh='none'
cpp_rtti=false
cpp_link_args=[
'-shared',
'-Bsymbolic',
'-Wl,-pie'
]
Main meson.build file:
Code: Select all
project('boot', ['c', 'cpp'], version : '1.0')
objcopy = find_program('objcopy')
add_project_arguments('-ffreestanding', '-fbuiltin', '-mgeneral-regs-only', language: ['c', 'cpp'])
add_project_link_arguments('-nostdlib', '-z', 'noexecstack', language: ['c', 'cpp'])
includes = [
'../include',
'../third_party',
...
]
sources = files(
'boot.cpp',
'display.cpp',
'memory.cpp',
...
)
link_script = 'efi.lds'
cpp = meson.get_compiler('cpp')
libgcc = cpp.find_library('libgcc')
crtbegin = run_command(cpp, '-print-file-name=crtbegin.o').stdout().strip()
crtend = run_command(cpp, '-print-file-name=crtend.o').stdout().strip()
libs = [
libgcc,
]
bootloader = executable('bootloader',
sources: sources,
objects: [crtbegin, crtend],
include_directories: includes,
dependencies: libs,
link_args: [
'-T' + meson.source_root() / link_script,
],
link_depends: link_script,
)
custom_target(
'bootloader.efi',
input: bootloader,
output: 'boot.efi',
command: [ objcopy,
'-j', '.text',
'-j', '.rodata',
'-j', '.data',
'-j', '.dynamic',
'-j', '.dynsym',
'-j', '.rel.*',
'-j', '.rela.*',
'-j', '.reloc',
'--target', 'efi-app-x86_64',
'@INPUT@',
'@OUTPUT@'
],
build_by_default: true,
)