使用Makefile在子目录中生成目标文件

时间:2012-02-13 11:54:29

标签: makefile subdirectory

我正在尝试创建一个Makefile,以便在子目录中生成目标文件,而不是让它们在src /文件夹中。 这是项目的结构:

Trunk
- Server
  - src/
  - include/
- Common
  - src/
  - include/

Makefile位于Trunk/Server。源文件位于Server/srcCommon/src中,因此Makefile目前具有以下内容:

SRC        =        src/main.cpp                  \
                    src/Network.cpp               \
                    ../Common/src/SQLManager.cpp  \
                    ../Common/src/Utils.cpp

我想把生成的对象文件放在相应的obj个文件夹中,所以Trunk/Server/objTrunk/Common/obj。我怎样才能做到这一点?我发现了很多方法可以在子目录中生成目标文件(vpathpatsubst等等),但是我不能让它们适用于这个文件夹组织。

编辑:如果有办法将所有目标文件放在Server/obj/中,那也可以。

这是完整的Makefile(减去一些源文件和链接库): Edit2:更新了Didier Trosset的更改

CXX             =       g++

RM              =       rm -vf

NAME            =       Server

SRC             =       src/main.cpp                  \
                        src/Network.cpp               \
                        ../Common/src/SQLManager.cpp  \
                        ../Common/src/Utils.cpp

OBJ             =       $(subst src/,obj/, $(subst .cpp,.o, $(SRC)))

LDFLAGS         =       -lpthread -lm

CPPFLAGS        =       -std=c++0x -pedantic -Wextra -Wall -Wconversion -Iinclude -I../Common/include

all: Server

%.o: %.cpp
        $(CXX) $< -o $@

Server: $(OBJ)
        $(CXX) -o $(NAME) $(OBJ) $(LDFLAGS)

clean:
        $(RM) $(OBJ) *~

fclean: clean
        $(RM) $(NAME)

re: fclean Server

.PHONY: all clean fclean Server

3 个答案:

答案 0 :(得分:3)

鉴于这些定义,应使用subst替换目录的src部分和文件扩展名。

OBJ = $(subst src/,bin/,$(subst .cpp,.o,$(SRC)))

然后,您必须添加新的模式规则来编译源文件。 (您必须为源文件所在的每个目录编写一个模式规则。)

obj/%.o: src/%.cpp
         $(CXX) -c $< -o $@

../Common/obj/%.o: ../Common/src/%.cpp
         $(CXX) -c $< -o $@

答案 1 :(得分:0)

我不确定这会起作用,但我会尝试这样的事情:

OBJ := $(join $(addsuffix ../obj/,$(dir $(SRC))),$(notdir $(SRC))
# or, as Didier suggested:
# OBJ := $(subst src/,obj/,$(SRC))

%.o: ../src/%.cpp
    $(CXX) $< -o $@

答案 2 :(得分:0)

目前尚不清楚你究竟要做什么,但这应该接近:

OBJ = $(subst src/,obj/,$(SRC:.cpp=.o))

obj/%.o : src/%.cpp
    $(CXX) $< -o $@

../Common/obj/%.o : ../Common/src/%.cpp
    $(CXX) $< -o $@