SHELL=/bin/sh
CC=gcc
CXX=g++
MAKE=make
..........
rebuild: clean all
cleanall:
rm -f $(OBJ_DIR)*
rm -f $(RELEASE_DIR)*
rm -f $(DEBUG_DIR)*
test:
$(OUT)
.PHONY: all
建议看56楼最新版本,这里的没有那个好,删掉了
http://bbs.chinaunix.net/viewthread.php?tid=909275&pid=6620665&page=6&extra=#pid6620665
[ 本帖最后由 net_robber 于 2007-3-30 16:58 编辑 ]
net_robber 回复于:2007-03-14 13:28:01
all: $(OUT)
$(OUT): $(OBJ_FILES)
$(CC) $^ -o $@
$(OBJ_DIR)%.o:$(SRC_DIR)%.c
$(CC) $(FLAG_COMPLE) $< -o $@
这几行是关键行,用于目录规则设置
net_robber 回复于:2007-03-14 13:29:22
对比以前精华里面的那个通用Makefile
我这个主要是提供“多目录”解决方案
PS:不断完善中
flw 回复于:2007-03-14 13:39:43
恭喜楼主脱胎换骨!
看来一个人长大只是一瞬间的事~
net_robber 回复于:2007-03-14 13:42:55
谢谢
永远学习,希望自己能够成为高手,呵呵
emacsnw 回复于:2007-03-14 15:09:11
又是一个通用Makefile,支持一下。
net_robber 回复于:2007-03-14 15:27:14
这里 顺带 提一个问题:
我学习Makefile的时候没有拿到第一手的资料
只有网上一个晦涩难解,并且翻译的不很准确的 中文版手册<GNU Make 使用手册>
man make不是我要的
man makefile没有结果
请问各位是从哪里弄的第一手资料???
我当前正在看
http://www.gnu.org/software/make/manual/make.html
mingyanguo 回复于:2007-03-14 15:41:56
info make 呢?
net_robber 回复于:2007-03-14 15:56:32
效果不错,^_^
谢谢
ericz 回复于:2007-03-15 09:15:55
如果某个.c包含的.h文件内容发生变化呢?
net_robber 回复于:2007-03-15 09:17:14
问的好。
晚上修改一下。现在工作,看书,学习!
呵呵
exir 回复于:2007-03-15 12:45:05
$(TARGET): $(OBJ) $(OBJ_O)
$(CC) -I ../include -o $@ $^
-include $(DEPS)
%.d: %.c
$(CC) -I ../include -MM -MD $<
%.o: %.c %.d
$(CC) $(CFLAGS) -I ../include $< -o $@
中国大表哥 回复于:2007-03-15 13:46:02
引用:原帖由 flw 于 2007-3-14 13:39 发表
恭喜楼主脱胎换骨!
看来一个人长大只是一瞬间的事~
。。。。。。
飞灰橙 回复于:2007-03-15 13:50:45
Makefile里如何正确处理带空格的文件名?
net_robber 回复于:2007-03-15 14:33:11
引用:原帖由 exir 于 2007-3-15 12:45 发表
$(TARGET): $(OBJ) $(OBJ_O)
$(CC) -I ../include -o $@ $^
-include $(DEPS)
%.d: %.c
$(CC) -I ../include -MM -MD $<
%.o: %.c %.d
$(CC) $(CFLAGS) -I ../include $< -o $@
十分感谢,已经处理完毕
net_robber 回复于:2007-03-15 14:35:12
最新修改如下:
all: $(OUT)
$(OUT): $(OBJ_FILES)
$(CC) $^ -o $@
$(OBJ_DIR)%.o:$(SRC_DIR)%.c $(OBJ_DIR)%.d
$(CC) $(FLAG_COMPLE) $< -o $@
$(OBJ_DIR)%.d:$(SRC_DIR)%.c
$(CC) $< -MM -o $@
net_robber 回复于:2007-03-15 14:37:39
最新版本上传
Makefile-0.2.0.tar.gz
net_robber 回复于:2007-03-15 14:39:29
引用:原帖由 飞灰橙 于 2007-3-15 13:50 发表
Makefile里如何正确处理带空格的文件名?
这个似乎没有办法处理
代空格的文件,不知道在列出文件名的时候,用Shell列出,是否可行
反正用wildcard 肯定不行
net_robber 回复于:2007-03-15 14:41:05
刚刚测试了一下不管事find还是ls都不能在返回的字符串带上"\"
似乎没有办法了
converse 回复于:2007-03-15 15:15:31
大概看了以下,LZ你的makefile比起whyglinux的可配置性差了一些....很多地方都是写死的,比如编译器,比如文件后缀....
net_robber 回复于:2007-03-15 15:30:15
是的
都是写死的
用的时候需要大量修改。
主要解决了一个问题
源文件和Makefile不在同一目录
soul_of_moon 回复于:2007-03-15 15:37:00
引用:原帖由 net_robber 于 2007-3-15 15:30 发表
是的
都是写死的
用的时候需要大量修改。
主要解决了一个问题
源文件和Makefile不在同一目录
但是源文件都在同一目录下。所以,路过
net_robber 回复于:2007-03-15 15:41:09
其实还解决了一个问题
我得Makefile原来执行起来和Shell没有区别,
不会进行文件更新检查,呵呵
现在会了
然后就是今天学会了Include的头文件依赖检查
soul_of_moon 回复于:2007-03-15 15:46:15
引用:原帖由 net_robber 于 2007-3-15 15:41 发表
其实还解决了一个问题
我得Makefile原来执行起来和Shell没有区别,
不会进行文件更新检查,呵呵
现在会了
然后就是今天学会了Include的头文件依赖检查
这个不是把头文件也加到依赖文件中么?
net_robber 回复于:2007-03-15 15:55:42
这个也是一种方法
特别是我原来那Makefile当Shell写的时候,也是这样。呵呵
wolfkin 回复于:2007-03-15 15:56:35
为什么不用 autotools 呢!
写一点模板,简单几条命令就可以生成所需要的文件了,并且具有很高的可移植性。
只是这个工具很有点难学,我也是好多都还没有搞定,初识门径而已。
shanan 回复于:2007-03-15 16:03:43
不错的东西
net_robber 回复于:2007-03-15 16:05:41
一定要学的,呵呵。
一个一个的来么
学以致玩。
大家玩的高兴。呵呵!
iwolcbao 回复于:2007-03-15 16:55:16
没有用过,在linux都用简单文件编译方式,没有楼主强,没有用到跨目录的,
还是顶一下,支持楼主!
exir 回复于:2007-03-15 22:47:38
auto工具对于交叉编译好像没什么用
还有就是带空格的文件名和路径用""括起了就行了。
曾在win下用win版gcc做arm平台交叉编译,program file这个目录带个空格,真是烦死了。
这么重要的目录用这么挫的一个名字,既带空格又不简洁。
还是*nix好。
net_robber 回复于:2007-03-15 22:49:54
引用:原帖由 exir 于 2007-3-15 22:47 发表
...
还有就是带空格的文件名和路径用""括起了就行了。
...
记下了,呵呵
yanweihao 回复于:2007-03-16 11:40:09
CODE:
[Copy to clipboard]
不要完全否定中国的教育制度!
它在扼杀一部分天才的同时,减少了更多废物的出现。
至少,每一个人都有学到了一些可用的知识。
yanweihao 说粗话被严重警告+禁言。
--by converse
[ 本帖最后由 converse 于 2007-3-22 23:11 编辑 ]
crackpot 回复于:2007-03-16 15:55:20
"多目录 源代码 编译"这个名字似乎和你写的makefile做的不是一件事情吧
在大的项目中源代码肯定是多目录的,通常需要每个目录下写一个makefile,然后在上级目录的makefile中运行下一级目录的make,按照顺序完成每个子目录的编译
这样,只需要一个make,就能完成整个项目的编译,很多开源的项目都是这样的,楼主找个开源的项目代码看看他们的makefile
这是openldap的makefile的一部分,应该能说明点问题:
all-common: FORCE
@echo "Making all in `$(PWD)`"
@for i in $(SUBDIRS) $(ALLDIRS); do \
echo " Entering subdirectory $$i"; \
( cd $$i; $(MAKE) $(MFLAGS) all ); \
if test $$? != 0 ; then exit 1; fi ; \
echo " "; \
done
net_robber 回复于:2007-03-16 16:26:00
Makefile、.h文件、.c文件、.o文件等等,有时候还有很多其他文件,都放在一个目录下,看着不乱么???
分目录管理一下,归归类,就比较舒服了
然后,各种文件不在同一目录下,
编译连接就需要手动指定路径。
我这个是希望使用通配符的方法,方便Makefile编写
这样可以体现Makefile的优势,
不然还不如用SHELL
cookis 回复于:2007-03-19 14:14:50
$(OBJ_DIR)%.o:$(SRC_DIR)%.c $(OBJ_DIR)%.d
$(CC) $(FLAG_COMPLE) $< -o $@
$(OBJ_DIR)%.d:$(SRC_DIR)%.c
$(CC) $< -MM -o $@
上边 %.d这个依赖是不是有点儿多余啊.
$(OBJ_DIR)%.o:$(SRC_DIR)%.c
$(CC) $(FLAG_COMPLE) $< -o $@
这样不就够了吗.
net_robber 回复于:2007-03-19 14:35:30
不可以
那个是检查依赖用的
cookis 回复于:2007-03-19 14:41:32
GCC会自动推导的...
net_robber 回复于:2007-03-19 14:45:02
168那个机器的不会,我测试过了,必须手动的
可能和版本有关吧
我再测试一下
I/0 回复于:2007-03-20 09:33:17
我昨天测试了一下17楼的那个, 不能正确处理头文件依赖
需要加上:
DEPS = $(OBJS:.o=.d) # 这个只用于当前目录
-include $(DEPS)
我机器: FreeBSD 6.2, GNU Make 3.81
[ 本帖最后由 I/0 于 2007-3-20 09:36 编辑 ]
net_robber 回复于:2007-03-20 09:51:13
能不能给出你的测试 过程
详细一点,
(建议使用此Makefile时, make dir 创建需要的目录结构)
我看一下,以便修改Bug
呵呵
I/0 回复于:2007-03-20 17:57:04
我先 gmake dir 生成目录, 然后在 src/ 下建了三文件: a.h a.c main.c
deps:
a.c: a.h
main.c: a.h
以下是测试结果:
$ gmake
gcc src/a.c -MM -o obj/a.d
gcc -c -g src/a.c -o obj/a.o
gcc src/main.c -MM -o obj/main.d
gcc -c -g src/main.c -o obj/main.o
gcc obj/a.o obj/main.o -o debug/out
rm obj/a.d obj/main.d
$ touch src/a.h
$ gmake
gmake: Nothing to be done for `all'.
net_robber 回复于:2007-03-20 18:07:44
引用:原帖由 I/0 于 2007-3-20 17:57 发表
我先 gmake dir 生成目录, 然后在 src/ 下建了三文件: a.h a.c main.c
deps:
a.c: a.h
main.c: a.h
以下是测试结果:
$ gmake
gcc src/a.c -MM -o obj/a.d
gcc -c -g src/a.c -o obj/a.o
gcc src/main ...
哦
是这样的,依赖关系不是靠名字相同检查的
要求.c文件中,有include .h文件,才会出现依赖
也就是说。你要在a.c Includ a.h
I/0 回复于:2007-03-21 08:59:24
引用:原帖由 net_robber 于 2007-3-20 18:07 发表
哦
是这样的,依赖关系不是靠名字相同检查的
要求.c文件中,有include .h文件,才会出现依赖
也就是说。你要在a.c Includ a.h
呵呵, 我是嫌帖那几个文件的源码太长才简单地用 deps: a.c: a.h main.c a.h 描述了一下include关系,
a.c 和 main.c 里面都有 include "a.h"
net_robber 回复于:2007-03-21 11:32:46
确实有问题
正在研究。
请稍后
wangyl1982 回复于:2007-03-21 13:39:23
不错,楼主能不能花点时间解释一下每行,让我只懂一点的人,用你这个,也知其所以然.
net_robber 回复于:2007-03-21 15:15:30
先不解释
还有点问题
net_robber 回复于:2007-03-22 17:51:22
已经找到不能正确检查头文件依赖的原因了
因为gcc自动生成的依赖规则中,目标文件并没有加入路径。
因此,他没有按照预期的规则进行检查、编译
net_robber 回复于:2007-03-22 18:09:16
# Readme:
# use: make config
# use: make dir
# use: make
# use: make clean
# use: make rebuild
# use: make cleanall
# use: make test
# use: make
# firs of all, use "make config" or "make dir" to
# build a source files struct. and then,
# put your source files into the DIR src
# link libs to the DIR lib
SHELL=/bin/sh
CC=gcc
CXX=g++
MAKE=make
MAKE_DIR=$(PWD)
SRC_DIR=$(MAKE_DIR)/src/
OBJ_DIR=$(MAKE_DIR)/obj/
LIB_DIR=$(MAKE_DIR)/lib/
DEBUG_DIR=$(MAKE_DIR)/debug/
RELEASE_DIR=$(MAKE_DIR)/release/
OUTPUT_DIR=
LIB=-L$(MAKE_DIR)/lib/
OUTPUT_FILE=out
OUT=
vpath %.c $(SRC_DIR)
#vpath %.o $(OBJ_DIR)
vpath %.d $(OBJ_DIR)
DEBUG=1
SRC_FILES:=$(wildcard $(SRC_DIR)*.c)
SRC_FILES:=$(notdir $(SRC_FILES))
OBJ_FILES:=$(patsubst %.c,%.o,$(SRC_FILES) )
DEP_FILES:=$(patsubst %.c,%.d,$(SRC_FILES) )
#SRC_FILES:=$(addprefix $(SRC_DIR),$(SRC_FILES))
#OBJ_FILES:=$(addprefix $(OBJ_DIR),$(OBJ_FILES))
DEP_FILES:=$(addprefix $(OBJ_DIR),$(DEP_FILES))
FLAG_DEBUG=-g
FLAG_COMPLE=-c
FLAG_LINK=
ifeq ($(DEBUG),1)
OUTPUT_DIR:=$(DEBUG_DIR)
FLAG_COMPLE:=$(FLAG_COMPLE) $(FLAG_DEBUG)
FLAG_LINK:=
else
OUTPUT_DIR:=$(RELEASE_DIR)
FLAG_COMPLE:=$(FLAG_COMPLE)
FLAG_LINK:=
endif
OUT=$(OUTPUT_DIR)$(OUTPUT_FILE)
$(OUT): $(OBJ_FILES)
@echo 1
@$(CC) $^ -o $@
%.o:%.c %.d
@echo 2.1
@$(CC) $(FLAG_COMPLE) $< -o $@
$(OBJ_DIR)%.d:%.c
@echo 3
@$(CC) $< -MM -MD -o $@
# if the system-libs will always update, please ues this instead for
# $(CC) $< -M -o $@
-include $(DEP_FILES)
config: dir
dir:
mkdir -p $(SRC_DIR)
mkdir -p $(OBJ_DIR)
mkdir -p $(LIB_DIR)
mkdir -p $(DEBUG_DIR)
mkdir -p $(RELEASE_DIR)
clean:
rm -f $(OBJ_DIR)* *.d *.o
rm -f $(OUT)
clear
rebuild: clean all
cleanall:
rm -f $(OBJ_DIR)*
rm -f $(RELEASE_DIR)*
rm -f $(DEBUG_DIR)*
test:
$(OUT)
.PHONY: all config rebuild
#.SUFFIXES:
net_robber 回复于:2007-03-22 18:10:31
48楼为最新更新
能够检查头文件的依赖关系了。
但是,没能将 .o 文件分离到单独的目录
原因在47楼
net_robber 回复于:2007-03-22 18:13:00
如果大家还有什么良策妙极,欢迎讨论
I/0 回复于:2007-03-22 21:21:04
呵呵, 我也是前几天刚开始学写 Makefile, 不过现在正忙着在win下搞毕设, 等有空再来慢慢研究.
net_robber 回复于:2007-03-27 12:06:17
最新更新
完全解决多目录编译
实现源文件与目标文件的分目录存储
解决依赖关系检查问题
Makefile-0.4.0.tar.gz
net_robber 回复于:2007-03-27 12:06:50
这次是比较完美的版本了
呵呵,可以暂时休息一下了
net_robber 回复于:2007-03-27 13:09:44
部分主要内容
vpath %.c $(SRC_DIR)
vpath %.o $(OBJ_DIR)
vpath %.d $(OBJ_DIR)
$(OUT): $(OBJ_FILES)
@$(CC) $(addprefix $(OBJ_DIR),$(notdir $^)) -o $@
%.o:%.c %.d
@$(CC) $(FLAG_COMPLE) $< $ -o $(OBJ_DIR)$@
$(OBJ_DIR)%.d:%.c
@$(CC) $< -MM -MD -o $@
-include $(addprefix $(OBJ_DIR),$(DEP_FILES))
说明:
vpath指定默认搜索路径
然后使用规则进行编译
include导入依赖关系
net_robber 回复于:2007-03-30 16:54:26
更新说明:
最新版本增加功能如下:
增加执行每个子目录下Makefile的 clean 目标
相关代码如下:
GlobalClean:
@find . -type f -name "Makefile" |sed -n '2,$$p'|sed s/Makefile/\ \`pwd\`/g|awk ' {ECHO="echo"};{CD="cd "};{MAKE="&& make clean&&"};{print ECHO,CD,$$1,MAKE,CD,$$2 } ' |sh
net_robber 回复于:2007-03-30 16:57:04
下载连接见下
Makefile-0.4.5.tar.gz
j1j1h1 回复于:2007-04-24 10:37:47
我下载了makefile
感觉修改了.h文件后,.c文件还是不自动编译啊
.o 依赖于.c和.d
.d 依赖于.c
如果在.h中加几个空格. .d是不会发生变化的,.c也不会发生变化
那么.o 怎么会重新编译呢?
:em14:
zhufu 回复于:2007-05-28 22:12:52
顶一个
net_robber 回复于:2007-05-29 09:09:47
引用:原帖由 j1j1h1 于 2007-4-24 10:37 发表
我下载了makefile
感觉修改了.h文件后,.c文件还是不自动编译啊
.o 依赖于.c和.d
.d 依赖于.c
如果在.h中加几个空格. .d是不会发生变化的,.c也不会发生变化
那么.o 怎么会重新编译呢?
:em14:
这一行
-include $(addprefix $(OBJ_DIR),$(DEP_FILES))
导入的依赖关系中
会有
类似
.o:.h
这样的代码。
这样保证了.h文件改编后,以其为依赖的.o会被重新编译。
编译命令由
.o:.c
定义
如果方便,请贴出你的编译过程和你使用的Makefile
|