makefile是liunx 平台下c、c++开发必不可的工具,掌握一些makefile的技巧对于项目编译构建有很大的帮助,本篇文章主要记录一下makefile中进行宏定义并传递给源代码的使用技巧,主要传递了一个code_version变量,变量是通过git命令获取commit id,通过宏定义传递给源码,在源码中可以获取commit id,可以作为code的版本信息,这对于频繁release的项目很重要,可以确认一些so的版本是否匹配。
1 工程目录结构
建立的demo工程目录结构如下所示:
├── include
│ └── common.h
├── main_dir
│ ├── main.c
│ └── makefile
├── makefile
├── obj
│ ├── function.o
│ └── main.o
├── readme.txt
└── sub_dir
├── function.c
└── makefile
2 顶层目录makefile解读
顶层目录makefile:
CC = gcc
CFLAGS = -g -Wall -O
export TARGET = demo
export OBJ = function.o main.o
export BUILD_PATH = $(PWD)
export SUBDIR = main_dir sub_dir
export OBJDIR = $(BUILD_PATH)
export code_version = $(shell (git rev-parse --short HEAD))
export code_branch = $(shell (git branch))
export code_date= $(shell (git log -1 --format=%cd ))
$(info $(code_version))
$(info $(code_branch))
$(info $(code_date))
all:sub_target $(TARGET)
$(TARGET):$(OBJ)
$(CC) $^ -o $(OBJDIR)/$@
@echo "-------build target success-------"
sub_target:
@echo "-------start build sub dir-------"
make -C main_dir
make -C sub_dir
@echo "-------build sub dir end-------"
clean:
rm -rf $(OBJDIR)/*.o $(TARGET)
顶层makefile目标是编译demo可以执行程序,编译demo需要依赖main_dir和sub_dir编译出的function.o 和main.o,并且编译function.o 和main.o时将其存放至obj文件夹,这样方便项目管理。顶层目录中还通过shell 命令定义了code_version变量,这样项目中其他makefile 就可以使用该变量了,这也是makefile之间传递变量的一种方式。
2 main_dir目录源码解读
main_dir 目录有一个main.c 和一个makefile文件,main.c 中内容入下:
#include <stdio.h>
#include "../include/common.h"
int main()
{
printf("code version: %s\n", CODE_VERSION);
printf("main IN\n");
int sum = add(5, 6);
printf("sum = %d \n",sum);
printf("main OUT\n");
return 0;
}
里面主要调用了一个add函数,add 函数的声明在include/common.h,实现在sub_dir/function.c,common.h中内容很简单,只做了add函数声明:
int add (int a, int b);
main函数中还打印了CODE_VERSION这个宏,这个宏在common.h和main.c中都没有定义,而是在编译的时候通过makefile定义的,main_dir 中makefile内容入下:
CFLAGS += -DCODE_VERSION=\"$(code_version)\"
$(OBJDIR)/main.o:main.c
$(CC) $(CFLAGS) -c $^ -o $@
其中:
CFLAGS += -DCODE_VERSION=\"$(code_version)\"
就是定义了CODE_VERSION这个宏,并且宏的内容是顶层makefile中传递的变量,此外,makefile中定义字符串宏时需要使用转义字符。
3 sub_dir目录源码解读
sub_dir 目录包含了一个function.c文件和一个makefile,function.c中就是add函数实现:
#include <stdio.h>
#include "../include/common.h"
int add (int a, int b)
{
return a+b;
}
sub_dir 中makefile内容:
$(OBJDIR)/function.o:function.c
$(CC) $(CFLAGS) -c $^ -o $@
4 效果验证
在顶层目录执行make命令进行编译:
make
编译结果如下: 运行程序:
./demo
结果如下: 可以看到CODE_VERSION有被正确印出来。 实验代码git 地址:https://github.com/zhenghaiyang123/makefile_demo.git
|