Makefile执行了意外行为 我使用下面的MaFag文件编译C++文件,但是发生了一些意外的行为。环境是MacOS X Mojave。生成文件如下所示: CC=gcc CXX=g++ CXXFLAGS=-std=c++11 RM=rm -f all: clean sort_test ds_test sort_test: data_structure sort .sort_test.o .sort_test .sort_test: sort_test.o sort.o ds.o $(CXX) $(CXXFLAGS) -o sort_test sort_test.o sort.o ds.o .sort_test.o: sort_test.cpp ../include/io.hpp $(CXX) $(CXXFLAGS) -c -o sort_test.o sort_test.cpp sort: ../include/sort.hpp ../include/data_structure.hpp ../src/sort.cpp $(CXX) $(CXXFLAGS) -c -o sort.o ../src/sort.cpp data_structure: ../include/data_structure.hpp ../src/data_structure.cpp ../include/io.hpp $(CXX) $(CXXFLAGS) -c -o ds.o ../src/data_structure.cpp ds_test: data_structure .ds_test.o .ds_test .ds_test: ds.o ds_test.o $(CXX) $(CXXFLAGS) -o ds_test ds.o ds_test.o .ds_test.o: ds_test.cpp ../include/io.hpp ../include/data_structure.hpp $(CXX) $(CXXFLAGS) -c -o ds_test.o ds_test.cpp clean: $(RM) *.o sort_test ds_test

Makefile执行了意外行为 我使用下面的MaFag文件编译C++文件,但是发生了一些意外的行为。环境是MacOS X Mojave。生成文件如下所示: CC=gcc CXX=g++ CXXFLAGS=-std=c++11 RM=rm -f all: clean sort_test ds_test sort_test: data_structure sort .sort_test.o .sort_test .sort_test: sort_test.o sort.o ds.o $(CXX) $(CXXFLAGS) -o sort_test sort_test.o sort.o ds.o .sort_test.o: sort_test.cpp ../include/io.hpp $(CXX) $(CXXFLAGS) -c -o sort_test.o sort_test.cpp sort: ../include/sort.hpp ../include/data_structure.hpp ../src/sort.cpp $(CXX) $(CXXFLAGS) -c -o sort.o ../src/sort.cpp data_structure: ../include/data_structure.hpp ../src/data_structure.cpp ../include/io.hpp $(CXX) $(CXXFLAGS) -c -o ds.o ../src/data_structure.cpp ds_test: data_structure .ds_test.o .ds_test .ds_test: ds.o ds_test.o $(CXX) $(CXXFLAGS) -o ds_test ds.o ds_test.o .ds_test.o: ds_test.cpp ../include/io.hpp ../include/data_structure.hpp $(CXX) $(CXXFLAGS) -c -o ds_test.o ds_test.cpp clean: $(RM) *.o sort_test ds_test,makefile,g++,gnu-make,Makefile,G++,Gnu Make,当我在同一个目录中运行“make ds_test”时,发生了一些奇怪的事情: g++ -std=c++11 -c -o ds_test.o ds_test.cpp g++ -std=c++11 -c -o ds.o ../src/data_structure.cpp g++ -std=c++11 -c -o ds_test.o ds_test.cpp g++ -std=c++11 -o ds_test ds.o ds_test.o gcc ds_test.o data_structure

当我在同一个目录中运行“make ds_test”时,发生了一些奇怪的事情:

g++ -std=c++11   -c -o ds_test.o ds_test.cpp
g++ -std=c++11 -c -o ds.o ../src/data_structure.cpp
g++ -std=c++11 -c -o ds_test.o ds_test.cpp
g++ -std=c++11 -o ds_test ds.o ds_test.o
gcc   ds_test.o data_structure .ds_test.o .ds_test   -o ds_test
clang: error: no such file or directory: 'data_structure'
clang: error: no such file or directory: '.ds_test.o'
clang: error: no such file or directory: '.ds_test'
make: *** [ds_test] Error 1
“make ds_test”命令永远不会出现此输出中的第一行和第五行,因为它应该只调用“data_structure”、“.ds_test.o”和“.ds_test”。
任何人,请解释为什么会发生这些意外行为,以及如何避免?谢谢

您的Makefile有点奇怪。基本的制定规则如下:

file-to-build: files-it-depends-on
    command-to-build
CC       := gcc
CXX      := g++
CXXFLAGS := -std=c++11
RM       := rm -f

.PHONY: all clean

all: clean sort_test ds_test

sort_test: sort_test.o sort.o data_structure.o
    $(CXX) $(CXXFLAGS) -o $@ $^

sort_test.o: sort_test.cpp ../include/io.hpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

sort.o: ../src/sort.cpp ../include/sort.hpp ../include/data_structure.hpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

data_structure.o: ../src/data_structure.cpp ../include/data_structure.hpp ../include/io.hpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

ds_test: data_structure.o ds_test.o
    $(CXX) $(CXXFLAGS) -o $@ $^

ds_test.o: ds_test.cpp ../include/io.hpp ../include/data_structure.hpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

clean:
    $(RM) *.o sort_test ds_test
而你写的东西是:

.ds_test: ds.o ds_test.o
        $(CXX) $(CXXFLAGS) -o ds_test ds.o ds_test.o
其中目标不是配方生成的文件。此外,您可以在没有适当扩展的情况下重命名对象(
data\u structure
ds.o
)。最后,对同一事物使用不同的名称(同样是
data\u-structure
ds.o
)。如果你从C++开始,你应该避免所有这些花哨的东西。 Makefile失败的主要原因是make试图构建一个名为
ds\u test
的文件(这是您在键入
make ds\u test
时要求的)。make知道很多构建文件的方法。在这种特定情况下,它使用默认规则,其中包括使用
$(CC)
链接
ds\u test.o
和所有其他文件
ds\u test
所依赖的,即
数据结构
.ds\u test.o
.ds\u test

如果你是新手,我建议你首先坚持最基本的原则。比如:

file-to-build: files-it-depends-on
    command-to-build
CC       := gcc
CXX      := g++
CXXFLAGS := -std=c++11
RM       := rm -f

.PHONY: all clean

all: clean sort_test ds_test

sort_test: sort_test.o sort.o data_structure.o
    $(CXX) $(CXXFLAGS) -o $@ $^

sort_test.o: sort_test.cpp ../include/io.hpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

sort.o: ../src/sort.cpp ../include/sort.hpp ../include/data_structure.hpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

data_structure.o: ../src/data_structure.cpp ../include/data_structure.hpp ../include/io.hpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

ds_test: data_structure.o ds_test.o
    $(CXX) $(CXXFLAGS) -o $@ $^

ds_test.o: ds_test.cpp ../include/io.hpp ../include/data_structure.hpp
    $(CXX) $(CXXFLAGS) -c -o $@ $<

clean:
    $(RM) *.o sort_test ds_test
注意:由于make将使用
gcc
进行链接,我们必须将
-lstdc++
添加到链接器标志(
LDLIBS
)。另一个选项是指定链接规则,而不是使用默认规则:

$(EXEC):
    $(CXX) $(CXXFLAGS) -o $@ $^

请注意,在最后一种情况下,指定先决条件的规则和指定配方的规则是不同的。

嗨,雷诺,这个答案对我帮助很大,非常感谢!顺便说一句,对于“sort_test”和“ds_test”,我必须手动添加命令以使用$(CXX),否则他们将默认使用gcc链接*.o文件,这会导致一些链接问题。你是对的。我编辑了我的答案,并添加了两种可能来解决这个问题。