我有以下文件夹结构:
├── 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目录怎么办?
干杯!
答案 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
的事实。可以设置它,但它有点复杂,这一天就足够了。