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
当我在同一个目录中运行“make 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
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文件,这会导致一些链接问题。你是对的。我编辑了我的答案,并添加了两种可能来解决这个问题。