Reputation: 23
I've been recently been turned from the Windows and VisualStudio darkside to Linux and am struggling to get my generic makefile to work. I know it's probably an easy fix, but I've been reading around this and watching youtube videos for hours and can't seem to spot/fix the issue - please help!
I had all my code in the same directory (and it worked fine!), but it was becoming a bit of a handful so moved it to a src directory, with all the object files to go to a build directory. That way, only the makefile and the final executable would sit in the top level. I get an error saying:
make: *** No ruke to make target 'build/main.o', needed by 'testProg'. Stop.
My makefile is below. Any help would be much appreciated! Thanks in advance!
#Program Name:
PROG = testProg
CC = g++
CPPFLAGS = -c -g -Wall
LINKER = $(CC) -o
SRC_DIR = ./src
BUILD_DIR = ./build
# All source cpp files
SRCS = $(shell find $(SRC_DIR) -name *.cpp -or -name *.CPP)
# Substitute the .cpp for a .o for all entries in the $SRCS list.
OBJS_NAMES = $(subst .cpp,.o,$(SRCS))
OBJS = $(subst $(SRC_DIR),$(BUILD_DIR),$(OBJS_NAMES))
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $(OBJS) -o $(PROG)
# Create object files
%.o: %.cpp
$(CC) $(CPPFLAGS) $< -o $@
clean:
rm -f $(PROG) $(OBJS)
#for debugging
show:
@echo 'Source files: ' $(SRCS)
@echo 'Object files: ' $(OBJS)
When doing make show
I get the output:
Source files: ./src/main.cpp ./src/func1.cpp ...
Object files: ./build/main.o ./build/func1.o ...
Upvotes: 0
Views: 425
Reputation: 101081
This rule:
%.o: %.cpp
$(CC) $(CPPFLAGS) $< -o $@
tells make how to build a file XXX.o from a file XXX.cpp. The XXX (the part that matches the %
) must be identical.
In your new makefile you're trying to build build/foo.o
, so that rule will only match if make can find a build/foo.cpp
to compile. Since it can't, that rule doesn't match, and make doesn't know how to build your build/foo.o
files.
If you want the source file and the target file in different directories you have to write the rule such that the non-identical parts are spelled out, like this:
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CC) $(CPPFLAGS) $< -o $@
BTW, I recommend you don't use subst
above because that replaces all occurrences even if they appear in the middle of a word which is unlikely but, won't be what you want. I'd use:
OBJS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
No need for OBJS_NAMES
at all.
Upvotes: 3