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.ckvm_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