多文件目录Makefile的写法

简介: 多文件目录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静态库文件)


参考:


曲径通幽论坛,Linux,编程,技术交流社区 - Standing on the shoulders of giants


Makefile中的wildcard用法_liangkaiming的专栏-CSDN博客_makefile wildcard


gcc -I -L -l区别_zqt520的专栏-CSDN博客


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!
相关文章
|
7月前
好用的 自定义Makefile文件
好用的 自定义Makefile文件
38 0
makefile实现创建目录和复制.ko文件
makefile实现创建目录和复制.ko文件
372 0
|
Shell Linux C语言
Makefile文件 | 编写指南
Makefile文件 | 编写指南
335 0
|
Linux C++
利用makefile文件编译c++源文件
makefile文件编译c++ 生成一个so库文件
6325 0