Update. I did not use addprefix in the link rule. # Makefile for top dir
# $(call makever,1.2.3) # major.minor.patch # libtool manual: -version-number define makever @ $(MAKE) -C $@ soname=lib$@.so.$(word 1,$(subst ., ,$(1))) @ cp $(OBJDIR)/$@/$@ $(OBJDIR)/$@/lib$@.so.$(1) @ cd $(OBJDIR)/$@; ln -f -s $(OBJDIR)/$@/lib$@.so.$(1) \ $(OBJDIR)/$@/lib$@.so.$(word 1,$(subst ., ,$(1))); cd .. @ cd $(OBJDIR)/$@; ln -f -s $(OBJDIR)/$@/lib$@.so.$(1) \ $(OBJDIR)/$@/lib$@.so; cd .. endef # make # BUILD_DIR=build ifndef BUILD_DIR export OBJDIR = $(abspath build) else export OBJDIR = $(abspath $(BUILD_DIR)) endif SUBDIRS = main foo all : $(SUBDIRS) install : $(SUBDIRS) $(SUBDIRS) : | $(OBJDIR) $(OBJDIR) : ; @ mkdir $@ main : foo main : ; @ $(MAKE) -C $@ foo : ; $(call makever,1.2.3) # make DESTDIR=~/foo install # Alexandre Duret-Lutz??s Autotools Tutorial (without animations): # "is ready to be uncompressed in / on many hosts" install : install -d "$(DESTDIR)/usr/local/bin" install -d "$(DESTDIR)/usr/local/lib" install -m 0755 $(OBJDIR)/main/main "$(DESTDIR)/usr/local/bin" install -m 0755 $(OBJDIR)/foo/*.so* "$(DESTDIR)/usr/local/lib" clean : @ for dir in $(SUBDIRS); do \ $(MAKE) -C $$dir $@; \ done -rm -fr $(OBJDIR) .PHONY : $(SUBDIRS) all install clean --- # Makefile for subdir # build shared library with -fPIC, -shared CFLAGS = # -g -O3 -fPIC # CXXFLAGS for .cpp CPPFLAGS = -MMD -MP -I../foo LDFLAGS = -L$(OBJDIR)/foo # -shared LDLIBS = -lfoo #CC = $(CXX) # link with CXX for .cpp LDFLAGS += -Wl,-rpath,$(OBJDIR)/foo LDFLAGS += -Wl,-rpath,'$$ORIGIN/../lib' #LDFLAGS += -Wl,-soname,$(soname) # make # NDEBUG=1 ifdef NDEBUG CPPFLAGS += -DNDEBUG CFLAGS += -O3 # .cpp else CFLAGS += -g # .cpp LDFLAGS += -fsanitize=address endif SUBDIR = $(OBJDIR)/main all : $(SUBDIR)/main # $(SUBDIR)/foo $(SUBDIR)/main : $(addprefix $(SUBDIR)/,$(patsubst %.c,%.o,$(wildcard *.c))) # .cpp $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(SUBDIR)/%.o : %.c | $(SUBDIR) # .cpp $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(SUBDIR) : ; @ mkdir $@ -include $(SUBDIR)/*.d clean : ; -rm -fr $(SUBDIR) .PHONY : all clean