2011-03-11 36 views
8

我的最新项目是在C++中,我正在使用GNU Make。 项目目录布局如下:使源文件的子目录

project 
|-src 
    |-subdir1 
    |-subdir2 (containing tests) 
|-doc 
|-bin 

我想能够调用make在顶级目录(即需要在项目目录中生成文件)编译所有来源都“SRC”子目录并将生成的二进制文件放在“bin”目录中。

什么是最好的方法来做到这一点?如果我不必为每个源文件添加make规则,但在目录中只有一个用于所有.cc和.h文件的话,这也会很棒。

回答

14

Make允许您概括规则,因此您不需要为每个文件创建一个规则。

project 
|-src 
    |-subdir1 
    |-subdir2 (containing tests) 
|-doc 
|-bin 

你可以尝试这样的事情:

#This finds all your cc files and places then into SRC. It's equivalent would be 
# SRC = src/main.cc src/folder1/func1.cc src/folder1/func2.cc src/folder2/func3.cc 

SRC = $(shell find . -name *.cc) 

#This tells Make that somewhere below, you are going to convert all your source into 
#objects, so this is like: 
# OBJ = src/main.o src/folder1/func1.o src/folder1/func2.o src/folder2/func3.o 

OBJ = $(SRC:%.cc=%.o) 

#Tells make your binary is called artifact_name_here and it should be in bin/ 
BIN = bin/artifact_name_here 

# all is the target (you would run make all from the command line). 'all' is dependent 
# on $(BIN) 
all: $(BIN) 

#$(BIN) is dependent on objects 
$(BIN): $(OBJ) 
    g++ <link options etc> 

#each object file is dependent on its source file, and whenever make needs to create 
# an object file, to follow this rule: 
%.o: %.cc 
    g++ -c $< -o [email protected] 
-1

您将不得不在目录中创建子makefile,并使用这些命令将g ++编译的文件输出到所需的目录中。 (使用的makefile变量等)

你会发现在递归的Makefile很好的介绍here

的Makefile让你使用一些通用的规则,如:

%.o:%.cpp 
    gcc blahblahblah 

,你也可以包括全球从另一个使用include的makefile。

如果你还谷歌的makefile,你会发现很多有关该主题的方法。

3

使用一个make运行做构建(我不是递归化妆的粉丝)。不要使用$(shell),因为它会杀死性能。将构建产品放入临时目录中。

素描:

subdir1-srcs := $(addprefix subdir1/,1.cc 2.cc 3.cc) 
subdir1-objs := ${subdir1-srcs:subdir1/%.cc=subdir1/obj/%.o) 
bin/prog1: ${subdir1-objs} ; gcc $^ -o [email protected] 
${subdir1-objs}: subdir1/obj/%.o: subdir1/%.cC# Static pattern rules rule 
    gcc -c $< -o [email protected] 
${subdir1-objs}: subdir1/obj/.mkdir # Need to create folder before compiling 
subdir1/obj/.mkdir: 
    mkdir -p ${@D} 
    touch [email protected] 

,你可以在这里看到的样板?一些功能与$(eval)在一起应该让你写:

$(call build,bin/prog1,subdir1,1.cc 2.cc 3.cc) 
$(call build,bin/prog2,subdir2,a.cc b.cc c.cc d.cc) 

与这些目标自动添加为假all的依赖关系,并很好地兼容-j(只需输入make -j5 all建)。

相关问题