BieremaBoyzProgramming / bbpPairings

A Swiss-system chess tournament pairing engine, implementing the Burstein and Dutch systems.
Other
75 stars 30 forks source link

Fix Makefile dependency handling #16

Open dejbug opened 1 year ago

dejbug commented 1 year ago

To get some nice errors, do this:

$ make
$ touch src/main.cpp
$ make

A couple of issues.

SRC = src
OBJ = build
SOURCES = $(shell find $(SRC) -name "*.cpp")
OBJECTS = $(patsubst $(SRC)/%.cpp, $(OBJ)/%.o, $(SOURCES))
# ...
$(OBJ)/%.o: $(SRC)/%.cpp
    mkdir -p $(dir $@)
    $(CXX) -o $@ $^ -c -I$(SRC) -MMD -MP $(CXXFLAGS)
# ...
-include $(OBJECTS:%.o=%.d)

The first time make is invoked, as expected, we get the single cpp in $^. But that recipe has the side-effect of creating a build/%.d for every src/%.cpp and these will get included at the second invocation.

So the second time the recipe is entered we get all the autogen'd dependencies, not just the $(SRC)/%.cpp. We can't compile the headers and have to guard against that, either by using $< instead of $^ (the dependencies are in a sane order, and usually we compile one source to one object file) or with a filter (just in case).

The other issue is that the the *.d files themselves needed to get updated whenever a source changes (i.e. when adding or removing includes).

Also that patsubst could be rewritten like the one in the include line.

dejbug commented 1 year ago

Well, I'm new to pull requests. Should have used branches. Anyway, instead of a second pull request, here's another quick fix (see the second commit).

The problem here is when you do this:

$ make engine_comparison=no

This will rather cryptically complain about "unused macros". Turns out that the compiler is right. Says the GCC Manual: "The preprocessor also warns if the macro has not been used at the time it is redefined or undefined." Hence every time we have two OMIT_*s defined.

So instead of

#if defined A
#define Z
#endif
#if defined B
#define Z
#endif

we need

#if defined A
#define Z
#elif defined B
#define Z
#endif

which is to say

#if defined A || defined B
#define Z
#endif