makefile实现多目录文件编译

时间:2021-09-15 13:46:33

现要在Ubuntu上编译一个大型工程文件,假设各文件目录及关系如下:

/home/vote:

comlib(文件夹)

vote.c(主函数在此.c文件中实现)

makefile


/home/vote/comlib:

include(文件夹)

lib(文件夹)

libsrc(文件夹)


/home/vote/comlib/include:

comlib.h(头文件)


/home/vote/comlib/lib:

暂无()


/home/vote/comlib/libsrc:

file.c、tcp.c、debug.c(这三个.c文件实现main函数调用的函数,函数定义在comlib.h中完成)

makefile


(一)现要编译此工程则需要实现两个makefile,一个是/home/vote/comlib/libsrc下的makefile,用来编译子目录下各文件,其写法如下所示:

.SUFFIXES:.c
HOMEDIR=/home/vote
COMDIR=$(HOMEDIR)/comlib
INCDIR=-I$(COMDIR)/include


CC=gcc
CFLAG=-O 
EDF=
help:
        @echo Please input filename that will be made
        @echo 'syntax: make <help|all|"filename">'
all:file tcp debug
.c:
        if [ -f $(COMDIR)/lib/libcom.a ]; then ar -x $(COMDIR)/lib/libcom.a; fi  
        $(CC) -c $< $(CFLAG) $(INCDIR)
        ar -rv libcom.a *.o 
        rm *.o
        mv libcom.a $(COMDIR)/lib


各变量及命令的含义:

.SUFFIXES 指定合法的源文件扩展名,此处是.c文件,即makefile只编译.c文件。

HOMEDIR为宏,指定当前项目的主目录,其余两个性质相同。

CFLAG指定编译选项。

if [ -f $(COMDIR)/lib/libcom.a ]; then ar -x $(COMDIR)/lib/libcom.a; fi         此句是if函数的一种用法,此处含义应该是如果此目录下有libcom.a库文件则将此文件解压缩成.o文件释放到此目录下(经过笔者亲自测试,若此目录下没有libcom.a文件,此命令就会创建一个libcom.a库,但ar -x命令貌似没有创建库的功能,这点最终没能想通,有同学知道其原理的话欢迎指点)。

$<变量为第一个依赖文件的名称。

ar -rv libcom.a *.o将.o文件加入到libcom.a中。



编译方法:在makefile目录下输入make all即可自动完成所有子文件编译。    

(二)第二个需要编译的文件是/home/vote目录下的vote.c文件,其makefile如下所示:

.SUFFIXE:.c
HOMEDIR=/xilinx/SamShare/APUE/vote
COMDIR=$(HOMEDIR)/comlib
INCDIRS=-I$(COMDIR)/include
LIBDIRS=-L$(COMDIR)/lib
 
LIB= -lcom 
CC=gcc
CFLAGS=-O 
 
EDF=
  
.c:
        $(CC) -o $@ $< $(CFLAGS) $(INCDIRS) $(LIBDIRS) $(LIB)
   #$@意为完整的目标名称。
~                                                                

其各变量及命令与第一个相同,这里不多介绍,需要注意的是此处要链接.../include目录下的comlib.h头文件,以及.../lib下由第一个makefile生成的libcom.a库文件。


编译方法:在makefile目录下输入make vote即可。