Reputation: 420
I seem to be going from one problem to the next ever since I decided to organize my code into subdirectories. The problems are naturally arising from the Makefile. So here's what I've currently got:
UNAME := $(shell uname)
# Directories
SOURCEDIR = src/
BUILDDIR = build/
# Compiler options
CC = clang++
DEBUG = -g
CFLAGS = -std=c++11 -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
# Files
SRC = $(wildcard $(SOURCEDIR)*.cpp) $(wildcard $(SOURCEDIR)**/*.cpp)
OBJS = $(SRC:$(SOURCEDIR)%.cpp=$(BUILDDIR)%.o)
ifeq ($(UNAME), Darwin)
LIBS = -lglfw3 -framework OpenGL -lglew -framework IOKit -framework CoreFoundation -framework ApplicationServices -framework Foundation -framework AppKit
BUILDDIR = ./build/osx/
endif
ifeq ($(UNAME), Linux)
LIBS = -lglfw -lGL -lGLEW
BUILDDIR = ./build/linux/
endif
# Build target
TARGET = test
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LFLAGS) $? -o $(TARGET) $(LIBS)
$(OBJS): $(BUILDDIR)%.o : $(SOURCEDIR)%.cpp
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $< -o $@
clean:
rm -rf $(BUILDDIR)*.o $(BUILDDIR)**/*.o $(TARGET)
I was really glad when it actually compiled everything! Except when I made a change to a file, and tried to make
it again, it spat this at me:
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [test] Error 1
Thing is, when I make
it once more, it works just fine. The problem seems to be with resolving dependencies? And for that, I need to specify a VPATH
? Well, that's the closest I've gotten, except trying to specify a VPATH hasn't made a difference. I'm probably specifying it incorrectly, or then I'm taking the wrong approach to this.
I'm pretty inexperienced when it comes to Makefiles, so I'd really appreciate some guidance!
Upvotes: 0
Views: 1545
Reputation: 420
Thanks to Etan Reisner for the solution. The problem was with the difference between $?
and $^
. Here's the fixed version:
UNAME := $(shell uname)
# Directories
SOURCEDIR = src/
BUILDDIR = build/
# Compiler options
CC = clang++
DEBUG = -g
CFLAGS = -std=c++11 -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
# Files
SRC = $(wildcard $(SOURCEDIR)*.cpp) $(wildcard $(SOURCEDIR)*/*.cpp)
OBJS = $(SRC:$(SOURCEDIR)%.cpp=$(BUILDDIR)%.o)
ifeq ($(UNAME), Darwin)
LIBS = -lglfw3 -framework OpenGL -lglew -framework IOKit -framework CoreFoundation -framework ApplicationServices -framework Foundation -framework AppKit
BUILDDIR = ./build/osx/
endif
ifeq ($(UNAME), Linux)
LIBS = -lglfw -lGL -lGLEW
BUILDDIR = ./build/linux/
endif
# Build target
TARGET = test
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LFLAGS) $^ -o $(TARGET) $(LIBS)
$(OBJS): $(BUILDDIR)%.o : $(SOURCEDIR)%.cpp
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $< -o $@
clean:
rm -rf $(BUILDDIR)*.o $(BUILDDIR)*/*.o $(TARGET)
Upvotes: 1