mesonbuild / meson

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

Adding library and include directory #11570

Open r2com opened 1 year ago

r2com commented 1 year ago

I went through the default tutorial and trying to get the proper compile operations with my meson.build First of all, let me show what I need meson to do for me:

gcc -I/home/r2com/eda/install/ghdl/include/ghdl -c ../tb/test.c -o vpi.o -fPIC
gcc -o vpi.vpi vpi.o --shared -L/home/r2com/eda/install/ghdl/lib -lghdl

In above, it is done manually without any build system, as you see for first command I do add include directory, specify source file and output .o file, plus some special flag.

In the second command I link the vpi.vpi executable with shared flag and adding library ghdl

So I do understand that I must add directory as: inc = include_directories('/home/r2com/eda/install/ghdl/include/ghdl')

But how to make sure it will be part of compilation and not linking (like second row of commands in my example) ?

And then, how do I add properly the library? For my meson.build which is:

project('test', 'c')
inc = include_directories('/home/r2com/eda/install/ghdl/include/ghdl')
add_global_arguments('-fPIC', '-L/home/r2com/eda/install/ghdl/lib', '-lghdl', language : 'c')
executable('vpi.vpi', 'test.c', include_directories : inc)

It did not work and complained about undefined references in vpi_* functions which are located in vpi_user.h file referenced from test.c, and that file is located in the directory I showed with -I

Can you give me a hint for proper meson.build file to successfully perform the two commands I shown on top?

eli-schwartz commented 1 year ago

Does the ghdl library come with a pkg-config file? That would make this a lot easier.

Failing that, the -lghdl flag needs to be add_global_link_arguments if you want it to apply to the link stage. But you may prefer to add it to the executable() using link_args.

The "proper" solution is pkg-config or else using

cc = meson.get_compiler('c')

ghdl_lib = cc.find_library('ghdl', dirs: '/home/r2com/eda/install/ghdl/lib')

executable(..., dependencies: ghdl_lib)
r2com commented 1 year ago

it does not seem to come with pkg-config file I modified my meson.build this way:

project('test', 'c')
cc = meson.get_compiler('c')
inc = include_directories('/home/r2com/eda/install/ghdl/include/ghdl')
add_global_arguments('-fPIC', language : 'c')
ghdl_lib = cc.find_library('ghdl', dirs: '/home/r2com/eda/install/ghdl/lib')
executable('vpi.vpi', 'test.c', include_directories : inc, dependencies: ghdl_lib)

But get the errors:

[2/2] Linking target vpi.vpi
FAILED: vpi.vpi 
cc  -o vpi.vpi vpi.vpi.p/test.c.o -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group /home/r2com/eda/install/ghdl/lib/libghdl.a -Wl,--end-group
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x17): undefined reference to `main'
/usr/bin/ld: vpi.vpi.p/test.c.o: in function `vpi_clk_proc':
/home/r2com/projects/fpga/vpitest1/vip/build/../test.c:29: undefined reference to `vpi_get_value'

etc etc.

Again, when I run above two commands as shown in my original post, it all compiles fine without any errors/warnings.

What else am I missing?

Also, why is it calling "cc" and not gcc as you see above? And also why it adds additional flags which I didnt ask it to add as these: -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group

eli-schwartz commented 1 year ago

Also, why is it calling "cc" and not gcc as you see above?

cc is probably a symlink to gcc on most systems, meson detects a bunch of possible compilers -- clang, gcc, microsoft's MSVC compiler on Windows, and a few that you've probably never heard of, such as the nvidia HPC compiler, ccrx, xc16, compcert, ti, c2000...

cc is the standard for "I just want whichever one is the default on my machine". You can choose a specific one by setting CC=gcc in the environment, but it shouldn't make a difference.

And also why it adds additional flags which I didnt ask it to add as these: -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group

This is some meson core options: https://mesonbuild.com/Builtin-options.html

-Db_asneeded=true -Db_lundef=true is the default if you don't specify any of them as =false on the command line when configuring meson. The former just means that if you add too many -lfoo arguments and don't use them all, the linker drops them as unused. The latter is supposed to produce errors about undefined references, since in most cases undefined references are a bug.

Question: where is vpi_get_value supposed to come from?

If you really are supposed to have an undefined reference, you can change this:

project('test', 'c')

to this:

project('test', 'c', default_options: ['b_lundef=false']`)

and disable this by default. See also the per-target override_options: [] kwarg for executable().

r2com commented 1 year ago

_Question: where is vpi_getvalue supposed to come from? ^ it comes from vpi_user.h which is included in test.c and located in: "home/r2com/eda/install/ghdl/include/ghdl" as shown in included directories.

So the script seems easy and my goal is not something out of this world, yet I'm having issues using this system. especially confusing is the default switches (core options) which now I have to struggle with.

I feel that meson lacks the reasonable examples library, that "lets compile hello world" type example in the main manual is not helpful at all. And just looking at reference commands and executing them according to the logic is not getting it anywhere because of hidden quirks and "features" which I'm stumbling upon...