目录
一、一个makefile模板
该模板来自于如下仓库:
#*****************************************************
# 程序名称:make.inc
# 功能描述:编译脚本的头文件
# 作 者:sunkxs
# 创建日期:2022年11月13日
# 版 本:v1.0
# 修改记录:
# <版本> <修改人> <修改日期> <修改内容>
#*****************************************************
#定义应用包含文件路径
INCDIR = $(FTPTOOLHM)/inc
LIBDIR = $(FTPTOOLHM)/lib
#定义系统命令
CC = cc -std=c99
AR = ar
CP = cp
LD = ld
RM = rm -f
MV = mv
MK = mkdir
RANLIB = ranlib
LINT = lint
#定义应用包含标志
APPINC = -I$(INCDIR)
#定义c文件编译标志
CFLAGS = -Wall -c -fPIC -D__DBG__
#定义程序编译标志
ECFLAGS = $(CFLAGS)
#定义检查标志
LINTFLAGS =
#定义共享库标志
SOFLAGS = -shared
SYSLFLAGS = -L$(FTPTOOLHM)/lib \
-ldevlog
USERLFLAGS += -Wl,-rpath=$(FTPTOOLHM)/lib
LFLAGS=$(SYSLFLAGS) $(USERLFLAGS)
CFLAGS = -Wall -c -fPIC -D__DBG__
该行中的fPIC可以参考:
linux编译动态库之fPIC - 知乎 (zhihu.com)
在该仓库的README.md文件中有说明添加环境变量。所以:
INCDIR = $(FTPTOOLHM)/inc
仅仅表示INCDIR=/home/.../ftp-tool/inc 路径。
看完这个makefile头,我的直觉就是这个东西就类似于c语言的宏,理解到这里,其实很多的东西都很好的理解
# Makefile
include $(FTPTOOLHM)/inc/make.inc
# 定义库名称 ,比如 libstring
LIBNAME = libstring
SRCS = ${wildcard *.c}
OBJS = ${SRCS:.c=.o}
#define library
OBJLIB = $(LIBNAME).so
OBJSTA = $(LIBNAME).a
all : $(OBJLIB) $(OBJSTA)
$(OBJLIB) : $(OBJS)
$(CC) $(SOFLAGS) $(OBJS) -o $@
$(MV) $(OBJLIB) $(LIBDIR)
$(OBJSTA) : $(OBJS)
#ar $^ -rv $@
$(AR) -rv $@ $(OBJS)
#mv $@ $(LIBDIR)
$(MV) $(OBJSTA) $(LIBDIR)
.c.o:
$(CC) $(ECFLAGS) $*.c $(APPINC)
.PHONY:clean
clean:
$(RM) *.o $(OBJLIB) $(OBJSTA)
1. ${wildcard *.c}:其中wildcard关键字 获取目录下的所有 .c文件
2. ${SRCS:.c=.o}:变量名替换函数,将该目录下的所有 .c文件替换为 .o文件
3. .c.o 其实就是%o:%c,这个是一个旧格式,在这里是为了生成 .o文件
4. .PHONY:clean :.PHONY的作用 - Easonay_Y - 博客园 (cnblogs.com)
5. 如何编译动态库、静态库linux c动态库与静态库的实现_NewDiscoverer的博客-CSDN博客
6. ar -rv :静态库用ar工具来制作。ar是一个归档工具,用于建立、修改、提取归档文(archive)。一个归档文件可以包含多个目标文件,也被称为静态库。在Linux下,静态库的扩展名一般为.a,在上面的连接中也有其他的制作静态库的方法。
7. 动态库:gcc -shared.
8. -Wl,-rpath与动态库链接相关。
9. SYSLFLAGS中的 -l(小写的L) 给gcc 指定具体的库 -L 给gcc添加额外的搜索库的路径
这个makefile主要是将.c编译生成一个动态库和一个静态库.
二、多makefile文件联合编译
在我的这篇博客中有我项目的结构(第三章),同时我也在这篇博客中讲了静态库和动态库的使用, linux c动态库与静态库的实现_linux动态库转换为静态库_NewDiscoverer的博客-CSDN博客
项目代码在myftp: 实现ftp工具,具备一些简单的功能 (gitee.com) ,目前程序可以编译成功,但是还是错误的,之所以贴个链接,目的是为了让有需要的人看的更清楚。目前它使用的链接静态库,如果你需要链接共享库,你需要学习我前面说的这个博客。
下面的makefile为client文件夹中的makefile,它负责调用其他makefile编译,同时他也编译当前文件夹的文件。
SUBDIR = $(wildcard ../command/*/)
SRCS = $(wildcard ../libsrc/*.c)
OBJS = $(SRCS:.c=.o)
SRCS2 = $(wildcard *.c)
OBJS2 = $(SRCS2:.c=.o)
CFLAGS = -I../include -L../lib -I../libsrc
LD = -ldownload -lmkdirr -lrmc -lrmd -lsls -ltouchc -lupdown
# all:
# #echo $(SUBDIR)
define make_subdir
@for i in $(SUBDIR); do \
( cd $$i && make $1 ) \
done;
endef
CLIENT = client
ALL:$(CLIENT)
$(CLIENT):$(OBJS) $(OBJS2)
$(call make_subdir)
gcc $(CFLAGS) $^ -o $@ $(LD)
clean:
$(call make_subdir , clean)
rm *.o
另一个复杂的例子makefile学习笔记二--多makefile联合编译-CSDN博客
这个例子里面有多个makefile,而且内容比较多,值得看一下。
参考:
gcc -I -L -l 来自于:GCC中 -I、-L、-l 选项的作用_YHQ-Fish的博客
-Wl -rpath来自于: -Wl,-rpath=_phymat.nico的博客-CSDN博客_-wl,-rpat