绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
玩转Makefile | 企业项目Makefile实例
2019-02-20 20:42:40
我是良许,世界500强外企 Linux 工程师,专业生产 Linux 干货,欢迎关注我的知乎「良许Linux」,欢迎点赞,收藏!

1. 前言

本教程展示了一个比较完整的企业项目级别的Makefile文件,包括了:版本号、动态库、宏定义等内容。

2. 程序展示

本例程的程序目录结构在企业项目中经常见到,即:所有.c文件全部放在一个src目录中,所有.h文件放一个.h目录中,生成的目标独立放在一个output目录中(动态生成)。

源代码可以从在公众号里回复mk4获取。

目录结构如下:

源程序为:

//fun1.h  
void fun1();  


//fun1.c  
void fun1()  
{  
    printf("this is fun1\n");  
}  


//fun2.h  
void fun2();  


//fun2.c  
void fun2()  
{  
    printf("this is fun2\n");  
}  


//dylib.h  
void dynamic_lib_call();  


//main.c  
int main()  
{  
    printf("hello world\n");  
    fun1();  
    fun2();  

#ifdef _MACRO  
    printf("macro test\n");  
#endif  
    dynamic_lib_call();  
}

Makefile文件为:

VERSION = 1.0.0     #程序版本号  

SOURCE = $(wildcard ./src/*.c)  #获取所有的.c文件  
OBJ = $(patsubst %.c, %.o, $(SOURCE))   #将.c文件转为.o文件  
INCLUDES = -I./h    #头文件路径  

LIBS = -ldylib      #库文件名字  
LIB_PATH = -L./lib  #库文件地址  

DEBUG = -D_MACRO    #宏定义  
CFLAGS = -Wall -c   #编译标志位  

TARGET = app  
CC = gcc  

$(TARGET): $(OBJ)     
    @mkdir -p output/   #创建一个目录,用于存放已编译的目标  
    $(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET).$(VERSION)  

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

.PHONY: clean  
clean:  
    rm -rf $(OBJ) output/

库文件说明:

库文件名称为libdylib.so,里面只有一个函数:dynamic_lib_call(),它就输出一句话:this is a function in dynamic library。

3. Makefile所包含内容

3.1 程序版本

软件开发过程中,会产生多个版本程序,通常会在程序末尾加上版本号后缀。

VERSION = 1.0.0 #定义  
$(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET).$(VERSION) #使用

3.2 头文件

由于.c文件与.h文件分开在不同目录下,所以应指定头文件路径。

INCLUDES = -I./h

3.3 宏定义

在代码调试的过程中,我们通常会加个宏定义来控制此段代码是否被编译,比如:

#ifdef _MACRO  
    printf("macro test\n");  
#endif

具体的宏我们可不定义在代码里,可在Makefile里指定,比如:

DEBUG = -D_MACRO    #定义  
$(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $< -o $@    #使用

3.4 编译选项

当编译选项较多时,我们通常会把它单独拿出来,比如:

CFLAGS = -Wall -c       #定义  
$(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $< -o $@    #使用

3.5 库

代码里如果要使用到库,我们可以将库名字和路径分别拿出来,比如:

LIBS = -ldylib          #库文件名字  
LIB_PATH = -L./lib      #库文件地址  
$(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET).$(VERSION) #使用

3.6 output目录

如果不想把生成的程序与源文件混在一起,可将生成的程序单独放在一个output目录,比如:

$(TARGET): $(OBJ)  
        @mkdir -p output/       #创建一个目录,用于存放已编译的目标  
        $(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET).$(VERSION)

4. 编译执行结果


码字不易,如果您觉得有帮助,麻烦点个赞再走呗~

-----------------

微信搜索公众号【良许Linux】,后台回复关键字:

  1. 回复【1024】:免费获取不断更新的海量技术资源;
  2. 回复【CSDN】:免费进入CSDN资源下载群;
  3. 回复【进群】:免费进入高手如云技术交流群。

干货分享 · 资源共享 · 认知提高 · 英语学习

分享好友

分享这个小栈给你的朋友们,一起进步吧。

Linux技术精选专区
创建时间:2020-07-08 10:30:23
Linux,全称GNU/Linux,是一套免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年次释出,它主要受到Minix和Unix思想的启发,是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的Unix工具软件、应用程序和网络协议。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • dapan
    专家
戳我,来吐槽~