许多子文件夹的Makefile

时间:2017-09-22 13:42:58

标签: c++ makefile

我有以下文件夹结构:

├── 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

我试图首先将libXClasses.cc和libXClasses.h编译为./external/build/libX.o,然后将所有libX.o组合成./external/build/external.so。 在第2步中,我想将SomeClass.h和SomeClass.cc编译成./build/SomeClass.o和SomeOtherClass.h,SomeOtherClass.cc编译成./build/SomeOtherClass.o。最后,我想将./external/build/external.o和./build/*.o链接到./build中的二进制文件。

然而,我已经在第1步中失败了。我对./external/Makefile的想法是这样的:

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 $@

这不像最后一条规则那样工作,我没有指定正确的.cc和.h来自哪里。但我不知道我怎么能这样做。我是否必须分别为每个libX目录编写规则?如果我有10个或20个libX目录怎么办?

干杯!

1 个答案:

答案 0 :(得分:0)

步骤1:创建libX目录列表(因为没有人想要手动维护这样的列表):

LIBS := $(wildcard external/lib*)

第2步:创建源文件列表:

LIB_SRCS := $(notdir $(wildcard $(addsuffix /*.cc, $(LIBS))))

(我已经删除了路径,因为它们很痛苦;这样做的方法不止一种。)

步骤3:创建所需目标文件的列表:

OBJS := $(patsubst lib%Classes.cc, external/build/lib%.o, $(LIB_SRCS))

步骤4:编写规则来构建这些文件:

vpath %.cc $(LIBS)

$(OBJS): external/build/lib%.o: lib%Classes.cc
    $(CXX) -c -fPIC -I$(dir $<) $< -o $@

(步骤5:编写规则来构建库,但是你已经有了。)

人们可以做得更多。此makefile未检测到libN.o依赖于libNClasses.h的事实。可以设置它,但它有点复杂,这一天就足够了。