C++ 创建makefile c++;将.o存储到一个目录

C++ 创建makefile c++;将.o存储到一个目录,c++,c,makefile,C++,C,Makefile,以下是如何存储我的数据的示例: \Program main.cpp makefile \Part1 file1.cpp file1.h file2.cpp etc \Part2 file3.cpp file4.cpp file4.h etc.. \Part3 file5

以下是如何存储我的数据的示例:

\Program
     main.cpp
     makefile
     \Part1
          file1.cpp
          file1.h
          file2.cpp
          etc
     \Part2
          file3.cpp
          file4.cpp
          file4.h
          etc..
     \Part3
          file5.cpp
          file5.h
          etc..

     \Objects
          file1.o
          file2.o
          file3.o
          file4.o
我想你明白了

我的问题是,无论我尝试什么,我的makefile都不起作用

叮当声:错误:没有输入文件

架构x86_64的未定义符号:

嗯,我试着自己学习如何构建一个makefile。我学习最简单的方法是:

all:exe
exe: Objects/file1.o Objects/file2.o Objects/file3.o Objects/file4.o Objects/file5.o .....
     $(CPP) $(LFLAGS) Objects/file1.o Objects/file2.o Objects/file3.o ... -o exe
然后,对于每个.o,我要求生成文件执行以下操作:

Objects/file1.0: Part1/file1.cpp
         $(CPP) $(CFLAGS) -o $(OBJ/file1).o Part1/file1.o
但我一直有这个问题:

makefile:XX:警告:覆盖目标
.o'的命令
makefile:XX:警告:忽略目标的旧命令
.o'

对于每个文件

我试图学习如何更恰当地构建makefile,但这相当困难。我尝试了很多很多东西,但都没用

这就是我所说的编写makefile的正确方法

ALL_CPP=Part1/*.cpp, Part2/*.cpp, Part3/*.cpp, Part4/*.cpp
CPP_FILES := $(wildcard $(ALL_CPP))
OBJ_FILES = $(patsubst $(ALL_CPP),Objects/%.o,$(CPP_FILES))

main: $(OBJ_FILES)
    g++ -o $@ $^

Objects/%.o: Animal/%.cpp
    g++ $(CFLAGS) -c -o $@ $<
Objects/%.o: Enclos/%.cpp
    g++ $(CFLAGS) -c -o $@ $<
Objects/%.o: Menu/%.cpp
    g++ $(CFLAGS) -c -o $@ $<
Objects/%.o: Zoo/%.cpp
    g++ $(CFLAGS) -c -o $@ $<
ALL\u CPP=Part1/*.CPP,Part2/*.CPP,Part3/*.CPP,Part4/*.CPP
CPP_文件:=$(通配符$(所有CPP))
OBJ_文件=$(patsubst$(所有_CPP),对象/%.o,$(CPP_文件))
main:$(对象文件)
g++-o$@$^
对象/%.o:动物/%.cpp
g++$(CFLAGS)-c-o$@$<
对象/%.o:enclose/%.cpp
g++$(CFLAGS)-c-o$@$<
对象/%.o:菜单/%.cpp
g++$(CFLAGS)-c-o$@$<
对象/%.o:Zoo/%.cpp
g++$(CFLAGS)-c-o$@$<
但这当然行不通

我的问题是:

如何创建一个makefile,它可以在像我这样的环境中工作(具有不同的子文件夹),并将.o存储在一个专用文件夹中


我使用的是xcode,但不幸的是,我想要一个菜单,您可以使用在xcode控制台上不起作用的箭头进行导航。

您的第二次尝试非常接近

问题在于这条线

OBJ_FILES = $(patsubst $(ALL_CPP),Objects/%.o,$(CPP_FILES))
$(patsubst)
的第一个参数是要匹配的模式,但
$(ALL_CPP)
不是模式。您希望那里的每个目录都有
dir/%.c
。如果你真的想,你可以列出这些模式,但是有更好的方法

这里有两个变换。一个用
对象替换任何前导目录
,另一个用
.o
替换
.cpp

所以要分开做

在第一部分中使用a:

OBJ_FILES := $(CPP_FILES:.cpp=.o)
以及第二部分的
notdir
addprefix

OBJ_FILES := $(addprefix Objects/,$(notdir $(OBJ_FILES))

这应该能让事情顺利进行。

Objets!=对象对不起,我会编辑。这个错误是因为我做了翻译,因为英语不是我的母语。说明为什么第二个例子不起作用会有帮助。首先,谢谢你花时间解释我。如果我理解得好,我有两个“OBJ_文件”?我想,在一个文件中,我有“未定义的体系结构x86_64符号:”,但我认为这是我的错(即使我不理解为什么,因为它在XCode上运行得非常好)另一个问题,%.o和*.o之间的区别是什么?看起来它做的事情和我做的一样,它现在工作了,但没有使用你的方法,因为它给了我错误。。。我对12个文件g++-o exe main.cpp folder/file1.cpp etcYou有一个
OBJ_文件
变量,您只需分配给它两次。第二次使用第一个值作为“输入”的一部分。我没有改变你的编译行。如果那些人以前工作过,现在就工作了。如果没有,那么这是您需要解决的其他问题,但它不会影响我在这里编写的内容。请参阅了解make如何在文件名中使用
*
。而
%
是模式中的“通配符”,无论是函数还是模式和隐式规则(您也可以阅读手册中的更多内容)。