在this tutorial之后...
我有2个源文件和1个头文件。我想让他们在单独的目录一样,在教程。
所以我设立了这个项目:
.
├── include
│ └── hellomake.h
├── Makefile
└── src
├── hellofunc.c
└── hellomake.c
生成文件:
IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)
ODIR=obj
LDIR =../lib
_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = hellomake.o hellofunc.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
hellomake: $(OBJ)
gcc -o $@ $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
我生成的错误如下:
gcc -o hellomake -I../include
gcc: fatal error: no input files
compilation terminated.
make: *** [hellomake] Error 4
发生什么事了?
5条答案
按热度按时间mrphzbgm1#
你的教程推广旧的和坏的做法,你应该避免它IMHO。
在你的统治下:
您告诉make在当前目录中查找源代码,而它们实际上驻留在
src
目录中,因此这个模式从未使用过,您也没有合适的模式。确保按如下方式组织项目目录:
然后,让我们使用良好的实践一步一步地执行该过程。
首先,如果你不需要的话,不要定义任何东西。Make有很多预定义的变量和函数,你应该在尝试手工做之前使用它们。事实上,他有这么多,你甚至可以编译一个简单的文件,而不在目录中有一个Makefile!
1.列出源目录和生成输出目录:
1.命名最终目标,即可执行文件:
1.列出源文件:
1.在源文件中,列出目标文件:
1.现在我们来处理旗子
(
CPP
在这里代表C*PreP**处理器,而不是CPlusPlus!使用CXXFLAGS
表示C标志,使用CXX
表示C编译器。)-MMD -MP
标志用于自动生成头文件依赖项,稍后我们将使用它在只有头文件更改时触发编译。好了,现在我们的变量已经正确填充,是时候推出一些配方了。
默认的目标应该被称为
all
,并且它应该是Makefile中的第一个目标,这是一种广泛传播的观点。它的先决条件应该是在命令行中只写make
时要构建的目标:但有一个问题是Make会认为我们实际上想创建一个名为
all
的文件或文件夹,所以让我们告诉他这不是一个真实的的目标:现在列出构建可执行文件的先决条件,并填写其配方以告诉make如何处理这些先决条件:
(
CC
代表C*C**编译器。)请注意,您的
$(BIN_DIR)
可能还不存在,因此对编译器的调用可能会失败,让我们告诉make您希望它首先检查它是否存在:一些简短的补充说明:
$(CC)
是一个内置变量,已经包含了在C中编译和链接时所需的内容$(LDFLAGS)
放在目标文件之前,将$(LDLIBS)
放在之后$(CPPFLAGS)
和$(CFLAGS)
在这里无用,编译阶段已经结束,这里是链接阶段下一步,由于源文件和目标文件不共享相同的前缀,您需要告诉make具体要做什么,因为它的内置规则并不适用于您的特定情况:
同样的问题,你的
$(OBJ_DIR)
可能还不存在,所以对编译器的调用可能会失败。好了,现在可执行文件应该构建得很好了。不过我们需要一个简单的规则来清理构建工件:
(同样,clean不是需要创建的目标,因此将其添加到
.PHONY
特殊目标中!)最后一件事。还记得自动依赖项生成吗?GCC和Clang会创建与您的
.o
文件相对应的.d
文件,其中包含供我们使用的Makefile规则,所以让我们将其包含在这里:最终结果:
3phpmpom2#
make实用程序,没有特定的'target',将创建文件中的第一个目标。
第一个目标通常命名为“all”
对于提交的文件,将生成目标文件,并且在命令行中未给定目标时,将不继续生成可执行文件
建议如下:
u0sqgete3#
简单的Makefile定义在你的问题中看起来还不错。试着在文件名之前指定编译器选项:
您需要从源目录运行
make
。bcs8qyzn4#
当您收到此错误时”
“,这意味着您没有对象文件,
只需查看Makefile中行“*
${OBJS} :=
*“。嗨,兄弟!
如果您的项目“
helloFunc
“的架构是这样的:您Makefile应该如下所示:
将该Makefile更改为所需的Linux版本:
您需要注意的是,“
Makefile
“文件与包含文件和源文件位于同一目录,所以你需要在你的“
Makefile
“中把你的“IDIR:=../include
“改为“IDIR:=./include”。结束!
nnvyjq4y5#
这是我在我的windows安装使用: