makefile编写练习
OVERVIEW
- makefile编写练习
- 文件结构
- 直接编译整个项目并运行
- 将项目制作成为静态库
- 将项目制作成为动态库
编写makefile文件来编译带头文件的程序,
文件结构
初始项目文件结构,如下所示:
#ifndef ADD_HPP
#define ADD_HPP
int m_add(int a, int b);
#endif //ADD_HPP
#ifndef MINUS_HPP
#define MINUS_HPP
int m_minus(int a, int b);
#endif //MINUS_HPP
#include "add.hpp"
int m_add(int a, int b)
{
return a + b;
}
#include "minus.hpp"
int m_minus(int a, int b)
{
return a - b;
}
#include "add.hpp"
#include "minus.hpp"
#include <iostream>
using namespace std;
int main() {
int a = 10;
int b = 5;
int add_d = m_add(a, b);
int minus_d = m_minus(a, b);
cout << "a + b = " << add_d << endl;
cout << "a - b = " << minus_d << endl;
return 0;
}
直接编译整个项目并运行
文件结构如下:
- objs目录为中间产生的目标文件,
- run目录为链接静态库后生成的可执行文件存放路径,
# makefile文件
cpp_srcs:=$(shell find src -name *.cpp)
cpp_objs:=$(patsubst src/%.cpp, objs/%.o, $(cpp_srcs))
include_paths:=/home/luochenhao/3.tool_tech/libTest/headfile_test/include
I_flags:=$(include_paths:%=-I %)
compile_options:= -g -O3 -w $(I_flags)
# 编译
objs/%.o:src/%.cpp
mkdir -p $(dir $@)
g++ -c $^ -o $@ $(compile_options)
# 链接生成可执行文件
run/exec:$(cpp_objs)
mkdir -p $(dir $@)
g++ $^ -o $@
# 执行可执行文件
run:run/exec
./$<
# 清理
clean:
rm -rf objs run
# 测试
debug:
echo $(cpp_srcs)
echo $(cpp_objs)
echo $(include_paths)
echo $(I_flags)
echo $(compile_options)
将项目制作成为静态库
文件结构如下:
- lib目录为编译打包后的静态库目录,静态库名称为
libxxx.a
- objs目录为中间产生的目标文件,
- run目录为链接静态库后生成的可执行文件存放路径,
lib_srcs:=$(filter-out src/main.cpp, $(shell find src -name *.cpp))
lib_objs:=$(patsubst src/%.cpp, objs/%.o, $(lib_srcs))
include_paths:=./include
library_paths:=./lib
library_name:=xxx
I_option:=$(include_paths:%=-I %) # 指定头文件路径
L_option:=$(library_paths:%=-L %) # 指定库的路径
l_option:=$(library_name:%=-l %) # 指定库名
compile_options:= -g -O3 -std=c++11 -w $(I_option) # 编译选项
linking_options:= $(L_option) $(l_option) # 链接选项
#####################################编译静态库
# 编译
objs/%.o:src/%.cpp
mkdir -p $(dir $@)
g++ -c $^ -o $@ $(compile_options)
# 打包成为第三方静态库
lib/libxxx.a:$(lib_objs)
mkdir -p $(dir $@)
ar -r $@ $^
#####################################链接静态库
# 编译
objs/main.o:src/main.cpp
mkdir -p $(dir $@)
g++ -c $^ -o $@ $(compile_options)
# 链接静态库
run/exec:objs/main.o
mkdir -p $(dir $@)
g++ $^ -o $@ $(linking_options)
#####################################其他
# 清理
clean:
rm -rf objs lib run
# 测试
debug:
echo $(include_paths)
echo $(compile_options)
echo $(linking_options)
将项目制作成为动态库
文件结构如下:
- lib目录为编译打包后的静态库目录,动态库名称为
libxxx.so
- objs目录为中间产生的目标文件,
- run目录为链接动态库后生成的可执行文件存放路径,
lib_srcs:=$(filter-out src/main.cpp, $(shell find src -name *.cpp))
lib_objs:=$(patsubst src/%.cpp, objs/%.o, $(lib_srcs))
include_paths:=./include
library_paths:=./lib
library_name:=xxx
I_option:=$(include_paths:%=-I %) # 指定头文件路径
L_option:=$(library_paths:%=-L %) # 指定库的路径
l_option:=$(library_name:%=-l %) # 指定库名
compile_options:= -g -O3 -std=c++11 -w -fPIC $(I_option) # 编译选项
linking_options:= $(L_option) $(l_option) # 链接选项
#####################################编译静态库
# 编译
objs/%.o:src/%.cpp
mkdir -p $(dir $@)
g++ -c $^ -o $@ $(compile_options)
# 打包成为第三方动态库
lib/libxxx.so:$(lib_objs)
mkdir -p $(dir $@)
g++ -shared $^ -o $@
#####################################链接动态库
# 编译
objs/main.o:src/main.cpp
mkdir -p $(dir $@)
g++ -c $^ -o $@ $(compile_options)
# 链接动态库
run/exec:objs/main.o
mkdir -p $(dir $@)
g++ $^ -o $@ $(linking_options)
#####################################其他
# 清理
clean:
rm -rf objs lib run
# 测试
debug:
echo $(include_paths)
echo $(compile_options)
echo $(linking_options)
test: lib/libxxx.so run/exec
./run/exec