makefile出错(“无输入文件”)

这是我第一次制作makefile,我真的很想了解这个过程。

我正在尝试为C ++项目创建一个非常简单的makefile,其结构如下:

根文件夹
生成文件
自述
src文件夹
……这里的源文件……
包含文件夹
…这里有外部库的头文件…
lib文件夹
…这里的外部lib文件…
bin文件夹
…构建可执行文件的输出目录…
obj文件夹
…这里的目标文件……

我在这里按照教程。

这是我的makefile:

IDIR=include . CC=g++ CFLAGS=-I$(IDIR) ODIR=bin/obj LDIR=lib LIBS=none SRC=src _DEPS=hello.h DEPS=$(patsubst %,$(IDIR)/,%(_DEPS)) _OBJ=file1.o file2.o OBJ=$(patsubst %,$(ODIR)/%,$(_OBJ)) $(ODIR)/%.o: $(SRC)/%.cpp $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) # $(LIBS) test_proj: $(OBJ) $(CC) -o $@ $^ $(CFLAGS) .PHONY: clean clean: rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

当我对此运行make时,我收到以下错误:

 g++ -o .o g++: fatal error: no input files compilation terminated. : recipe for target '.o' failed mingw32-make.exe: *** [.o] Error 1 

我正在使用为i686-pc-mingw32构建的GNU Make 3.82.90,如果这很重要的话。

任何人都可以指出我正在犯的任何荒谬的错误吗?

 IDIR=include . 

是第一个问题。 替换为:

 IDIR=include 

使用您的代码CFLAGS扩展为:

 -Iinclude . 

我害怕,这没有道理。 第二个问题是:

 DEPS=$(patsubst %,$(IDIR)/,%(_DEPS)) 

应该是:

 DEPS=$(patsubst %,$(IDIR)/%,$(_DEPS)) 

并将扩展为:

 DEPS=include/hello.h 

如果你解决了第一个问题,否则:

 DEPS=include ./hello.h 

哪个也没有意义。 这两个错误的累积效应是奇怪的配方(我没有尝试手动扩展它们),可能会触发带有错误参数的make隐式规则。

 IDIR=include . CC=g++ CFLAGS=-I$(IDIR) 

这是错的。 首先,对于C ++代码,使用CXX而不是CCCXXFLAGS而不是CFLAGS 。 运行make -p以了解make -p的内置规则。

然后-I$(IDIR)不“分发” -I ,而IDIR从未在别处使用过。 所以我建议启动你的Makefile

 CXX=g++ MY_CXX_LANG_FLAGS= -std=c++11 MY_CXX_WARN_FLAGS= -Wall -Wextra MY_CXX_INCL_FLAGS= -I. -Iinclude MY_CXX_MACRO_FLAGS= -DMYFOO=32 ### replace with -O2 for a release build below MY_CXX_OPTIM_FLAGS= -g CXXFLAGS= $(MY_CXX_LANG_FLAGS) $(MY_CXX_WARN_FLAGS) \ $(MY_CXX_INCL_FLAGS) $(MY_CXX_MACRO_FLAGS) 

我不会改进你的Makefile ,但我建议尽可能升级到GNU make版本4(并且在2015年从其源代码编译make 4.1)是为了这个目的。 如果可能,在其中启用GUILE脚本。

如果你被迫使用make 3.82使用remake调试你的Makefile (使用-x ); 如果你买得起make版本4,可以使用它的--trace选项

顺便说一下,你可以考虑使用自动依赖,即通过传递g++ -M-MG (等)标志来生成依赖,看看。

最后,一个小程序(不到十万个源代码行)的简单项目可能只将所有(几十个)文件放在当前目录中(然后Makefile可以更简单); 你提出的目录结构对于一个简单的项目来说可能是神秘的(但如果你有数百万个C ++源代码行,那么这个问题可能会很痛苦)。 我已经给出了几个简单Makefile示例,例如这个和那个 。 GNU make源代码本身有一个不太复杂的文件树,你想要的。

顺便说一下,我强烈不同意这个答案的意见(我做了upvote,因为它很有帮助)。 我不觉得GNU make是老态的,但我很遗憾,不是使用最近版本(4.x) make上的最新function,许多人更喜欢使用复杂和神秘的Makefile生成器(如cmake )而不是编码一个聪明的Makefile (具体为make版本4)。

最后,您可以使用其他构建器,例如omake , icmake ,….