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

时间:2015-09-16 01:45:06

标签: c makefile g++ gnu-make

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

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

根文件夹
makefile文件
自述
src文件夹
...源文件全部在这里......
包含文件夹
...此处外部库的头文件......
lib文件夹
...外部lib文件都在这里......
bin文件夹
...构建可执行文件的输出目录...
obj文件夹
...这里的目标文件......

我按照教程here

这是我的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.
<builtin>: recipe for target '.o' failed
mingw32-make.exe: *** [.o] Error 1

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

有人能指出我正在制造的任何荒谬的错误吗?

2 个答案:

答案 0 :(得分:1)

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

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

然后-I$(IDIR)不“分发”-IIDIR从未在其他地方使用过。所以我建议你用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(并从其source代码编译make 4.1值得在2015年)为此目的。如果可能的话,在其中启用GUILE脚本。

如果您被迫使用make 3.82使用remakeMakefile)调试-x;如果您负担得起make版本4,请使用其--trace选项

BTW,您可以考虑使用自动依赖项,即通过传递g++的{​​{3}}标志来生成依赖项,请参阅-M or -MG (etc)

最后,一个小程序的简单项目(不到十万个源代码行)可能只将所有(几十个)文件放在当前目录中(然后是{ {1}}可能更简单);对于简单项目,您提出的目录结构可能是神秘的(但如果您有数百万个C ++源代码行,则值得痛苦)。我已经给出了Makefile的几个简单示例,例如that&amp; this。 GNU make源代码本身有一个不太复杂的文件树,你想要的。

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

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

答案 1 :(得分:1)

IDIR=include .

是第一个问题。替换为:

IDIR=include

将代码CFLAGS扩展为:

-Iinclude .

没有意义,我很害怕。第二个问题是:

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

应该是:

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

并将扩展为:

DEPS=include/hello.h

如果您解决了第一个问题,请执行以下操作:

DEPS=include ./hello.h

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