Based on some SO questions -- and some further reference found --, I'm trying to build a makefile able to:
- find, given the directories in
$(SRC)
, the.cpp
files to be compiled; - compile the
.cpp
, producing.o
objects; - generate
.so
shared objects from each.o
formerly compiled.
What the make file is supposed to do to achieve that is:
- find, given the directories in
$(SRC)
, the.cpp
files to be compiled; - build the dependency list for each
.cpp
using-MM
compiler's flag; - annotate/add each dependency using
$(eval ...)
; - evaluate/solve each dependency found, producing both the
.o
and.so
files.
What do I have so far:
I've been able to do quite the whole thing, except for making it work (:
The error I'm getting states that there is, somehow, an empty label ''
as dependency:
$ make make: * No rule to make target
', needed by
/home/rubens/bin/label.o'. Stop.
So, here is the makefile I'm yet not able to run:
# Directories
SRC := process init
BIN := $(HOME)/bin
LIB := watershed
LIBPATH := $(WATERSHED)/lib
INC := $(WATERSHED)/include $(XERCES)/include
# Paths
MPICPP := mpic++
SOURCES := $(shell find $(SRC) -name '*.cpp')
OBJECTS := $(addprefix $(BIN)/, $(notdir $(SOURCES:.cpp=.o)))
SHARED := $(OBJECTS:.o=.so)
# Flags
CFLAGS := -std=c++0x -O2 -Wall -fPIC
CFLAGS += $(foreach inc, $(INC), -I $(inc))
LFLAGS :=
LFLAGS += $(foreach lib, $(LIB), -l $(lib))
LFLAGS += $(foreach path, $(LIBPATH), -L $(lib))
# Rules
$(SHARED): | bindir
%.o:
@echo $@ -- [$<][$^][$*]
@echo $(MPICPP) $(CFLAGS) -c $< -o $@
%.so: %.o
@echo $(MPICPP) $(LFLAGS) -shared $< -o $@
bindir:
@mkdir -p $(BIN)
# Utilities
.PHONY: all clean
all: $(SHARED)
clean:
@rm -f $(OBJECTS) $(SHARED)
# Dependencies
define dependencies
$(addprefix $(BIN)/, $(notdir $(1:.cpp=.o))): \
$(shell $(MPICPP) $(CFLAGS) -MM $(1) | sed 's/^.*\.o:[ ]*//')
endef
$(foreach src, $(SOURCES), $(eval $(call dependencies, $(src))))
Where exactly seems to be the error:
It seems to be caused by the dependency generation step, as, when I remove any empty lines , piping the output to grep
, as follows:
define dependencies
$(addprefix $(BIN)/, $(notdir $(1:.cpp=.o))): \
$(shell $(MPICPP) $(CFLAGS) -MM $(1) | sed 's/^.*\.o:[ ]*//' | \
grep -v ^$)
endef
The error somehow digivolves to an empty list of dependencies; I'm able to see the list is actually empty with the echo
's in rule %.o:
-- the only variables not empty are $@
and $*
.
/home/rubens/bin/label.o -- [][][/home/rubens/bin/label]
mpic++ -std=c++0x -O2 -Wall -fPIC -I /home/rubens/libwatershed/include -I /home/rubens/xerces-c-3.1.1/include -c -o /home/rubens/bin/label.o
mpic++ -l watershed -L -shared /home/rubens/bin/label.o -o /home/rubens/bin/label.so
Any advice on better ways to solve this are very, very welcome; yet, I would really like to finish writing this makefile, before I get to use something like Cmake
or Scons
.