您的位置:首页 > 其它

多文件目录Makefile的写法

2016-07-13 13:25 169 查看


                                                        多文件目录Makefile写法

1、前言
  linux下程序开发,涉及到多个文件,多个目录,这时候编译文件的任务量比较大,需要写Makefile
2、简单测试
  测试程序在同一个文件中,共有func.h、func.c、main.c三个文件,Makefile写法如下所示:

1 CC = gcc
2 CFLAGS = -g -Wall
3
4 main:main.o func.o
5     $(CC)  main.o func.o -o main
6 main.o:main.c
7     $(CC) $(CFLAGS)  -c main.c -o main.o
8 func.o:func.c
9     $(CC) $(CFLAGS) -c func.c -o func.o
10 clean:
11     rm -rf *.o


执行过程如下图所示:



3、通用模板
  实际当中程序文件比较大,这时候对文件进行分类,分为头文件、源文件、目标文件、可执行文件。也就是说通常将文件按照文件类型放在不同的目录当中,这个时候的Makefile需要统一管理这些文件,将生产的目标文件放在目标目录下,可执行文件放到可执行目录下。测试程序如下图所示:


完整的Makefile如下所示:

1 DIR_INC = ./include
2 DIR_SRC = ./src
3 DIR_OBJ = ./obj
4 DIR_BIN = ./bin
5
6 SRC = $(wildcard ${DIR_SRC}/*.c)
7 OBJ = $(patsubst %.c,${DIR_OBJ}/%.o,$(notdir ${SRC}))
8
9 TARGET = main
10
11 BIN_TARGET = ${DIR_BIN}/${TARGET}
12
13 CC = gcc
14 CFLAGS = -g -Wall -I${DIR_INC}
15
16 ${BIN_TARGET}:${OBJ}
17     $(CC) $(OBJ)  -o $@
18
19 ${DIR_OBJ}/%.o:${DIR_SRC}/%.c
20     $(CC) $(CFLAGS) -c  $< -o $@
21 .PHONY:clean
22 clean:
23     find ${DIR_OBJ} -name *.o -exec rm -rf {}


解释如下:
(1)Makefile中的 符号 $@, $^, $< 的意思:
  $@  表示目标文件
  $^  表示所有的依赖文件
  $<  表示第一个依赖文件
  $?  表示比目标还要新的依赖文件列表
(2)wildcard、notdir、patsubst的意思:
  wildcard : 扩展通配符

  notdir : 去除路径

  patsubst :替换通配符
 例如下图例子所示:



输出结果如下所示:



SRC = $(wildcard *.c)
等于指定编译当前目录下所有.c文件,如果还有子目录,比如子目录为inc,则再增加一个wildcard函数,象这样:
SRC = $(wildcard *.c) $(wildcard inc/*.c)
(3)gcc -I -L -l的区别:

       gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld
       上面这句表示在编译hello.c时-I /home/hello/include表示将/home/hello/include目录作为第一个寻找头文件的目录,
   寻找的顺序是:/home/hello/include-->/usr/include-->/usr/local/include
   -L /home/hello/lib表示将/home/hello/lib目录作为第一个寻找库文件的目录,
   寻找的顺序是:/home/hello/lib-->/lib-->/usr/lib-->/usr/local/lib
       -lworld表示在上面的lib的路径中寻找libworld.so动态库文件(如果gcc编译选项中加入了“-static”表示寻找libworld.a静态库文件)
参考:
http://www.groad.net/bbs/read.php?tid-2920-page-e.html
http://blog.csdn.net/liangkaiming/article/details/6267357
http://blog.csdn.net/zqt520/article/details/7727051 http://blog.csdn.net/haoel/article/details/2886/
最后一行应为
find ${DIR_OBJ} -name *.o -exec rm -rf {} \ ;
少了一个反斜杠和;
注:-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of ';'
is encountered. The string '{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped
(with a '\') or quoted to protect them from expansion by the shell. 
See the EXAMPLES sec-tion for examples of the use of the '-exec' option. The speci-fied command is run once for each matched file. The command is executed in
the starting directory. There are unavoidable security problems surrounding use of the -exec option; you should use the -execdir option instead.

附:我的makefile:
########################################

#makefile

########################################

#编译指定子目录

SUBDIRS := .\\lib\\NC_Com\
  .\\lib\\NC_FileSys\

           .\\lib\\NC_BlkFile\

           .\\lib\\NC_Card\\NC_Card_Lib\

           .\\lib\\NC_UPCash\\NC_UPCash_Lib

define make_subdir

 @ for subdir in $(SUBDIRS) ; do \

 ( cd $$subdir && make $1) \

 done;

endef

#编译主程序

BINARY  := ./bin/bus

OBJ_DIR := ./obj/

CC= gcc

LD= ld

CFLAGS= -std=c99 -Wall -g

LDSCRIPT= -lmycom -lws2_32 -liconv -lmyfile  -lmycard -lmyup -lmycalc -lmyblkfile

LDFLAGS= -Llib 

SRC  = $(wildcard *.c)

DIR  = $(notdir $(SRC))

OBJS = $(patsubst %.c,$(OBJ_DIR)%.o,$(DIR))

#OBJS=  main.o myutils.o  inirw.o  cmdpboc.o cputest.o bustcp.o ansrec.o m1cmd.o m1api.o m1test.o upcash.o myother.o getsys.o

#CFLAGS=-std=c99

#@echo Building lib...

#$(call make_subdir)

.PHONY: clean

all:  prebuild  $(BINARY).exe

prebuild:
@echo
Building lib...
$(call make_subdir)
@echo Building app...

$(BINARY).exe : $(OBJS)
@echo Generating ...
$(CC) -o $(BINARY).exe $(OBJS) $(LDFLAGS) $(LDSCRIPT) 
@echo OK!

$(OBJ_DIR)%.o : %.c
$(CC) -c $(CFLAGS) $< -o  $@

clean:
rm -f $(OBJ_DIR)*.o
@echo Removed!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: