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

使用Makefile在子目录中生成对象文件,makefile,subdirectory,Makefile,Subdirectory,我试图创建一个Makefile,以便在子目录中生成对象文件,而不是将它们放在src/文件夹中。 以下是该项目的结构: Trunk - Server - src/ - include/ - Common - src/ - include/ Makefile位于Trunk/Server中。源文件位于Server/src和Common/src中,因此Makefile当前有如下内容: SRC = src/main.cpp \

我试图创建一个Makefile,以便在子目录中生成对象文件,而不是将它们放在src/文件夹中。 以下是该项目的结构:

Trunk
- Server
  - src/
  - include/
- Common
  - src/
  - include/
Makefile位于
Trunk/Server
中。源文件位于
Server/src
Common/src
中,因此Makefile当前有如下内容:

SRC        =        src/main.cpp                  \
                    src/Network.cpp               \
                    ../Common/src/SQLManager.cpp  \
                    ../Common/src/Utils.cpp
我想将生成的对象文件放在相应的
obj
文件夹中,因此
Trunk/Server/obj
Trunk/Common/obj
。我怎样才能做到这一点?我已经找到了许多在子目录中生成对象文件的方法(
vpath
patsubst
以及更多),但我无法使它们中的任何一种适用于此文件夹组织

编辑:如果有办法将所有对象文件放入
Server/obj/
中,也可以

以下是完整的Makefile(减去一些源文件和链接库): 编辑2:更新了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
CXX=g++
RM=RM-vf
名称=服务器
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
全部:服务器
%.o:%.cpp
$(CXX)$<-o$@
服务器:$(OBJ)
$(CXX)-o$(名称)$(OBJ)$(LDFLAGS)
清洁:
$(RM)$(OBJ)*~
清洁:清洁
$(RM)$(名称)
回复:fclean服务器
.假冒:所有清洁fclean服务器

根据这些定义,应使用
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$@

根据这些定义,应使用
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$@

我不确定这是否有效,但我会尝试以下方法:

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

%.o: ../src/%.cpp
    $(CXX) $< -o $@
OBJ:=$(join$(addsuffix../OBJ/,$(dir$(SRC)),$(notdir$(SRC))
#或者,正如迪迪埃所说:
#OBJ:=$(subst src/,OBJ/,$(src))
%.o:../src/%.cpp
$(CXX)$<-o$@

我不确定这是否有效,但我会尝试以下方法:

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

%.o: ../src/%.cpp
    $(CXX) $< -o $@
OBJ:=$(join$(addsuffix../OBJ/,$(dir$(SRC)),$(notdir$(SRC))
#或者,正如迪迪埃所说:
#OBJ:=$(subst src/,OBJ/,$(src))
%.o:../src/%.cpp
$(CXX)$<-o$@

不清楚您到底想做什么,但这应该很接近:

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

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

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

不清楚您到底想做什么,但这应该很接近:

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

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

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

我试过了(在
subst
之后删除了多余的逗号),它似乎使GCC在
obj/
中查找
.cpp
文件,而不是
src/
…我得到了一个
无规则来生成目标
错误。@Jukurrpa感谢逗号。另外,生成文件的其余部分是什么。你在这里发布的内容还不够!你需要其他目标,至少是链接你的对象。是的,我没有指定确定“常规”规则,例如调用
$(OBJ)
的规则,然后是所有对象的链接。如果可以帮助您找到解决方案,我可以将它们添加到我的原始帖子中:)@Jukurrpa请发布更多的Makefile。该错误似乎与
SRC
OBJ
现在无关。我添加了我的“原始”Makefile。我用你的替换了我的
OBJ
,添加了
%.o
规则,并立即获得了
make:**没有规则将目标设置为“OBJ/main.cpp”,这是“服务器”所需要的。
我尝试过了(删除
subst
后的多余逗号后),它似乎使GCC在
obj/
中查找
.cpp
文件,而不是
src/
…我得到了一个
无规则来生成目标
错误。@Jukurrpa感谢逗号。另外,生成文件的其余部分是什么。你在这里发布的内容还不够!你需要其他目标,至少是链接你的对象。是的,我没有指定确定“常规”规则,例如调用
$(OBJ)
的规则,然后是所有对象的链接。如果可以帮助您找到解决方案,我可以将它们添加到我的原始帖子中:)@Jukurrpa请发布更多的Makefile。该错误似乎与
SRC
OBJ
现在无关。我添加了我的“原始”Makefile。我用你的替换了我的
OBJ
,添加了
%.o
规则,并立即获得了
make:**没有规则将目标设置为“OBJ/main.cpp”,这是“服务器”所需的。
我获得了same错误与Didier Trosset的方法相同。它使GCC在
obj/
文件夹中查找
.cpp
文件。我得到的错误与Didier Trosset的方法相同。它使GCC在
obj/
文件夹中查找
.cpp
文件。这里几乎每隔一周都会问这样的问题。你是否尝试过搜索,如果是,你能解释一下吗在“为什么/如何”中,这些问题的答案不适用于您?我确实尝试过搜索,并阅读了如下答案:,。但文件夹结构不适用