makefile的一个错误:*** missing separator
原文转自:http://blog.sina.com.cn/s/blog_87c063060101c9yp.html
1、在写 多目录下makefile的时候,碰到一个错误提示,让我纠结许久,后面还是解决了,这个错误不容易被发现。
2、错误提示如下:
Makefile:8: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
3、先来说一下我想干什么,有些什么?
想干什么: 搭建一个Linux LCD的裸机开发环境,注意是多目录下面的,想写 一个比较通用的makefile。
有什么:父目录①←子目录①(build目录)、子目录①(code目录)
子目录①(build目录)←Makefile make.rule
子目录①(code目录)← 子目录②(startup)、子目录②(lib)、子目录②(foo)、子目录②(huge)
如下图:
1.工程目录下:
2.build 目录下
3.code目录下
4.code目录下的子目录都有2个子目录: src目录(存放.c文件) 、 include目录(存放.h文件)
5、下面贴一下makefile的内容
a. build下面的make.rule:
.PHONY:all clean
CC = arm-linux-gcc
LD = arm-linux-ld
AR = arm-linux-ar
ARFLAGS = crs
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump
CFLAGS := -Wall -O2
RM = rm
RMFLAGS = -fr
export CC LD AR RM RMFLAGS ARFLAGS OBJCOPY OBJDUMP CFLAGS
SRCS = $(wildcard *.c)
ASS = $(wildcard *.S)
OBJS := $(SRCS:.c=.o)
ASMS := $(ASS:.S=.o )
DEPS := $(SRCS:.c=.dep)
ifneq ("$(EXE)","")
EXE := $(EXE)
RMS += $(EXE)
endif
ifneq ("$(LIB)","")
LIB := $(LIB)
RMS += $(LIB)
endif
ifneq ($(INCLUDE_DIRS), "")
INCLUDE_DIRS := $(strip $(INCLUDE_DIRS))
INCLUDE_DIRS := $(addprefix -I, $(INCLUDE_DIRS))
endif
ifneq ($(LINK_LIBS), "")
LINK_LIBS := $(strip $(LINK_LIBS))
LIB_ALL := $(notdir $(wildcard $(DIR_LIB)/*))
LIB_FILTERED := $(addsffix %,$(addprefix lib, $(LINK_LIBS)))
$(evel DEP_LIBS = $(filter $(LIB_FILTERED), $(LIB_ALL) ) )
DEP_LIBS := $(addprefix $(DIR_LIBS)/, $(DEP_LIBS))
LINK_LIBS := $(addprefix -l, $(LINK_LIBS))
endif
all: $(EXE) $(LIB)
$(EXE):$(OBJS) $(LIB)
$(CC) $(CFLAGS) $(INCLUDE_DIRS) -o $@ $^
$(LIB):$(ASMS) $(OBJS)
$(AR) -$(ARFLAGS) $@ $^
%.o : %.c
$(CC) $(CFLAGS) $(INCLUDE_DIRS) -o $@ -c $<</P>
%.o : %.S
$(CC) $(CFLAGS) $(INCLUDE_DIRS) -o $@ -c $<</P>
%.dep: %.c
@echo "Creating $@ ..."
@set -e;\
$(RM) $(RMFLAGS) $@.tmp ;\
$(CC) $(INCLUDE_DIRS) -E -MM $(filter %.c, $^) > $@.tmp ; \
sed 's,\(. *\)\.o[ :]*,objs/\1.o $@: ,g' < $@.tmp > $@ ; \
$(RM) $(RMFLAGS) $@.tmp
clean:
$(RM) $(RMFLAGS) *.bin *.bak *.o *.dep *.a
b. build下面的 Makefile:
.PHONY: all clean touch
ROOT = $(realpath ..)
#注意:因为 huge目录下 是编译 可执行文件(最终目标).所以对于 foo bar huge 这三个目录,huge 需要放到 最后编译。
DIRS = $(ROOT)/code/startup/src \
$(ROOT)/code/lib/src \
$(ROOT)/code/foo/src \
$(ROOT)/code/huge/src
RM = rm
RMFLAGS = -fr
RMS = $(ROOT)/build/exes $(ROOT)/build/libs
all clean:
@set -e; \
for dir in $(DIRS); \
do \
cd $$dir && $(MAKE) ROOT=$(ROOT) $@; \
done
@set -e;\
if ["$(MAKECMDGOALS)" = "clean" ]; \
then $(RM) $(RMFLAGS) $(RMS); fi
@echo ""
@echo ":-) Completed"
@echo ""
touch:
@echo "Processing ......"
@find $(ROOT) -exec touch {} \;
@echo ""
@echo ":-) Completed"
@echo ""
c.huge/src 下面的 makefile:
正确的写法如下:
EXE = huge.bin
LIB =
INCLUDE_DIRS = $(ROOT)/code/huge/include \
$(ROOT)/code/startup/include \
$(ROOT)/code/lib/include \
$(ROOT)/code/foo/include
LINK_LIBS = startup lib foo
include $(ROOT)/build/make.rule
d. startup/src 目录下面Makefile的写法:
#2012-10-21
EXE =
LIB = libstartup.a
INCLUDE_DIRS = $(ROOT)/code/startup/include \
$(ROOT)/code/foo/include
LINK_LIBS =
include $(ROOT)/build/make.rule
e. foo/src 目录下的Makefile :
#2012-10-21
EXE =
LIB = libfoo.a
INCLUDE_DIRS = $(ROOT)/code/foo/include
LINK_LIBS =
include $(ROOT)/build/make.rule
f. lib/src 目录下的Makefile :
#2012-10-21
EXE =
LIB = liblib.a
INCLUDE_DIRS = $(ROOT)/code/lib/include
LINK_LIBS =
include $(ROOT)/build/make.rule
PS:我们重点注意 我们标色的 地方,其它地方不用看。
⑴
INCLUDE_DIRS = $(ROOT)/code/huge/include \
$(ROOT)/code/startup/include \
$(ROOT)/code/lib/include \
$(ROOT)/code/foo/include
PS:在 huge目录下的 C文件 包含了其它目录下面的头文件时(如 foo/include 下面的 2440addr.h),
main.c(假设在 huge/src下):
#include"2440addr.h"
#include"stdio.h"
............
像这样子的 程序,头文件 在 "别人的目录下面" 你想用它 就必须 用 INCLUDE_DIRS = 去选择它的 路径,但是 它($(ROOT)/code/lib/include ) 必须写在 $(ROOT)/code/huge/include 的后面。
如果 将 上面改成 下面这样,就会出现 "文章开始的错误了" :
INCLUDE_DIRS =$(ROOT)/code/lib/include \
$(ROOT)/code/startup/include \
$(ROOT)/code/huge/include \
$(ROOT)/code/foo/include
错误提示:Makefile:8: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
同理下面也是一样的.
⑵
INCLUDE_DIRS = $(ROOT)/code/startup/include \
$(ROOT)/code/foo/include
makefile的一个错误:*** missing separator的更多相关文章
- makefile:4: *** missing separator. Stop.
今天在编写蜂鸣器的驱动程序时,makefile文件是这样: CROSS=arm-linux- all: beep beep: beep.c $(CROSS)gcc -o beep beep.c $(C ...
- [ASM C/C++] C makefile:2: *** missing separator. Stop. 问题
在利用make编译代码时,makefile文件的目标代码前面要用tab而不能用空格来代替. 要不然就会提示: makefile:2: *** missing separator. Stop. 要注意 ...
- Makefile:130: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
修改了snmp里面的包Makefile,出现了如下问题: Makefile:130: *** missing separator (did you mean TAB instead of 8 spac ...
- makefile:n: *** missing separator. Stop
makefile has a very stupid relation with tabs, all actions of every rule are identified by tabs .... ...
- Linux C编程学习之开发工具3---多文件项目管理、Makefile、一个通用的Makefile
GNU Make简介 大型项目的开发过程中,往往会划分出若干个功能模块,这样可以保证软件的易维护性. 作为项目的组成部分,各个模块不可避免的存在各种联系,如果其中某个模块发生改动,那么其他的模块需要相 ...
- C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素”
Q: 在反序列化 Xml 字符串为 Xml 对象时,抛出如下异常. 即在 XML文档(0, 0)中有一个错误:缺少根元素. A: 首先看下代码: StringBuilder sb = new Stri ...
- 处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler”
新服务器安装完开发环境后,还需要注册framework4.0到IIS.不然会报错: HTTP 错误 500.21 - Internal Server Error 处理程序“Extensionles ...
- 关于Java中的继承和组合的一个错误使用的例子
[TOC] 关于Java中的继承和组合的一个错误使用的例子 相信绝大多数人都比较熟悉Java中的「继承」和「组合」这两个东西,本篇文章就主要就这两个话题谈论一下.如果我某些地方写的不对,或者比较幼稚, ...
- HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipe ...
随机推荐
- 如何理解并正确使用MySql索引
原文链接:https://my.oschina.net/feinik/blog/1305784 1.概述 索引是存储引擎用于快速查找记录的一种数据结构,通过合理的使用数据库索引可以大大提高系统的访问性 ...
- c++ 容器元素填充(fill)
#include <iostream> // cout #include <algorithm> // fill #include <vector> // vect ...
- 设置网站URL启动
当新建一个MVC WEB程序 当你打开一个视图按F5运行 这时候并且不能政策运行会出现与个错误 无法找到资源. 这时候站点的默认设置是 把这个个默认设置更改成 红色框框的地方为修改点 你以为这样就完了 ...
- 分析 HTML 代码并提取数据
在前面的内容中,我们已经学习了 HTML.CSS 和 XPath 的基础知识.从真实世界的网页中获取数据,关键在于如何编写合适的 CSS 或者 XPath 选择器.本节介绍一些确定选择器的简单方法.假 ...
- 【Golang】格式化JSON字符串,方便查看
分别介绍golang及Python格式化接口返回JSON数据的方法,及Python json.dumps方法出现NameError: name 'true' is not defined原因解析及解决 ...
- Linux访问windows共享(samba/smbclient/smbfs/cifs)
samba是一个实现不同操作系统之间文件共享和打印机共享的一种SMB协议的免费软件.●安装samba,samba-client和cifs-utils.x86_64此步将自动安装好相关依赖包:samba ...
- shuoj 418 丢史蒂芬妮(素数筛+sg函数)
丢史蒂芬妮 代码: #include<bits/stdc++.h> using namespace std; +; int SG[N][N]; bool S[N]; vector<i ...
- 生物信息Python-从入门到精通?
Python开发的方向太多了,有机器学习,数据挖掘,网络开发,爬虫等等.其实在生信领域,Python还显现不出绝对的优势,生信的大部分软件流程都是用shell或Perl写的,而且已经足够好用了.我选P ...
- 20170624xlVBA生成通讯录文件
Public Sub QqYunContactTransferCsvFile() '应用程序设置 Application.ScreenUpdating = False Application.Disp ...
- Java使用POI读取和写入Excel指南
Java使用POI读取和写入Excel指南 做项目时经常有通过程序读取Excel数据,或是创建新的Excel并写入数据的需求: 网上很多经验教程里使用的POI版本都比较老了,一些API在新版里已经废弃 ...