i should probably learn how makefiles work some day
-
@eniko the most important thing is make is a jobs system based on file dependencies.
a makefile is a series of jobs, which will produce a file (which is supposed to be the name of the job) with a list of tasks (individual commands to generate said file). a job sometimes though will depend on other jobs, and those also have dependencies noted by file.
when make runs a job, it will get the date of the file produced by that job. then, look at all dependencies. if any dependency has been updated since (it will try to run those jobs, and look at all the dependencies, it might not actually run any command), then it will actually launch the tasks
@eniko it's a bit abstract, so it's easier with an example: you have a makefile with three jobs, two for two c files, lib.o and main.o, which depend respectively on lib.c and main.c, and one that will link the two together into an executable (say, prog)
lib.o: lib.c
gcc -c lib.c
main.o: main.c
gcc -c main.c
prog: lib.o main.o
gcc -o prog lib.o main.ohere, when you run
make prog, make will first check wether lib.o needs updating. maybe it wasn't updated manually, but it is a job in make, and that job also gets checked. if the c file was modified, then lib.o will be regenerated, otherwise, it won't. then, make will do the same with main.o (and main.c).if any of them was updated, then prog will run its own tasks, and produce the prog binary, and otherwise, will just tell you there's nothing to do.
-
i should probably learn how makefiles work some day
@eniko They're nice when you want more than a shell one-liner but don't want a fancy build system. (I basically never want a fancy build system.)|
-
@eniko it's a bit abstract, so it's easier with an example: you have a makefile with three jobs, two for two c files, lib.o and main.o, which depend respectively on lib.c and main.c, and one that will link the two together into an executable (say, prog)
lib.o: lib.c
gcc -c lib.c
main.o: main.c
gcc -c main.c
prog: lib.o main.o
gcc -o prog lib.o main.ohere, when you run
make prog, make will first check wether lib.o needs updating. maybe it wasn't updated manually, but it is a job in make, and that job also gets checked. if the c file was modified, then lib.o will be regenerated, otherwise, it won't. then, make will do the same with main.o (and main.c).if any of them was updated, then prog will run its own tasks, and produce the prog binary, and otherwise, will just tell you there's nothing to do.
@eniko make also has some niceties to handle configurability of the build, and to reduce boilerplate, but those are just for that, reducing boilerplate, and aren't fundamentally necessary to how make works. a fair few systems will also just generate makefiles or ninja files (which are basically the same but stripped down, which can improve compile performance for large projects) because configurability in make is generally a mess, and is done more easily with an external tool, like meson or cmake or autoconf
-
@eniko make also has some niceties to handle configurability of the build, and to reduce boilerplate, but those are just for that, reducing boilerplate, and aren't fundamentally necessary to how make works. a fair few systems will also just generate makefiles or ninja files (which are basically the same but stripped down, which can improve compile performance for large projects) because configurability in make is generally a mess, and is done more easily with an external tool, like meson or cmake or autoconf
@eniko people really make it to be more complex than it really is, but honestly the parts that are hardest to deal with are the configurability and boilerplate reduction parts, which ... yeah, messy is the nicest way i can describe them
-
@eniko A few months ago I would’ve said “don’t, it’s not worth it.”
But I love using them as basically shell scripts. They’re really flexible and a good universal tool for building simple projects in any language.
Anything more complex…. nah, I reach for a more modern build tool.
-
i should probably learn how makefiles work some day
Wait. Is cmake make? Or are they different things
-
Wait. Is cmake make? Or are they different things
@eniko completely different, but cmake can generate make files.
-
Wait. Is cmake make? Or are they different things
@eniko cmake ostensibly was a system to make makefiles but I don't think it does that any more and just has its own way of building stuff
-
@eniko completely different, but cmake can generate make files.
-
Wait. Is cmake make? Or are they different things
@eniko cmake makes make for c but you can make not make for not c
-
Wait. Is cmake make? Or are they different things
@eniko Different things. CMake can create makefiles. Or project files for IDEs. Kinda like an additional abstraction layer.
CMake is slightly less gnarly than make, but still not fun.
-
-
Wait. Is cmake make? Or are they different things
@eniko cmake is it's own thing, it can do a lot more things, but a lot more complicated
-
Wait. Is cmake make? Or are they different things
@eniko different, IIRC cmake generates a makefile for make (please don't quote me on that, it was a while since manually I built something using make from source)
-
-
i should probably learn how makefiles work some day
@eniko make is kind of a mess, but very simple to learn, honestly
GNU make has a full manual online I've referenced frequently
the important bit to understand is that it is very based in traditional C building where each .c file is compiled into a .o file and then linked
so, it effectively does a topological/tree sort of dependencies where when you ask "make binary" it goes:
- is binary newer than its dependencies? (by file modification time?)
- are those dependencies newer than their dependencies?
- etc.
and then builds the stuff as necessary. it also lets you parallelise which is cool
the most complicated bit is "phony" targets where instead of an actual file, you say something like "make build" which always runs commands and/or builds dependencies
also, load-bearing tabs; space-indenting doesn't work
-
Wait. Is cmake make? Or are they different things
@eniko Different and bleh but better than automake.
Build tools are a mess each generation must create their own flavor of dissatisfaction that they get used to—you know, like fashion.
-
Wait. Is cmake make? Or are they different things
@eniko cmake is really a bad name, it is very different from make. yea, as other comments said, it generates makefiles from a cmake definition, and does extra things like managing subprojects and stuff iirc
what really doesn't help is there is bmake, which is a make implementation from the BSD operating systems, and gnu make is often referred to as gmake, so it is a reasonable assumptions that cmake would also be a make implementation, but, yea, no
-
Wait. Is cmake make? Or are they different things
I looked into cmake a couple of times, but it seemed to bring so much complexity of its own.
I think it can make things easier (or at least quicker) when you want to pull in a ton of dependencies, which it can download & build for you.
My projects only have very few dependencies, so I just put in the time to write a versatile Makefile that works with all my projects.
How are you building your projects at the moment?
-
@eniko make is kind of a mess, but very simple to learn, honestly
GNU make has a full manual online I've referenced frequently
the important bit to understand is that it is very based in traditional C building where each .c file is compiled into a .o file and then linked
so, it effectively does a topological/tree sort of dependencies where when you ask "make binary" it goes:
- is binary newer than its dependencies? (by file modification time?)
- are those dependencies newer than their dependencies?
- etc.
and then builds the stuff as necessary. it also lets you parallelise which is cool
the most complicated bit is "phony" targets where instead of an actual file, you say something like "make build" which always runs commands and/or builds dependencies
also, load-bearing tabs; space-indenting doesn't work
@eniko also like, the reason why external systems like cmake exist is because, specifically for the purpose of making C code, plain make is a pain in the absolute ass
while header files make dependency lookup relatively easy, make does not do that, and so you either have to just force-rebuild parts if you modify a header file or manually list all dependencies and update them when they change
so, cmake will figure that out for you, and so will ninja, etc.
but makefiles are still really good in any build system, because if you have a way of outputting the dependency tree into a file and the right commands you can just have make figure out how to run and parallelise it for you