I love Makefile. It is the easiest build system.
In my projects, whether the language is Go, Rust, Python, typescript, or even Android, there are standard make commands, if applicable, always work
- make format
- make lint
- make build
- make docker_build
- make docker_run
Once might migrate from one build system eg pipenv to poetry to uv, but the high level `make format` commands doesn't change.If you have a single file C program you can also use Make without a Makefile.
I always had the idea that Make reads a Makefile, so when I saw this for the first time it blew my mind.
So if you have file.c you can just call âmake fileâ and that is it.
Perhaps in the coming years, when Make reaches its 50th anniversary, people will finally begin to question the status quo regarding need of different separate language to build their programs in some particular language, e.g. C language.
https://oneofus.la/have-emacs-will-hack/files/1978_Feldman_M...
Some already do
https://github.com/tsoding/nob.h
https://youtu.be/D1bsg8wkZzo?t=97
https://youtu.be/mLUhSPD4F2k?t=73
https://youtu.be/eRt7vhosgKE?list=PLpM-Dvs8t0Va1sCJpPFjs2lKz...
Autotools looks like a great idea: try to compile some programs and see if it works to learn the specifics of your environment. Yet I share the feeling from Julia that I hope to never have to learn how it works.
I wish more projects would include a dockerfile in which a compiler and all dependencies are installed to run the right make command as âdocker build .â
So you get a working build example, and if youâre lucky and the base image exists for your architecture, itâll compile a binary for your system too (assuming static linking I guess).
I think this covers most of the useful folk knowledge, except pkg-config which can tell you the right -I and -l flags for something (in theory a makefile should invoke it to fill variables).
> C doesnât have a dependency manager
On the contrary it has many. My favorite is apt but maybe you prefer cargo or homebrew or rubygems.
If you feel the need say "C/C++" you probably want to think twice.
One again, this site misses a lot of details, some of which are quite important:
* build-essential - this actually installs what is considered "essential" for Debian packages. This happens to include some common compilers, other tools, and libraries, but also a bunch of junk you probably don't need. Still, this is harmless.
* There is `pkg-config` for detailing dependencies that are already installed, there's just no standard way to automatically download and run code from the internet (and good riddance)
* Sometimes you have to run `autoreconf -i` first to generate `configure` in the first place. This normally happens if you're running from a git clone rather than a tarball. Autotools is mostly useless if you're only working on Linux, marginally useful if you're also working on a different modern OS (especially since the first step is "install the GNU version of all the build tools"), but extremely useful if MyWeirdPrePosixProprietaryUnix. Despite this, `./configure` remains the single best interface for end-user installing - cmake in particular is an atrocity.
* There is a little confusion about "build/host/target", due to the question "what machine am I running on, at what time?" If you aren't cross-compiling you can ignore all this though.
* For more about `./configure` and `make` options, see https://www.gnu.org/prep/standards/html_node/Managing-Releas... - there's also some good reference material in the documentation for `autotools` and `make`. I won't repeat all the things there, many of which people really need to learn before posting.
* One annoying thing is that `./configure` and `make` disagree about whether libraries go in `LIBS` or `LDLIBS`. You should normally set variable for `./configure` so you don't have to remember them; one exception is `DESTDIR`.
* `as` and `ld` are called internally by then compiler, you should never call them directly, since it needs to mangle flags.
* The `checkinstall` tool, if supported for your distro, can help call `make install` in a way that uninstallation is reliable.
* rpath is the correct solution instead of `LD_LIBRARY_PATH`, and can be automated based copying `-L` arguments to `-R`. There's some FUD floating around the internet, but it only affects `setuid` (and other privileged) packages on multiuser systems, and even then only if they set it to certain values.
[dead]
[dead]
CPPFLAGS and CXXFLAGS are different. CPPFLAGS are for options for the C preprocessor, regardless of what language it is being used for. CXXFLAGS are for C++. The XX's are ++ rotated 45 degrees.
Don't be fooled by the convention used in some necks of the woods of a .cpp suffix for C++ files; CPPFLAGS have to do with the "cpp" program, not the .cpp suffix.
LDLIBS is sister to LDFLAGS. Both these variables hold options for the linker command line destructured into two groups: LDFLAGS are the early options that go before the object files. LDLIBS are the -l options that give libraries, like -lssl -ldl -lcrypto ... these go after the object files.
If you're writing a Makefile, with your own custom recipes for linking, be sure you interpolate both LDFLAGS and LDLIBS in the right places.