dinit icon indicating copy to clipboard operation
dinit copied to clipboard

Draft: meson: Meson build system for dinit!

Open mobin-2008 opened this issue 3 years ago • 28 comments

Hi!

Goal

Meson build system for dinit project!

Why?

I have thought about it for a while. dinit currently uses make and I think that's enough for now, but the benefits of meson have been tempting me for a while. Actually, this discussion whether to use meson or make goes back to another discussion (not exactly): Low-level tools vs. high-level tools: In the computer world, usually as you move towards the lower levels, the structural limitations that software and programming languages ​​impose on the user become less. In fact (usually) low-level tools leave the user open for different tasks, it can be said that in this case, less work is done by the low-level tool and the user has to do more work. This may seem like a weakness, but I see it as a "trait" because it's not always good or bad, but good or bad depending on the situation. The good thing about this issue is that the user can do his work in the desired way. On the contrary, it can be said that high-level tools are usually designed to do more work by themselves and put the user's work in a certain framework. This problem makes the user unable to carry out the work according to his wishes due to structural limitations. In fact, the issue of the user's freedom of action is discussed

long story in short: we need a good balance, do we need make's low-level features? Or is it better to use a build system like Meson?

Advantages of meson:

  1. Its clean by default
  2. Have build-in support for depends
  3. Better compatibility betwen platforms

All of "Advantages of meson" can be done in Make, but there are several problems: 1- It needs a lot of work and time 2- It is usually not optimal (in terms of speed, stability, etc.)

I will say more about it in the future, for now I think its enough. regards

ToDo

  • [x] Initial meson.build
  • [x] Initial meson_options.txt
  • [x] Prepare & create mconfig.h in meson
  • [x] When host_platform is not linux; dont build shutdown/reboot/halt
  • [x] supprot_cgroups option in meson_options.txt
  • [x] use_utmpx option in meson_options.txt
  • [x] shutdown_prefix option in meson_options.txt
  • [x] Have auto-detecter for use_new_abi option
  • [x] Have auto-detecter for cpp_rtti option
  • [x] Have auto-detecter for -fno-plt compiler flag
  • [x] Have auto-detecter for supprot_cgroups option
  • [x] Set required meson version in meson.build (E.g: meson_version : '>= 0.53.2')
  • [x] Unit tests option & target
  • [x] Integration tests option & target
  • [x] Prepare & install man-pages
  • [x] fuzz subproject
  • [ ] Complete docs
  • [ ] Clean files

Signed-off-by: Mobin <[email protected]>

mobin-2008 avatar Sep 12 '22 19:09 mobin-2008

Why workflows run for "Draft" PR? I must fix it.

mobin-2008 avatar Sep 12 '22 19:09 mobin-2008

To be clear, I don't want to use meson as the default build system for dinit. I prefer that dinit can be built on a minimal POSIX system without additional dependencies (including build tools). In particular meson pulls in Python as a build-time dependency which I would definitely prefer to avoid.

All tools (eg m4) required for building at the moment, other than a C++ compiler, are already required by POSIX.

If you would like to continue this and offer meson build as an alternative, alongside the existing makefiles, that's fine - but please understand that it won't be the default. Also CI should continue to use the default (make). I will personally continue to develop without building using meson.

davmac314 avatar Sep 13 '22 03:09 davmac314

To be clear, I don't want to use meson as the default build system for dinit. I prefer that dinit can be built on a minimal POSIX system without additional dependencies (including build tools). In particular meson pulls in Python as a build-time dependency which I would definitely prefer to avoid.

All tools (eg m4) required for building at the moment, other than a C++ compiler, are already required by POSIX.

If you would like to continue this and offer meson build as an alternative, alongside the existing makefiles, that's fine - but please understand that it won't be the default. Also CI should continue to use the default (make). I will personally continue to develop without building using meson.

I agree. its experimental & we dont want to deprecate Make for one simple reason: "Make" Available on everywhere (Linux; FreeBSD; MacOS & some another UNIX systems) & dont need to "Runtime depends" because its written in C.

mobin-2008 avatar Sep 13 '22 03:09 mobin-2008

I prefer that dinit can be built on a minimal POSIX system without additional dependencies (including build tools). In particular meson pulls in Python as a build-time dependency which I would definitely prefer to avoid.

This is less of a problem than it sounds, really. https://sr.ht/~lattis/muon is a c99 implementation of Meson, which is a significantly less complex build-time dependency than python (although it's still a tool that isn't preinstalled via posix) and is very easily bootstrapped.

eli-schwartz avatar Sep 13 '22 04:09 eli-schwartz

https://sr.ht/~lattis/muon is a c99 implementation of Meson,

I was aware of muon - it's still an extra dependency though, and it has some limitations (eg it apparently doesn't support cross-compilation, which the Makefiles handle just fine).

davmac314 avatar Sep 13 '22 09:09 davmac314

I add shutdown/reboot/halt building to meson. its have build_shutdown option & its can be set to enabled, disabled & auto. if that option set to auto; because dinit dont support shutdown on other POSIX oses (Only Linux supported); if host system not a Linux based; meson do not generate shutdown/reboot/halt. Now there is one problem: can we have something like SHUTDOWN_PREFIX in meson? In addition, several things have been fixed.

mobin-2008 avatar Sep 13 '22 11:09 mobin-2008

I search about it; but founds nothing. How to set #define in meson? I mean can set some #defines as preprocesser argument? We use a mconfig.h file. this file have some #defines to set some options. mconfig file genraeted by make & mconfig-gen.cc make it toC/ C++ style: https://github.com/davmac314/dinit/blob/7bee6fe92c8961cbf7ecd7d1452dff1d9890cae2/build/tools/mconfig-gen.cc#L70-L72 We can use this #define when we need compile cgroups specifce sections/codes: https://github.com/davmac314/dinit/blob/7bee6fe92c8961cbf7ecd7d1452dff1d9890cae2/src/dinit.cc#L355-L358

If its possible; we can remove mconfig.h in meson builds and use meson options.

mobin-2008 avatar Sep 13 '22 18:09 mobin-2008

https://mesonbuild.com/Configuration.html

Note: you can do this without an input file, or with an input template.

eli-schwartz avatar Sep 13 '22 18:09 eli-schwartz

https://mesonbuild.com/Configuration.html

Note: you can do this without an input file, or with an input template.

Yep; i think to do this without original mconfig Thanks :)

mobin-2008 avatar Sep 13 '22 18:09 mobin-2008

@davmac314 I add a auto-detecter for use_new_abi. Usually libstdc++ is bundled with c++ compiler. This means that they usually have similar versions, since checking the libstdc++ version is simply not possible, we check the compiler version instead. Just one question, in which version of clang++ should use_new_abi be used/not used?

mobin-2008 avatar Sep 17 '22 06:09 mobin-2008

The more I work with meson, the more I like it. It provides a good framework for writing everything. I also thought about maintaining make: I will maintain make. It's actually a good balance: if you have meson, I suggest you use it, meson is faster (I'm a bit unsure about it, especially when standalone make-without autotools comes to vs meson), cleaner and more automated than make, but if you don't use meson for whatever reason, no problem, you'll only need a make and dinit (& several POSIX-critical tools like sh). I don't intend to consider make deprecated, probably after this PR, I will go for several patches for dinit's make. About CI: I wanted ci to test both meson and make builds, but it seems like it would be expensive, Github actually only allocates 2000 minutes for free per account, and testing meson and make at the same time is a waste of time. almost doubles the I will test dinit with Meson myself.

mobin-2008 avatar Sep 17 '22 19:09 mobin-2008

Just one question, in which version of clang++ should use_new_abi be used/not used?

The problem is in libstdc++, so it depends on the libstdc++ version that it uses (if any), but I don't know if there's any easy way to check that. The problem is gone now even with newer versions of gcc/libstdc++ so you could probably just assume that if clang++ is the compiler then there's no need to define the macro to specify the ABI (especially since clang might be using libc++ instead).

About CI: I wanted ci to test both meson and make builds

