GNU MAKE:缺少分离器。停止'源代码文件的含义?
我是Makefiles的新手,我正在尝试使用GCC
为C项目创建一个。
我熟悉错误makefile:< col>:***缺少分离器。停止。
它在我使用空格而不是标签以先于makefile中的规则之前弹出。我只是尝试为这个特定项目编写一个makefile(确保使用选项卡字符而不是空格),当我运行make
命令时,我会遇到一个非常不明智的错误,我不明白如何修复: src/main.c:7:***缺少分离器。 stop
我的目录结构看起来像这样:
- projectfolder/
- Makefile
- bin/
- build/
- inc/
- src/
- main.c
- otherfolder/
- inc/
- common.h
- io.h
- src/
- io.c
main.c
,其中包括main
函数,具有以下导入:
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "io.h"
我的目标是制作一堆<<代码> .o 和.d
来自src/
和inc/
目录的文件中的文件> projectFolder/build/,以便可以使用ProjectFolder/bin/code>在
projectfolder/bin/code>中使最终
权
# Compiler and linker
CC := gcc
# Target binary
TARGET := the-program
# File extensions
SRCEXT := c
# Directories
TARGETDIR := bin
BUILDDIR := build
SRCDIRS := src /home/myusername/otherfolder/src
INCDIRS := inc /home/myusername/otherfolder/inc
# gcc options
CCFLAGS := -Wall -Wextra -O3
#---------------------------------------------------------------------------------
#DO NOT EDIT BELOW THIS LINE
#---------------------------------------------------------------------------------
vpath %.$(SRCEXT) $(SRCDIRS)
vpath %.h $(INCDIRS)
CCFLAGS += $(addprefix -I,$(INCDIRS)) -MMD -MP
SRC := $(shell find $(SRCDIRS) -name *.$(SRCEXT))
OBJ := $(SRC:$(SRCDIRS)/%.$(SRCEXT)=$(BUILDDIR)/%.o)
DEP := $(OBJ:.o=.d)
TARGET := $(TARGETDIR)/$(TARGET)
# RULE: Default make
all: makedirs $(TARGET) clean
# RULE: Remake
remake: fullclean all
# RULE: Clean
clean:
rm -rf $(BUILDDIR)
# RULE: Full clean (objects and binaries)
fullclean: clean
rm -rf $(TARGETDIR)
# RULE: Make dirs
makedirs:
mkdir -p $(BUILDDIR)
mkdir -p $(TARGETDIR)
# RULE: Link
$(TARGET): $(OBJ)
$(CC) $(OBJ) -o $@
# RULE: Compile
$(OBJ): $(SRC)
$(CC) $(CCFLAGS) -c $< -o $@
# RULE: Non-file targets
.PHONY: all remake clean fullclean makedirs
# include dependencies
-include $(DEP)
执行 会导致所述错误吗?我假设它与makefile本身有关,而不是src/main.c
实际上包含的C代码,因为这似乎不是汇编错误,但是如果我错了,请让我知道,我可以更改帖子。
I'm fairly new to Makefiles, and I am trying to create one for a C project I am building using gcc
.
I am familiar with the error Makefile:<col>: *** missing separator. Stop.
It has popped up before when I used spaces instead of tabs to precede rules in the Makefile. I just tried writing a Makefile for this particular project (being sure to use TAB character instead of spaces) and when I run the make
command, I get a very nondescript error I do not understand how to fix: src/main.c:7: *** missing separator. Stop
My directory structure looks like this:
- projectfolder/
- Makefile
- bin/
- build/
- inc/
- src/
- main.c
- otherfolder/
- inc/
- common.h
- io.h
- src/
- io.c
main.c
, which includes the main
function, has the following imports:
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "io.h"
My goal is to make a bunch of .o
and .d
files from the files in both src/
and inc/
directories and put those into projectfolder/build/
, so that they can then be used to make the final executable in projectfolder/bin/
Finally, here is the Makefile that is causing the issue:
# Compiler and linker
CC := gcc
# Target binary
TARGET := the-program
# File extensions
SRCEXT := c
# Directories
TARGETDIR := bin
BUILDDIR := build
SRCDIRS := src /home/myusername/otherfolder/src
INCDIRS := inc /home/myusername/otherfolder/inc
# gcc options
CCFLAGS := -Wall -Wextra -O3
#---------------------------------------------------------------------------------
#DO NOT EDIT BELOW THIS LINE
#---------------------------------------------------------------------------------
vpath %.$(SRCEXT) $(SRCDIRS)
vpath %.h $(INCDIRS)
CCFLAGS += $(addprefix -I,$(INCDIRS)) -MMD -MP
SRC := $(shell find $(SRCDIRS) -name *.$(SRCEXT))
OBJ := $(SRC:$(SRCDIRS)/%.$(SRCEXT)=$(BUILDDIR)/%.o)
DEP := $(OBJ:.o=.d)
TARGET := $(TARGETDIR)/$(TARGET)
# RULE: Default make
all: makedirs $(TARGET) clean
# RULE: Remake
remake: fullclean all
# RULE: Clean
clean:
rm -rf $(BUILDDIR)
# RULE: Full clean (objects and binaries)
fullclean: clean
rm -rf $(TARGETDIR)
# RULE: Make dirs
makedirs:
mkdir -p $(BUILDDIR)
mkdir -p $(TARGETDIR)
# RULE: Link
$(TARGET): $(OBJ)
$(CC) $(OBJ) -o $@
# RULE: Compile
$(OBJ): $(SRC)
$(CC) $(CCFLAGS) -c lt; -o $@
# RULE: Non-file targets
.PHONY: all remake clean fullclean makedirs
# include dependencies
-include $(DEP)
What about this file would cause the described error? I am assuming that it is related to the Makefile itself rather than the C code actually contained in src/main.c
since this does not appear to be a compilation error, but if I am wrong, let me know and I can change the post.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此错误:
显然是由Make打印。由于我们知道这些消息的格式是
&lt; makefile&gt;:&lt; linenumber&gt;:&lt; error&gt;
,我们可以看到这是试图解析文件src/main.c.c.c.c.c
作为makefile,显然这是行不通的。如何做这样的事情?显而易见的罪魁祸首是:
如果变量
dep
包含文件src/main.c
,那么Make将尝试将其包括在内并解析。那么dep
如何设置?这将以
obj
以.o
结尾的所有单词更改为.d
结束。至关重要的是,应该注意的是,这没有任何更改 以.o
结尾的单词。因此,如果objs
包含src/main.c
,则将其通过未修改的deps
。那么
obj
如何设置?以下是相关变量:让我们扩展以下内容:
src
变量运行: )。
现在我们要说SRC获得了值:
现在
obj
包含什么?这显然无法使用:您不能将多个目录放入
srcdirs
中,但随后将其视为仅包含一个单词。This error:
is clearly being printed by make. Since we know the format of these messages is
<makefile>:<linenumber>: <error>
, we can see that make is trying to parse the filesrc/main.c
as a makefile and obviously this cannot work.How could make be doing such a thing? The obvious culprit is this line:
If the variable
DEP
contains the filesrc/main.c
, then make would try to include that as a makefile and parse it. So how isDEP
set?This changes all words in
OBJ
that end with.o
to end with.d
. Crucially, it should be noted that this makes no changes to words that do not end in.o
. So, ifOBJS
containedsrc/main.c
, this would pass it through unmodified toDEPS
.So how is
OBJ
set? Here are the relevant variables:Let's expand this: the
SRC
variable runs:(you really should escape the
*
, either with backslash or quotes: it's very dangerous how you have this).Now we'll say that SRC gets the value:
Now what does
OBJ
contain?This clearly cannot work: you can't put multiple directories into
SRCDIRS
, but then treat it as if it contained only one word.问题是在线中,
模式替代起作用 ,其中模式匹配,而则使所有其他字符串单独。
作为一个简单的演示,请参阅此makefile(没有规则,只有变量分配):
输出:
您可以看到,
foo
仍然存在,尽管它与模式ba%<不匹配,但仍未改变/代码>。
在您的情况下,您将无法替代模式,
$(srcdirs)的内容
是两个单词:src/home/myusername/myusername/shotherfolder/src
to替代调用,因此main.c
- 是src/main.c
或/home/myusername/myusername/otherfolder/src/src/main.c
保持在您的列表中保持不变,无意间冲入$(dep)
中,最终作为文本包含在您的最后一行incclude $(dep)
。作为建议,我想向您指出
vather
(请参阅手册,此处: https://www.cmcrossroads.com/article/basics-vath-and-vath ),这是指示源位置到make
。The problem is in the line
The pattern substitution works only where the pattern matches and leaves all other strings alone.
As a simple demonstration see this makefile (no rules, just variable assignments):
Output:
As you can see,
foo
still is there, unchanged although it didn't match the patternba%
.In your case you are passing an impossible to substitute pattern, the content of
$(SRCDIRS)
, which is the two words:src /home/myusername/otherfolder/src
to the substitution call, thereforemain.c
- which is eithersrc/main.c
or/home/myusername/otherfolder/src/main.c
remains unchanged in your list, gets inadvertently flushed further into$(DEP)
and is finally included as text with your last line-include $(DEP)
.As a recommendation I want to point you to
VPATH
(see manual and here: https://www.cmcrossroads.com/article/basics-vpath-and-vpath), which is the better alternative to indicate the location of your sources tomake
.