Home > Mobile >  why is GNU make not filling out the $^ variable here?
why is GNU make not filling out the $^ variable here?

Time:10-07

I can compile the project just fine if I run the project by hand with g source/* -lSDL2 -o bin/fly_fishing. When I do run make, I get

mkdir -p bin
g     -lSDL2 -o bin/fly_fishing
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text 0x17): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [Makefile:20: bin/fly_fishing] Error 1

Which tells me that it's not populating from $^ for linking. So what have I missed here? Here's the makefile for reference.

 SRC_DIR := source
OBJ_DIR := objects
BIN_DIR := bin 

EXE := $(BIN_DIR)/fly_fishing
SRC := $(wildcard $(SRC_DIR)/*.c)
OBJ := $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)

CXXFLAGS := -Wall
#CFLAGS   := -Wall
LDLIBS   := -lSDL2a
LDFLAGS :=

.PHONY: all clean

all: $(EXE)

$(EXE): $(OBJ) | $(BIN_DIR)
        $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
        $(CXX) -c $(CXXFLAGS) $(CFLAGS) $< -o $@

$(BIN_DIR) $(OBJ_DIR):
        mkdir -p $@

clean:
        @$(RM) -rv $(BIN_DIR) $(OBJ_DIR)

-include $(OBJ:.o=.d)

CodePudding user response:

Which tells me that it's not populating from $^ for linking.

That seems unlikely. Much more likely would be that $^ expands to nothing. Which would be the case if $(OBJ) expands to nothing. Which seems plausible because I don't see any corresponding objects being built (though perhaps you've omitted that, or they were built on a previous run). And $(OBJ) expanding to nothing implies that $(SRC) expands to nothing.

So what have I missed here?

That $(SRC) expands to nothing is not inconsistent with the data presented. I observe that the manual compilation command you present is

g   source/* -lSDL2 -o bin/fly_fishing

That does seem to suggest that there are indeed source files in source/, but do they match the pattern source/*.c? Since you're compiling with g , I bet not. It would be highly unconventional to name C source files to end with .c, and surely you would not attempt to compile C source files with a C compiler. I infer, then, that your source files are all named with .cpp, or maybe .cc or .C, all of which forms are conventions for C source names.

If all your source names follow one or another of those patterns then indeed, this ...

SRC := $(wildcard $(SRC_DIR)/*.c)

... will result in $(SRC) being empty.

  • Related