Embedded projects can be more complicated to build than the Linux kernel in two respects: Embedded projects are usually cross-compiled; whereas, one is ordinarily building the Linux kernel for that machine or one like it. And, hardware vendor code is usually bad.
I had one embedded project that I handrolled the makefile for, and it was all in pure C, no OS. That was fine, but ensuring that the versions of the hardware abstraction layer, and other drivers I wanted to use from the same vendor was a source of annoyance. Keeping track of which source files were to be enabled and disabled in the makefile was also annoying.
Another project I am working on uses platformio on an RTOS (and a much bigger micro). Platformio is written in Python to handle all of that 'seamlessly' and it does work pretty well from my perspective. And I don't have to manually install separate toolchains to /opt (or wherever) and keep track of them; it 'just works.'
I like the makefile approach. With only a little work, it's possible to make clean build directories without .o files littered around like mouse droppings. I know exactly what code is being built, and, because I usually have to write the linker script, where it is being put. But once it gets more complicated with different toolchains and compatibility problems (and it usually does if you have an RTOS), it sure is nice to have something like Platformio.
There's also the aspect that a lot of the really good packages for dealing with e.g. text or the OS don't translate well to the constraints of embedded systems.
So I could go to all the trouble to have a cascading compilation all in pure c or c++, so the git SHA is written into a given source file, which is in turn built and flashed onto my target device. Or I could use an interpreted language for all the off-the-device operations, completely skip over configuring a separate development environment, and do it all in a fraction of the time.
The only reason I want to be compiling c or c++ for the host is because I'm also writing a driver at the same time, and even then...
I'll see your "Python and Ruby" And raise you to "A windows batch file that calls perl, python, nmake, and gnumake" It's like each person who contributed to the build system just used whatever tool was closest.
I've got a (bash) build script that that uses perl (with lots of regular expressions), python (apparently for no other reason than that the version of perl it started with didn't have `say`), dc (to calculate absolute memory addresses, because python and perl don't have a convenient equivalent of `P`), and runs a windows batch file under wine to build the .exe version with MinGW (although that will print a warning and continue if wine or MinGW is missing or out-of-PATH).
The cherry on top: visiting the https://cryptography.io/en/latest/ landing page, a Python outsider wouldn't be able to tell that this is for Python.
A full text search for "python" reveals only a single match hidden at the bottom within the FAQs section; ironically within the context "Why are there no wheels for my Python3.x version?".
Most of the other FAQs add to it:
- I cannot suppress the deprecation warning that cryptography emits on import
- cryptography failed to install!
- Why does cryptography require Rust?
- Installing cryptography produces a fatal error: 'openssl/opensslv.h' file not found error
- cryptography raised an InternalError and I’m not sure what to do?
- Installing cryptography fails with error: Can not find Rust compiler
- I’m getting errors installing or importing cryptography on AWS Lambda
- Why can’t I import my PEM file?
What happened to the backend argument?
- Will you upload wheels for my non-x86 non-ARM64 CPU architecture?
Python is by far the most platform-dependent, brittle programming environment, and the prime example that the "interpreted languages run everywhere!" trope is increasingly dead.
Why is this python's problem? You are choosing to use a c/rust accelerated library. If your project were pure c or rust, you would still have to build everything.
I meant: "Python *has by far the most platform-dependent, brittle programming environment".
> You are choosing to use a c/rust accelerated library.
Especially with something as fundamental as `cryptography`, I don't choose it - it is a given through transitive transitive dependencies.
> If your project were 𝗽𝘂𝗿𝗲 c or rust, you would still have to build everything.
That's the whole point: when developing in programming language XYZ, then stay within XYZ's environment: As much as possible, implement stuff by writing in XYZ, and import other stuff following this principle.
Whereas, the moment you or one of your dependencies delegate to other environments, your program inherits and requires additional environments.
So many projects and libraries in Python World have taken the latter approach, resulting in so many Python applications being a cobbled-together Frankenstein diva. It will refuse to work on your users' system, until they have the correct rubyenv, and autoconf version, and npm.
"Huh, why does the user report a problem with npm when installing my Python application?". Well, that could be because unbeknownst to you, whenever you yourself developed, updated, and ran your program, there was always this tiny dependency of a dependency that needs it - you just didn't know about it until this issue report, because your system already had Node and npm set up correctly. That reporting user's not!
Linux, being a kernel, has no external dependencies (except for its menuconfig, which requires ncurses). That sort of isolated build tree is very rare in almost every other software project, even something like gcc has a dozen external dependencies IIRC.
It does, including at least a shell, a C++ compiler, make, and a bunch of other UNIX/GNU tools to run the whole thing. And where do you get those programs from, and can you trust them? If you look really seriously, a scary problem emerges. (See: Trusting Trust Attack)
The Guix project recently hit a massive milestone in untangling this, by creating a package set which starts by building a 357-byte program and works its way up to the utilities you'd expect: https://guix.gnu.org/blog/2023/the-full-source-bootstrap-bui...
I've seen embedded C code that requires Python AND Ruby to build.
Linux is still using makefiles (+ config). Your project cannot possibly be more complicated