The make build will be the official build and the meson build is an extra contribution that will need to be maintained by yourself (or other external contributors) - so CI shouldn't fail if the meson build gets broken. (I don't want to have to maintain two build systems and other contributors shouldn't need to worry about two build systems).

davmac314 avatar Sep 17 '22 23:09 davmac314

It's actually a good balance: if you have meson, I suggest you use it, meson is faster (I'm a bit unsure about it, especially when standalone make-without autotools comes to vs meson),

Meson is equivalent to autotools, ninja is equivalent to make.

Ninja is faster than Make, in part because ninja assumes you generate the ninja file and doesn't include "slow" features like pattern rules, default rules, macros, guile script bindings... whether meson is faster than make depends on how much stuff you do in make, such as $(shell ...) -- the standard way for Makefiles to implement meson-comparable features without autotools.

So, once you have generated a build directory with meson, ninja is always going to be a little bit faster. OTOH if you're not doing much startup in Make other than doing an OS check and symlinking a static platform config, you're not paying much in terms of the Make tax.

About CI: I wanted ci to test both meson and make builds, but it seems like it would be expensive, Github actually only allocates 2000 minutes for free per account, and testing meson and make at the same time is a waste of time. almost doubles the

That doesn't sound right -- the Github Actions limits for public OSS repositories aren't based on minutes, you should get unlimited minutes. Although sometimes you do wait a bit for an available runner -- Meson itself has about 30 CI jobs including a Windows cygwin job that takes anywhere from 1 to 2 hours, 2 hours worth of MSYS2 jobs, an hour worth of macOS jobs, and 12 linux jobs that take between 15 and 30 minutes each.

And macOS jobs get a 10x multiplier, and Windows ones a 2x multiplier, for the minutes they use.

Meson doesn't pay for minutes, but any time two PRs, or one push and one PR, is running at the same time, we wait hours for one set of jobs to finish before the next can begin. ;)

eli-schwartz avatar Sep 18 '22 01:09 eli-schwartz

That doesn't sound right -- the Github Actions limits for public OSS repositories aren't based on minutes, you should get unlimited minutes. Although sometimes you do wait a bit for an available runner -- Meson itself has about 30 CI jobs including a Windows cygwin job that takes anywhere from 1 to 2 hours, 2 hours worth of MSYS2 jobs, an hour worth of macOS jobs, and 12 linux jobs that take between 15 and 30 minutes each.

And macOS jobs get a 10x multiplier, and Windows ones a 2x multiplier, for the minutes they use.

Meson doesn't pay for minutes, but any time two PRs, or one push and one PR, is running at the same time, we wait hours for one set of jobs to finish before the next can begin. ;)

Ok; thanks for information. I think about it. Form docs.github.com:

GitHub Actions usage is free for standard GitHub-hosted runners in public repositories, and for self-hosted runners. For private repositories, each GitHub account receives a certain amount of free minutes and storage for use with GitHub-hosted runners, depending on the product used with the account. Any usage beyond the included amounts is controlled by spending limits.

mobin-2008 avatar Sep 18 '22 05:09 mobin-2008

I have already set up target fuzz. I'm a bit confused about meson subprojects in docs. My goal is for fuzz to be a separate part from the parts of dinit, meaning that fuzz is never compiled with other executables. Subproject doesn't seem to offer that.

@eli-schwartz it seems meson can't set the default compiler. This issue has been brought up before and seems to have been rejected due to "not having a real situation that requires this feature". Now we need fuzz to be compiled with clang/clang++. I know it's not hard to do but it seems nice to have such a feature.

regards

mobin-2008 avatar Sep 21 '22 09:09 mobin-2008

seems like on older meson (<0.56): cant set version in project(). i figure it out.

mobin-2008 avatar Sep 22 '22 10:09 mobin-2008

Its looks very weird but i cant add a value to meson options. We need to add -lrt to cpp_link_args for FreeBSD uses but i cant add a value to get_option(cpp_link_args):

meson.build:63:2: ERROR: Plusassignment target must be an id.
  get_option('cpp_link_args') += '-lrt'

I search about it in meson docs & google but finds nothing.

mobin-2008 avatar Sep 22 '22 17:09 mobin-2008

