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
而不是CC
和CXXFLAGS
而不是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
,….