Reputation: 14688
Perhaps I missing something, but this make file fails, with error (paraphrasing due to localization is active):
there is no rule to build target ****.o
where **** is the name of existing .cpp file. Make version 3.81, gcc 4.7.5 (if that's relevant).
Here is the makefile.
program_name := librlsmatt.a
source_dirs := ../src
include_dirs := $(source_dirs)
CXX = g++
AR = ar
WARNS := -Wall -Wno-deprecated -Wno-unused -Wno-unused-parameter
CFLAGS:= $(addprefix -I, $(include_dirs)) $(WARNS) -fstack-protector-all -g
ARFLAGS := cru
source_files := $(wildcard $(addsuffix /*.cpp, $(source_dirs) ) )
object_files := $(notdir $(source_files:.cpp=.o) )
dep_files := $(object_files:%.o=%.d)
.PHONY : clean
-include $(dep_files)
$(program_name): $(object_files)
$(info Linking ...)
@$(AR) $(ARFLAGS) $@ $(object_files)
%.o: %.cpp makefile
$(info Compiling $< ...)
@$(CXX) -c $(CFLAGS) $< -o $@ -MF $(@:%.o=%.d) -MT $@
clean:
$(info Clean $(program_name)...)
@$(RM) -f $(program_name) $(object_files) $(dep_files)
Upvotes: 0
Views: 39
Reputation: 58627
Firstly, note that the default target in a Makefile is the first one; therefore if we the dependency files exist, and we include them before the main target, then the .o
target in the first included dependency rule will be the default target. As a rule of thumb, include dependencies somewhere farther down, like the very end.
The pattern matching problem in this Makefile is caused by the fact that the .o
files do not have a directory prefix, due to the use of $(notdir ...)
in the expansion which generates them, but the .cpp
files do.
make
is trying to build some foo.o
and the %.o: %.cpp
rule tells it to look for foo.cpp
. But there is no foo.cpp
; what exists is is some src/dir/foo.cpp
.
If you really want the .o
files to be in one directory, the VPATH
mechanism may be a possibility. If src/dir
is in the VPATH
, then when make
looks for foo.cpp
to update foo.o
, it will find it in src/dir
.
If you force all .o
files from the tree into one directory, you have to be sure there are no two .cpp
files with the same name.
If you want to deposit .o
files outside of the source tree (which is useful, because you can then have a read-only source tree, for instance), it's probably best to mirror the structure of the source tree in the output tree, like this:
$(OUTPUT_DIR)/%.o: %.cpp: # where the % stem is src/dir/whatever/foo
The idea is that the object file is $(OUTPUT_DIR)/src/whatever/foo.o
, and the source file is src/whatever/foo.cpp
.
The recipe has to make sure that the directory $(OUTPUT_DIR)/src/whatever
exists; so a mkdir -p
command will be needed in there somewhere:
$(OUTPUT_DIR)/%.o: %.cpp:
$(info Compiling $< ...)
@mkdir -p $(dir $@)
@$(CXX) -c $(CFLAGS) $< -o $@ -MF $(@:%.o=%.d) -MT $@
Upvotes: 1