Neither the get_option function nor its return value is a variable pointer, so you cannot assign it a value. And if you could, then it still wouldn't make the coredata see such a change.

If you want to add additional global link arguments, there's a dedicated function for that:

add_global_link_arguments('-lrt', language: 'c')

eli-schwartz avatar Sep 22 '22 17:09 eli-schwartz

Thanks. Why wasn't this mentioned in the docs? I found it on https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/meson.build#L1261

mobin-2008 avatar Sep 22 '22 18:09 mobin-2008

Also i use add_project_argument instead of add_global_argument. its recommended for some reasons (such as: with add_global_argument; project cant be used as subproject).

mobin-2008 avatar Sep 22 '22 18:09 mobin-2008

@davmac314 Hi; i have a question: we need to pass -lrt to FreeBSD fuzzing? I think no because original LDFLAGS in mconfig not applied on fuzz target.

mobin-2008 avatar Sep 22 '22 19:09 mobin-2008

@davmac314 Hi; i have a question: we need to pass -lrt to FreeBSD fuzzing? I think no because original LDFLAGS in mconfig not applied on fuzz target.

I have never tried to run the fuzzer on FreeBSD, but: if it links fine without -lrt, then it doesn't need -lrt :)

davmac314 avatar Sep 22 '22 23:09 davmac314

@davmac314 Hi; i have a question: we need to pass -lrt to FreeBSD fuzzing? I think no because original LDFLAGS in mconfig not applied on fuzz target.

I have never tried to run the fuzzer on FreeBSD, but: if it links fine without -lrt, then it doesn't need -lrt :)

I try it on FreeBSD.

mobin-2008 avatar Sep 23 '22 08:09 mobin-2008

@davmac314 seems like; you right! :)

mobin-2008 avatar Sep 23 '22 08:09 mobin-2008

I Implement unit tests in meson. everything looks good but loadtests fails for no reason. its "Aborted" by system via SIGABRT!

==================================== 4/5 =====================================
test:         loadtests
start time:   12:16:10
duration:     0.01s
result:       killed by signal 6 SIGABRT
command:      MALLOC_PERTURB_=212 /home/mobin/dinit_on_meson/github_fork/dinit/dirbuild/loadtests
----------------------------------- stdout -----------------------------------
test_basic...                
----------------------------------- stderr -----------------------------------
terminate called after throwing an instance of 'service_not_found'

its ok on make builds but fails on meson. includes or compiler/linker flags is broken? i figure it out.

mobin-2008 avatar Sep 25 '22 12:09 mobin-2008

Seems like -fno-plt broke Integration tests in FreeBSD 12.3. Dinit crashed with SIGFAULT

mobin-2008 avatar Sep 27 '22 10:09 mobin-2008

I am happy to say that the works are almost finished. Everything looks good and there are only a few possible improvements left such as:

  • Use environment() in man-pages generation, unit & integration tests its very better to use general environment() in that things. i test environment().set() but seems like dont work.
  • When linux kernel is very old; dont enable cgroups support. because its not supported on old linux kernels.
  • for later; use fs module instead of reading files via script when oses updated to newer mesons.

For now its ready (after doing some ToDo things about docs) Also code review is very helpful! :)

mobin-2008 avatar Oct 03 '22 19:10 mobin-2008

To be clear, I don't want to use meson as the default build system for dinit. I prefer that dinit can be built on a minimal POSIX system without additional dependencies (including build tools). In particular meson pulls in Python as a build-time dependency which I would definitely prefer to avoid.

All tools (eg m4) required for building at the moment, other than a C++ compiler, are already required by POSIX.

you require GNU make specifically though, which implements tons of poorly specified extensions over POSIX, so that's not exactly clean

q66 avatar Oct 05 '22 14:10 q66

@q66 Thanks for your review :)

but otherwise i see lots of other issues with this implementation

What are that problems? For example please mention that if you like to do it.

mobin-2008 avatar Oct 16 '22 17:10 mobin-2008

i will re-review this when i get a bit more time

q66 avatar Nov 13 '22 14:11 q66