4 ms·
The recommended Makefile has several issues, not least of which being that it relies on dependency fulfilment order which can be non-deterministic (e.g. if you
by Arch-TK 3y ago
The recommended Makefile has several issues, not least of which being that it relies on dependency fulfilment order which can be non-deterministic (e.g. if you pass -j).
The project structure includes flavour-of-the-week litter like .devcontainer, .github, .vscode.
compile_commands.json should be getting generated, not stored.
Not sure if I would recommend anyone follow this information.
The build system situation in the C world is dire. And I should know, given I write my own build systems for C.
I would say, while I've never actually used it, Meson seems the least non-sensical out of the box experience.
Ideal in some ways but not in others is designing and implementing your own build system because genuinely everything else out there has some major shortcoming or other.
If you are insistent on make, stick to GNU make, read the GNU make manual, understand make and then write something simple and non-recursive.
This is the most recent Makefile I helped create:
CXX ?= clang++
CXXFLAGS += -std=c++20 -Wall -Wextra -fsanitize=address -ggdb3 -MMD -MP
LDFLAGS += -fsanitize=address
OBJ := program.o parse.o
all: program compile_flags.txt
program: $(OBJ)
$(CXX) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
$(OBJ): Makefile
compile_flags.txt: Makefile
printf "%s\n" $(CXXFLAGS) >$@
clean:
$(RM) *.o *.d program compile_flags.txt
-include $(OBJ:.o=.d)
.PHONY: clean
If you want to do something like run a linter, code formatter, etc, before building, then this should be performed by a script which calls into make. Make is not designed to be used as a switch statement for your bash snippets.
- ReleaseCandidat 3y ago> The build system situation in the C world is dire. Meta's Buck 2 (written is Rust) would be my choice, if I would write "new" C or C++. Examples using Vcpkg https://github.com/Release-Candidate/Cxx-Buck2-vcpkg-Examples https://github.com/Release-Candidate/Cxx-Buck2-vcpkg-Example... And Conan https://github.com/Release-Candidate/Cxx-Buck2-Conan-Examples https://github.com/Release-Candidate/Cxx-Buck2-Conan-Example...
- humanrebar 3y agoIf you're writing C, you might not want tools written in higher level languages required for your build environment. This is why you still see a lot of important C project support autotools even though it's a pretty awful developer experience.
- eska 3y agoIt seems weird to me to write your own build system and give advice on build systems when your basic makefile already completely violates what the manual suggests.
- Arch-TK 3y agoUnnecessarily vague and uncharitable comment but I'll bite. While I recommend anyone who uses GNU make should read the manual, the manual is full of outdated best practices which can be safely ignored. If I was going to use this makefile for my own project, I would even drop the clean target entirely. phony targets are mostly a misfeature. Although it looks like the makefile as accepted by the project hasn't marked the all target as phony. But go on, tell me what it is that is not recommended specifically. I am aware of many deviations from what the GNU make manual claims is recommended. A large portion of deviations is the lack of many of the standard targets it thinks should be provided. Another deviation might be the uppercase OBJS should be lowercase according to the manual, but in this case I was trying to minimize the number of immaterial changes from the original makefile I modified to arrive at this point since it was not my project.
- eska 3y agoNo need to talk about anything advanced. Line 2 and 3 for example make it impossible to override certain behavior you’ve set. >If you are insistent on make, stick to GNU make, read the GNU make manual, understand make I refer to this authoritative sounding comment while you miss out on the very basics like that.
- Arch-TK 3y ago>Line 2 and 3 for example make it impossible to override certain behavior you’ve set. This is intentional. It's not possible (unfortunately) to allow users to simultaneously be able to override a variable OR add to a variable in make. In the case of the FLAGS variables I usually prefer to append to allow users to add to the variables. As a compromise, in my own makefiles I explicitly ensure that these variables _only_ contain flags which are mandatory for the project to build correctly. In this case this was deviated from (with the warning flags, -fsanitize=address, -ggdb) because of the request of the project author. Would you rather an end user be able to quickly add LDFLAGS and CXXFLAGS or rather have the end-user have to copy the entire list of flags out of the makefile just so they can add one? I would say it's more common for someone to want to add a flag than to replace all the mandatory ones. If someone is using a sufficiently different compiler such that those flags are no longer relevant, they would likely need to modify the rest of the makefile. >I refer to this authoritative sounding comment while you miss out on the very basics like that. It's uncharitable to assume that just because you don't understand a decision someone made in something they wrote, that they must be ignorant about the tool they are using.
- LabMechanic 3y agoYou can consider using MinUnit and Clang-Tidy together with Clang-Format as well, further, for C it should be something more like this: CC = clang CFLAGS = -g -std=c2x -Weverything -fsanitize=undefined,address all: app.exe app.exe: src/main.c $(CC) $(CFLAGS) src/main.c clean: rm -rf /build See my comment here with an example of an NMAKE Makefile. Consider: https://nullprogram.com/blog/2017/08/20/ https://nullprogram.com/blog/2017/08/20/
- UncleEntity 3y ago> ...not least of which being that it relies on dependency fulfilment order which can be non-deterministic (e.g. if you pass -j). Didn't actually know that was a thing until I accidentally ran into it yesterday when I ran the make command in the wrong terminal window and the build was very, very unhappy. At least it didn't bork my entire /home directory like that time we don't talk about... My general rule is Make for simple things and CMake if it involves distro-packed library deps or I'm building python modules with complicated enough builds that I don't wan't to beat the dead horse of distutils into submission. Honestly, if I can't tell what the build system is doing without having to ask google then it's way too complicated.