-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build system needs replacing #200
Comments
The time to do it would certainly be after the merge of the CMake is not perfect, but is widely adopted and understood and does come with a lot of useful macro functions. It would also be a good time to start at the beginning, create a build from the ground up, instead of just trying to fit the existing Submakefiles into CMakeLists.txt files. If all binaries and libs were built within their respective directories, instead of objects and deps being moved to temporary dirs and built en-masse with deceptively short commands, the whole build process would be a lot easier to understand and alter if required. |
I started looking into this issue in connection with #268 - as one deeply affect the other and this has been such a long-standing problem that it is probably high time to solve this. (Plus making head and tails of the Makefile/Configure system is a quite harrowing task now.) Currently, there is open the #250 pull request, which implements new CMake build system for Machinekit-HAL. However, it has several problems:
So all in all I think the best course of action forward it to gut #250 for the good parts and assemble new pull request. To the point of specific technologies, I think there are only two viable alternatives: Modern CMake and Meson. By Modern CMake I mean something post 3.10. Debian distributes 3.16 as far as I know in its backports repositories, but given the availability of Snap and Pip distributed CMake in (always) the latest version, getting later version is not an issue - which is why I would suggest developing it for the latest 3.18 version first and then backporting it to lower ones where viable (I think there is nothing really serious which would prevent this). The Meson option is possibility because it is under continuous development, the use base is growing and recently some heavy hitters started using it - so the changes it will stay there for prolonged period of time is quite high. The syntax is a bit better than CMake, I think (but there recently was discussion about new, more deterministic looking syntax in CMake community which would make this moot point), however it is a newer product and as such many issues which CMake had to solve already are so far unsolved (like the global-only namespace and such). CMake also supports both Make and Ninja, whereas Meson only supports Ninja. Anything else seems to be on the way out (namely the Autotools) with shrinking user base (primarily to the Meson and CMake). Additionally, I think it is time to do some reorganizing of the directory tree structure of Machinekit-HAL repository. (Maybe at the same time as a general code-formatting - I am not so sure how well git is at moving files, so one breaking change is better than two.) Because - at least to me - it looks (in some aspects) a bit messy. And this represents another barrier for first time developers. (Or at least it was additional entry barrier for me when starting out.) CMake doesn't impose any specific rules on the structure of repository in relation to build directory structure or installation directory structure. In other words, targets can output its artifacts to the same directory (flattening the original structure) and install wherever they want (additionally flatten the structure, for example [or deepening it arbitrarily]). What I have in mind:
From what I have written, I am talking only in terms of targets. Which is the Modern CMake approach (or at least they claim it in tutorials) and the reason why the 2.8 branches mentioned in first post of this issue are very probably useless. |
Looking some more into this problem I came up with few points which I would like to discuss here in the open (better now than later): When first encountering Machinekit's source code, for me at least it was, it is quite confusing to get what uses what and how is all connected together. Basically how the application is structured. It doesn't seem very transparent. There is the high abstraction of RTAPI and HAL, however (probably because of non-existent documentation) it's not clear how from that you get the binaries (or if you want to do some changes, where to put them). So I have been thinking about toning down a bit the high abstraction and structure the code more to the point of the output. (In no way I want to remove the HAL or RTAPI (runtime) differentiation.) More to the point of having:
Where So then would be:
And so on. In other words, I think the HAL is lot more comprehensible when one sees that it is a just bunch of libraries dlopened into some process memory. When one sees that Machinekit(-HAL) is just a rtapi_app and rtapi_msgd running together. The question is what to do about so-called userspace components (I use the so-called because even though I know the LinuxCNC history behind that term, I consider it in terms of Modern Machinekit quite terrible name which has potential to send some poor soul on cyclical Google Quest where nothing will make sense), these are basically executable which are _fork'n'exec_ed into new process. Problem is, you cannot execute them as is. Or better yet, you can, but some strange behaviour will happen. So not executables and not modules, per se. But I think these are nearer to modules than to executables. So the simplest thing I can come up with is to put them into When installing, Machinekit puts its code into
Which is fine. Problem is, Machinekit uses it for executables like Then there are in To me, this sounds like inconsistency. Well, more tomorrow. |
I see (I think you do too) multiple issues mashed together here. First, about directory structure:
I'm all for reorganizing, and this top-level structure makes sense to me: simple and obvious.
Nits:
This looks like a fine idea to me, and it fits well into a build system replacement project. About installation locations:
Definitely fix that. This could be addressed in this issue as part of a new build system, or in a new issue, implemented in the current or a future build system.
Is this question primarily about installation locations, or is it more about the C-language userspace comps issue (below)? About C-language userspace comps:
Here, you're talking about the C-language binary userspace comps, not the Python-language script userspace comps. The change you're proposing sounds like you mean to stop Would we lose support for independently-executable C-language userspace comps? Does EMC build any of those (I haven't checked)? Will that prevent any exotic use cases, such as building a HAL comp into a plugin (.so module) for another application? What's the difference that C-language userspace comps can't run independently, whereas Python-language comps can? How will C-language userspace comps be run from HAL, if not from Why is this problem of C-language userspace comps part of this issue? I can't tell why changing how those are loaded needs to be done in concert with replacing the build system. I'm absolutely not trying to shoot down the idea; in fact, I think it sounds interesting, creative, and outside the box. I'm just trying to understand exactly what it is and how it fits along with everything else. |
I do. Certainly. The problem is, to get green tests and build packages (and stay inside C4 mandated rules) I need to solve multitude of different thing at once - as they are connected together and this is a quite big endeavour.
I would love to minimize occurrences of "I should have implemented it differently" in the future to minimum, so I have been thinking that tree structure with un-branching nodes might be helpful in this. Particularly I was theoretizing about @the-snowwhite's FPGA HAL idea and that to allow AXI connection between FPGA and ARM core, one will need kernel-space originating memory block and atomic access functions. Hence, kernel module. I also am thinking that there is no reason, why Machinekit-HAL cannot combine kernel-space modules with user-space ones. (For example for use with parport and co-kernel real-time system. Similar how the triple buffer components are implemented now.) But then it would probably use user-space module as a controlling one. But still, kernel-space memory origin and the actual active kernel module/driver would be needed. Bottom line is, it is for possibility of future expansion. But I can try to keep things flat. (I would like to avoid something like current situation in
No problem, I took it from the suffix from
I look at the three main folders ( I would like to avoid creating language specific directories as this can limit what languages can be added in the future. (And it again presents the "I should have implemented it differently" problem.)
The I think scripts which are programs (or are used as programs) should go to Shell script which are sourced in other scripts or exports functions for other shell scripts (I am not sure now if those even exists) are kind of like library and I think should be put into Not sure where to put the Docker stuff. I have already filtered off the stuff for Debian package build to I am also not sure where to put the assembler stuff (mainly as I don't read assembler, I do not exactly know what it is doing).
This question was mainly about install locations and how the targets should be build. I was thinking that these programs (userspace components) should not be in That way it would be almost similar, but still not a program. And nobody is trying to use shared library (
Even through I am afflicted with serious case of Iwouldhaveimplementeditdifferentia, I consider this out of scope for this issue. In the future, I would like to implement multiple
No. I hope not. I have no idea. Build HAL component will hopefully become task done by adding some INTERFACE
One of my wants is to have as language agnostic solution as possible. With normally scheduled components, I think it is possible. But I think you wrongly understood me here. I don't want to do this big of change now.
I won't be any different.
It really isn't. The only part of this issue - and relevant to this issue - is how to build the userspace components targets. |
Some more ideas/questing I have about the CMake switch: The current build system rules specify some compile flags, like DEBUG or turning off optimization for given objects. I am thinking how important these are for the HAL/RTAPI/real-time/whatever targets. Draft #250 does not implement logic in relation to As a precaution, I would disallow configuring without specifying the The defaults on my computer are:
There is of course possibility to change them all or change target specific flags. However, which targets should have what? (I would probably copy the optimization levels from current build system for real-time related targets at least). Machinekit-HAL's libraries now use weird combination of naming rules - libmkini.so, libmtalk.so, libmachinekitsomething.so etc. I like things with order, so I would vote for renaming all libraries to libmachinekitsomething.so. How it is with Debian packages and CMake target scripts? Looking through packages, I cannot see any WhateverConfig.cmake or WhateverVersion.cmake in the installed files. And for example ZeroMQ has one. CMake has ability to automagically create these files from targets when installing. I think this functionality should be helpful when converting Machinekit-CNC to use the CMake build system too. However, how these should be installed in Draft #250 is big on compiling the C/C++ files into object libraries, which are basically collections of .o object files which are then depended on to executable and library target (and because of using 3.0.2 minimal version of CMake, it uses the older syntax with generator expressions). Question is, is it done because the current build system is doing it this way or is it a design which has some (for me hidden) advantages or benefits? Because I would prefer to specify (and compile) sources directly in targets and if some targets use the same source file (like |
In your last reply to my comment, +1 on everything. I like the thinking.
Good. My questions that followed this one all assumed otherwise, and are therefore moot. Sorry to make you answer them. |
Maybe @kinsamanka could chime in here, but my understanding is the CMake implementation in #250 tried to implement the inner workings of the current build system very faithfully. I would prefer the new build system to follow the usual CMake conventions, like specifying the sources of a target and letting CMake figure out how to compile and link it; after all, that's what CMake is good at. Related to this, #250 also faithfully reimplements the RIP build. One of the opportunities I saw in redoing the build system was getting rid of that forever. CMake should be able to build such that after |
The key issue that bugged me with the CMake conversion is on how to keep the git history intact. I've tried to keep the changes less intrusive so that a simple rebase is all that's needed to keep it updated. #250 closely follows the original build without the redundant steps and cleaned up some unnecessary linking. This is basically a RIP build; |
@kinsamanka,
You mean blameability by this?
Machinekit is now much more calm water than it was in the past. So I am just planning to do big bang switch and be done with it. |
So, And with all due respect to all parties involved, I consider the current state extremely chaotic, messy and borderline insane. (I am stating this now so anybody feeling insulted or thinking I am not right can open the discussion and tell me why I am wrong.) Given the setup presented in previous posts, the new tree should look something like this:
(And so on.) It is basically workspace approach. Flattened in regards with current system. The idea is that even though more folders under one root, it will still help newcomers to better understand what is available and how all comes together. (And the workspace model already has a precedent in Machinekit-HAL: Everything will be accessed through CMake targets (shared libraries for There is couple questions I have (or more things I would like to point out so somebody can protest/present his opinion):
|
So, few updates for whoever is watching this: One of the biggest problems with current Machinekit-HAL build-system is the differentiation between PUBLIC vs PRIVATE headers files. (Think of PUBLIC headers as an interface or an API for usage of the shared library or Second issue and ugliness is the MODULE library/shared library patter. (part of it was explained in issue #346.) Currently, that is mainly the Runtime ( |
With the merge of #349 most of the points of this issue have been solved. The single still remaining glaring issue is that the hairy generation of configuration variables for run from INSTALLED and BINARY trees is still required, but this is going to be solved in due time with introduction of I am sure I introduced few atrocities in the process of change, but these will have to be ironed with time and use. From the top-down viewpoint, this is done. |
There have been a number of discussions about replacing the build system, but I can't seem to find an issue for it. (Apologies for the length; deficiencies are probably overly-detailed after I've encountered scepticism about whether the current build system in fact even has any major problems.)
The problem
The build system is decrepit and needs replacing. The problems of the build system can be explained in the context of its origins.
Makefile
build system with Linux Kbuild integration$EMC_HOME
environment variable configures both build and run-time systems.ko
modules becomes an issue latergcc -I
in the%.o: %.c:
target!$EMC_HOME
conflated with$prefix
, but semantic differences./configure --prefix=/usr
(the default in normal Autotools build systems), run tests or run the application, and thenmake install
for a system install$prefix
artificially set to$EMC_HOME
, the source directory by default$prefix
insideconfigure.ac
introduces subtle problems, e.g. requires crazy hacks to template files that include variables based on$prefix
$EMC_HOME
libtool
support are another ingredient missing to run out of the source directory and thenmake install
to/usr
without rebuilding from zeropthreads
"sim" build was introduced.so
pluginsmake modules
for each configured thread flavor.o
files from the same.c
files to integrate with the "sim" module build rulessrc/subdir/Submakefile
orsrc/Makefile
?CFLAGS
orLDFLAGS
variable to use?*FLAGS
variables documented?src/objects
directorymake clean; make threads=posix objects/posix/hal/components/encoder.o
)The end result, the build system of today, is very difficult to modify. It's difficult to understand the structure of dependencies, files and variables in order to know how to introduce the change at all, much less where to add it so that it doesn't make the structure even more disorganized and hard to understand for the next person.
The only way to fix it at this point is by replacing it. Fortunately, this will be easier today than ever before. The split machinekit-hal repository reduces the size of the task. The upcoming per-flavor module merge will simplify build rules. Eliminating kernel threads also eliminates the requirement to support kbuild. And today there are two options that are already 50% complete.
Possible build system replacements
Among alternatives, these make the best sense, given the enormous head start, and given that both are widely-used and well-supported in general, and that the Machinekit community has more or less experience with both.
configure.ac
gets us halfway to a full Autotools configurationThe text was updated successfully, but these errors were encountered: