Makefile框架

1 makefile框架:

include ./other/Makefile   #包含其它makefile

CC=g++  
    
CFLAGS := -Wall -g $(INC_FLAGS) -D$(HIARCH) -DHICHIP=$(HICHIP) -DSENSOR_TYPE=$(SENSOR_TYPE) \ 
          -D$(HIDBG) -D$(HI_FPGA) -D$(ISP_VERSION)  
  
LIBS = $(REL_LIB)/lib_hiae.a
LIBS += $(REL_LIB)/lib_hiawb.a
LIBS += $(REL_LIB)/lib_hiaf.a

INCLUDES=-Iinclude -Iinclude/ffmpeg 
INCLUDES += -I/usr/local/include/opencv  

SRC  := $(wildcard *.c) 
OBJ  := $(SRC:%.c=%.o)
TARGET := $(OBJ:%.o=%)

.PHONY : clean all       #伪命令

all: $(TARGET)
$(TARGET):%:%.o 
    $(CC) $(CFLAGS) -lpthread -o $@ $^ $(LIBS)  $(INCLUDES)  
  
clean :  
	  @rm -f $(TARGET)
	  @rm -f $(OBJ)
	  rm -f $(TARGET)
	  rm -f $(OBJ)
	  -rm -f $(TARGET)
	  -rm -f $(OBJ)	

2 动态、静态链接库

//hello.c

#include<stdio.h>  
void hello()  
{  
        printf("hello world/n");  
} 


//test.c
#include<stdio.h>  
int main()  
{  
        printf("call hello()");  
        hello();  
}  

动态链接库:

gcc -shared hello.c -o libhello.so  //-shared 编译为动态库(后缀一般为.so)

gcc test.c -lhello -L. -o test      //-lhello 调用动态链接库 libhello.so,且将当前路径.加入链接文件的搜索路径中

执行test可执行文件时,会找不到libhello.so;解决方法:

     (方法一)要把该连接库的路径加入环境变量LD_LIBRARY_PATH中;

     (方法二)或者直接把该库拷入/lib,/usr/lib/等位置

静态链接库:

1, gcc -c hello.c   //生成hello.o文件

2, ar -r libhello.a hello.o   //把目标文件归档    

程序 ar 配合参数 -r 创建一个新库 libhello.a 并将命令行中列出的对象文件插入。采用这种方法,如果库不存在的话,参数 -r 将创建一个新的库,而如果库存在的话,将用新的模块替换原来的模块。

3. 在程序中链接静态库

           gcc test.c -lhello -L. -static -o hello.static

3 makefile 参数讲解:


-Idir:在头文件的搜索路径列表中添加dir目录. (是 i)
-Dmacro:定义宏macro,宏的内容定义为字符串`1'.
-Dmacro=defn:定义宏macro的内容为defn.命令行上所有的`-D'选项在`-U'选项之前处理
-llibrary   -lpthread:连接名为library的库文件.(是L)连接器在标准搜索目录中寻找这个库文件,
          库文件的真正名字是`liblibrary.a'.连接器会当做文件名得到准确说明一样引用这个文件 ;
$@ 代表目标 
$^ 代表所有的依赖对象
$< 代表第一个依赖对
Tab键之后为shell命令:
Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不用前缀.
3种格式的shell命令区别如下:
不用前缀 :: 输出执行的命令以及命令执行的结果, 出错的话停止执行
前缀 @   :: 只输出命令执行的结果, 出错的话停止执行
前缀 -   :: 命令执行有错的话, 忽略错误, 继续执行
wildcard命令:
例子:SRC  := $(wildcard *.c) 
在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“wildcard”,它的用法是:$(wildcard PATTERN...) 。在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表。


= 和 :=   的区别在于, := 只能使用前面定义好的变量, = 可以使用后面定义的变量
+=         变量追加值

查看C文件的依赖关系:
$ gcc -MM kvm_main.c 
  kvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h   <-- 这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系


make 命令时执行了谁:

  GNU make在当前目录下依次搜索下面3个文件 "GNUmakefile", "makefile", "Makefile",  

  也可make时指定要运行的makefile文件;$ make -f MyMake target2

  

makefile 隐含规则:

编译C时,<n>.o 的目标会自动推导为 <n>.c

# Makefile 中
main : main.o
    gcc -o main main.o

#会自动变为:
main : main.o
    gcc -o main main.o

main.o: main.c    <-- main.o 这个目标是隐含生成的
    gcc -c main.c

makefile 自动变量:

$@ 目标集合

$% 当目标是函数库文件时, 表示其中的目标文件名

$< 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标

$? 比目标新的依赖目标的集合

$^ 所有依赖目标的集合, 会去除重复的依赖目标

$+ 所有依赖目标的集合, 不会去除重复的依赖目标

$* 这个是GNU make特有的, 其它的make不一定支持

  

  

用export传递参数:

# Makefile 内容
export VALUE1 := export.c    <-- 用了 export, 此变量能够传递到 ./other/Makefile 中
VALUE2 := no-export.c        <-- 此变量不能传递到 ./other/Makefile 中

all:
    @echo "主 Makefile begin"
    @cd ./other && make
    @echo "主 Makefile end"

# ./other/Makefile 内容
other-all:
    @echo "other makefile begin"
    @echo "VALUE1: " $(VALUE1)
    @echo "VALUE2: " $(VALUE2)
    @echo "other makefile end"

 

makefile判断语句: 

#ifneq、ifeq;
ifeq ("aa", "bb")
    @echo "equal"
else
    @echo "not equal"
endif
# ifndef和ifdef
ifdef SRCS
    @echo $(SRCS)
else
    @echo "no SRCS"
endif












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章