Makefile example
example
实现内容
- 所有文件直接编译、链接形成可执行文件;
- 将
add.c
和minus.c
编译成静态文件库,然后链接形成可执行文件; - 将
add.c
和minus.c
编译成动态文件库,然后链接形成可执行文件;
文件夹结构
.
├── inc
│ ├── add.h
│ └── minus.h
├── Makefile
└── src
├── add.c
├── main.c
└── minus.c
add.h
#ifndef ADD_H
#define ADD_H
int add(int a, int b);
#endif
minus.h
#ifndef MINUX_H
#define MINUX_H
int minus(int a, int b);
#endif
add.c
# include"add.h"
int add(int a, int b)
{
return a + b;
}
minus.c
# include"minus.h"
int minus(int a, int b)
{
return a - b;
}
main.c
#include<stdio.h>
#include "add.h"
#include "minus.h"
int main()
{
printf("Hello world\n");
printf("add = %d\n", add(7, 5));
printf("minus= %d\n", minus(7, 5));
return 0;
}
将add和minus编译成静态库,然后链接成可执行文件
直接编译链接
# 源文件
c_srcs := $(shell find src -name "*.c")
o_objs := $(patsubst src%.c, objs%.o, $(c_srcs))
# 头文件
include_path := ./inc
# 编译选项
I_flag := $(include_path:%=-I%)
compile_flag := -g -O3 $(I_flag)
# 编译
objs/%.o: src/%.c
@mkdir -p $(dir $@)
gcc -c $^ -o $@ $(compile_flag)
# 链接
workspace/exec: $(o_objs)
@mkdir -p $(dir $@)
gcc $^ -o $@ $(linking_flag)
run: workspace/exec
@./$<
debug:
@echo $(c_srcs)
@echo $(o_objs)
clear:
rm -rf objs workspace
.PHONY: clear debug
执行
make debug
:查看变量是否正确
src/minus.c src/add.c src/main.c
objs/minus.o objs/add.o objs/main.
make clear
:清除编译文件make run
: 编译+运行
gcc -c src/minus.c -o objs/minus.o -g -O3 -I./inc
gcc -c src/add.c -o objs/add.o -g -O3 -I./inc
gcc -c src/main.c -o objs/main.o -g -O3 -I./inc
gcc objs/minus.o objs/add.o objs/main.o -o workspace/exec
Hello world
add = 12
minus= 2
编译、链接静态库
# 库源文件
lib_srcs := $(filter-out src/main.c, $(shell find src -name "*.c"))
lib_objs := $(patsubst src%.c, objs%.o, $(lib_srcs))
# 头文件
include_path := ./inc
# 编译选项
I_flag := $(include_path:%=-I%)
compile_flag := -g -O3 $(I_flag)
# 链接选项
library_path := ./lib
linking_lib := XXX
l_flag := $(linking_lib:%=-l%)
L_flag := $(library_path:%=-L%)
linking_flag := $(l_flag) $(L_flag)
# 加上编译选项
objs/%.o: src/%.c
@mkdir -p $(dir $@)
gcc -c $^ -o $@ $(compile_flag)
# 编译静态库
lib/libXXX.a: $(lib_objs)
@mkdir -p $(dir $@)
ar -r $@ $^
static_lib: lib/libXXX.a
# 链接静态库
objs/main.o: src/main.c
@mkdir -p $(dir $@)
gcc -c $< -o $@ $(compile_flag)
# 加上链接选项
workspace/exec: objs/main.o
@mkdir -p $(dir $@)
gcc $^ -o $@ $(linking_flag)
run: workspace/exec
@./$<
debug:
@echo $(lib_srcs)
@echo $(compile_flag)
clear:
rm -rf objs workspace lib
.PHONY: clear debug run
编译、链接动态库
# 库源文件
lib_srcs := $(filter-out src/main.c, $(shell find src -name "*.c"))
lib_objs := $(patsubst src%.c, objs%.o, $(lib_srcs))
# 头文件
include_path := ./inc
# 编译选项
I_flag := $(include_path:%=-I%)
compile_flag := -g -O3 -fpic $(I_flag)
# 链接选项
library_path := ./lib
linking_lib := XXX
l_flag := $(linking_lib:%=-l%)
L_flag := $(library_path:%=-L%)
# 加上链接选项-Wl,-rpath=[库路径]
linking_flag := $(l_flag) $(L_flag) -Wl,-rpath=$(library_path)
# 加上编译选项
objs/%.o: src/%.c
@mkdir -p $(dir $@)
gcc -c $^ -o $@ $(compile_flag)
# 编译动态库:gcc -shared
lib/libXXX.so: $(lib_objs)
@mkdir -p $(dir $@)
gcc -shared $^ -o $@
share_lib: lib/libXXX.so
# 链接动态库
objs/main.o: src/main.c
@mkdir -p $(dir $@)
gcc -c $< -o $@ $(compile_flag)
# 加上链接选项
workspace/exec: objs/main.o
@mkdir -p $(dir $@)
gcc $^ -o $@ $(linking_flag)
run: workspace/exec
@./$<
debug:
@echo $(lib_srcs)
@echo $(r_flag)
clear:
rm -rf objs workspace lib
.PHONY: clear debug run