mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.66k stars 1.64k forks source link

meson looks for c compiler when it shouldn't #12565

Open stsp opened 1 year ago

stsp commented 1 year ago

Describe the bug meson.build:

project('kernel', 'nasm', version: '1.7')

toolchain.ini:

[binaries]
nasm = 'nasm'

[constants]
arch = 'i386-linux-gnu'

[host_machine]
system = 'linux'
cpu_family = 'x86'
cpu = 'i386'
endian = 'little'

Attempt to configure:

$ meson setup --cross-file ../toolchain.ini . ..
The Meson build system
Version: 1.2.1
Source dir: /home/stas/src/fdpp/fdpp/kernel/t
Build dir: /home/stas/src/fdpp/fdpp/kernel/t/build
Build type: cross build
Project name: kernel
Project version: 1.7

../meson.build:1:0: ERROR: 'c' compiler binary not defined in cross or native file

Why does it look for a c compiler, if I asked for nasm?

tristan957 commented 1 year ago

cc @xclaesse @nirbheek

bonzini commented 1 year ago

It's looking for the C compiler in order to use it as a linker.

bonzini commented 1 year ago

For example,

f.asm:

global main
main:
xor eax, eax
ret

meson.build:

project('kernel', 'nasm', version: '1.7')
executable('f', 'f.asm')

Compilation:

$ ninja -v
[1/2] nasm -f elf64 -DELF -D__x86_64__ -O0 -g -F dwarf -I.. -I. -If.p -MD f.p/f.asm.o.d -MQ f.p/f.asm.o -o f.p/f.asm.o ../f.asm
[2/2] cc  -o f f.p/f.asm.o -Wl,--allow-shlib-undefined
stsp commented 1 year ago

This is what I am fighting with right now. I need a custom link process. How can I tell meson to please don't use C linker? nasm_ld is not supported.

bonzini commented 1 year ago

Would your linking phase use ld directly?

I think you need to use a static library to invoke nasm, then extract_objects and a custom_target for the linking phase.

stsp commented 1 year ago

Yes, I need to use cross-ld directly. Can I avoid the "static lib" step, and just operate with a plain list of objects? I can't find a possibility to tell meson to run compilation only, so is the static lib an only solution here?

stsp commented 1 year ago

And the problem is, even if I don't use executable(), meson still insists on defining a C compiler. Which is a bug I think, because I will use the linker directly and no where I asked meson to use C linker.

bonzini commented 1 year ago

Can I avoid the "static lib" step, and just operate with a plain list of objects?

If the library is build_by_default: false, it will actually not be built. The static library is just a way to trigger the compilation, and have something that supports extract_objects() or extract_all_objects().

I agree that it would be nicer if the C compiler would only be required by the linking step, but I think Meson decides which languages are in use at the time it evaluates project().

stsp commented 1 year ago

but I think Meson decides which languages are in use at the time it evaluates project()

But I explicitly put 'nasm' there! :) So is it a bug, right?

Thanks for a build_by_default trick, went trying...

bonzini commented 1 year ago

But I explicitly put 'nasm' there! :) So is it a bug, right?

You put "nasm" and Meson interprets that as "I want to build executables using the nasm language". Which requires a C compiler, because Meson right now cannot invoke ld directly.

The tricky part is that some pure-asm programs may still want to link to libc. Therefore, switching nasm to use ld directly is not obviously correct either. It could be considered a regression to require link_language: 'c' for such programs.

I understand why you see it as a bug but I see why the developers would treat it as a "can't fix" situation.

stsp commented 1 year ago

So what to do? Add some dummy C compiler def to the binaries section?

stsp commented 1 year ago

It could be considered a regression to require link_language: 'c' for such programs.

I think you don't have to. You may still use C link for the executable() case, but I won't be using executable(). So I don't think this is unfixable/regressible situation.

stsp commented 1 year ago

Now I have to specify build_by_default: true for the final custom_target(), otherwise nothing is built at all. I wonder if this is the only way to achieve building. Can I instead list the explicit targets that are needed to be built for this project?

bonzini commented 1 year ago

Use staticlib.extract_all_objects(recursive: true) as the inputs to the custom target.

stsp commented 1 year ago

I added recursive: true (otherwise I did exactly the same), and it didn't change anything. Not sure why it had. meson simply doesn't know what to build, and build_by_default seems false for custom_target() by default.

bonzini commented 1 year ago

Yes, you need build_by_default: true for the custom target and build_by_default: false for the static library.

stsp commented 1 year ago

But is there no way to explicitly specify the needed targets for the project? build_by_default: true looks like a hack. Can't I specify the needed target explicitly? That would be very strange.