dinit
dinit copied to clipboard
Draft: meson: Meson build system for dinit!
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:
- Its clean by default
- Have build-in support for depends
- 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.hin meson - [x] When host_platform is not linux; dont build shutdown/reboot/halt
- [x]
supprot_cgroupsoption inmeson_options.txt - [x]
use_utmpxoption inmeson_options.txt - [x]
shutdown_prefixoption inmeson_options.txt - [x] Have auto-detecter for
use_new_abioption - [x] Have auto-detecter for
cpp_rttioption - [x] Have auto-detecter for
-fno-pltcompiler flag - [x] Have auto-detecter for
supprot_cgroupsoption - [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]
fuzzsubproject - [ ] Complete docs
- [ ] Clean files
Signed-off-by: Mobin <[email protected]>
Why workflows run for "Draft" PR? I must fix it.
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.
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.
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.
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).
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.
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.
https://mesonbuild.com/Configuration.html
Note: you can do this without an input file, or with an input template.
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 :)
@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?
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.
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).
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-withoutautotoolscomes to vsmeson),
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
mesonandmakebuilds, but it seems like it would be expensive, Github actually only allocates 2000 minutes for free per account, and testingmesonandmakeat 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. ;)
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.
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
seems like on older meson (<0.56): cant set version in project(). i figure it out.
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.
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')
Thanks. Why wasn't this mentioned in the docs? I found it on https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/meson.build#L1261
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).
@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.
@davmac314 Hi; i have a question: we need to pass
-lrtto FreeBSD fuzzing? I think no because originalLDFLAGSin mconfig not applied onfuzztarget.
I have never tried to run the fuzzer on FreeBSD, but: if it links fine without -lrt, then it doesn't need -lrt :)
@davmac314 Hi; i have a question: we need to pass
-lrtto FreeBSD fuzzing? I think no because originalLDFLAGSin mconfig not applied onfuzztarget.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.
@davmac314 seems like; you right! :)
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.
Seems like -fno-plt broke Integration tests in FreeBSD 12.3. Dinit crashed with SIGFAULT
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 testenvironment().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
fsmodule 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! :)
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 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.
i will re-review this when i get a bit more time