I have the following folder structure:
├── build
├── external
│ ├── build
│ ├── lib1
│ │ ├── lib1Classes.cc
│ │ └── lib1Classes.h
│ ├── lib2
│ │ ├── lib2Classes.cc
│ │ └── lib2Classes.h
│ ├── lib3
│ │ ├── lib3Classes.cc
│ │ └── lib3Classes.h
│ └── Makefile
├── include
│ ├── SomeClass.h
│ └── SomeOtherClass.h
├── Makefile
└── src
├── main.cpp
├── SomeClass.cc
└── SomeOtherClass.cc
I am trying to first compile libXClasses.cc and libXClasses.h into ./external/build/libX.o, then combine all libX.o into an ./external/build/external.so. In step 2 I'd like to compile SomeClass.h and SomeClass.cc into ./build/SomeClass.o and SomeOtherClass.h, SomeOtherClass.cc into ./build/SomeOtherClass.o. Finally I want to link ./external/build/external.o and ./build/*.o into a binary in ./build.
I am however already failing in step 1. My idea for ./external/Makefile was something like this:
CXX = g++ -std=c++11
TARGET ?= external.so
BUILD_DIR ?= ./build
# get all source files
SRCS = $(shell find . -name *.cc -or -name *.cpp -or -name *.h)
# get the name of all directories that contain at least one source file
SRC_DIRS ?= $(foreach src,$(SRCS),$(shell dirname $(src)))
# remove duplicate directories
SRC_DIRS := $(shell echo $(SRC_DIRS) | xargs -n1 | sort -u | xargs)
# define one target object file foreach .cc source file
OBJS := $(foreach srcd,$(SRC_DIRS),$(BUILD_DIR)/$(patsubst %.cc,%.o,$(shell find $(srcd) -name *.cc -printf "%f\n")))
# rule to build ./external/build/external.so
$(BUILD_DIR)/$(TARGET): $(OBJS)
$(CXX) -shared $(OBJS) -o $@
# no idea how to build libX.o in one rule
$(BUILD_DIR)/%.o: %.cc %.h
$(CXX) -c -fpic $< -o $@
This does not work as in the last rule I am not specifying where the correct .cc and .h come from. But I don't know how I could do that at all. Do I have to write a rule for each libX directory separately? What if I have 10 or 20 libX directories?
Cheers!