Makefile入门与实例

main.cpp源文件:包含入口函数 int main(),该源文件中添加了“func.h”头文件,在入口函数中调用func()函数。
func函数中在func.cpp中定义,在func.h中原型声明。

编写Makefile文件
1)定义变量
首先定义SOURCE,OBJS和TARGET变量,用于指代我们项目中的源文件、目标文件和可执行文件。
2) 设置编译参数
CC:配置编译器为g++,
LIBS:需要调用的链接库(-l开头,去掉lib和.so。例:对 libopencv_core.so链接库的调用要写作:-lopencv_core),
LDFLAGS:链接库的路径(-L开头),
INCLUDE:头文件的路径。
3)链接生成
此步骤生成可执行文件(ELF),链接需要用到目标文件,由下一步产生
4)编译
此步骤生成目标文件(.o)
5)清理
此步骤清理可执行文件和所有的目标文件

#######################
# Makefile
#######################
# source object target
SOURCE := main.cpp func.cpp
OBJS := main.o func.o
TARGET := main

# compile and lib parameter
CC := g++
LIBS :=
LDFLAGS := -L.
DEFINES :=
INCLUDE := -I.
CFLAGS :=
CXXFLAGS:=

# link
#(TARGET):(OBJS)
(CC) -o@ ^

# compile
#(OBJS):(SOURCE)(CC) -c main.cpp -o main.o
(CC) -c func.cpp -o func.o

# clean
clean:
rm -fr *.o
rm -fr(TARGET)

#将上述Makefile中的:
# link
#(TARGET):(OBJS)
(CC) -o@ ^

# compile
#(OBJS):(SOURCE)(CC) -c main.cpp -o main.o
(CC) -c func.cpp -o func.o

#也可以修改为:
all:(CC) -o (TARGET)(SOURCE)

将func.cpp源文件制作成动态链接库libfunc.so,然后调用该动态库对main.cpp进行编译链接。

#######################
# Makefile 动态链接库的生成
#######################

# compile and lib parameter
CC := g++
LIBS :=
LDFLAGS :=
DEFINES :=
INCLUDE := -I.
CFLAGS :=
CXXFLAGS:=

# link parameter
LIB := libfunc.so

#link
(LIB):func.o(CC) -shared -o -fPIC -o @^
#compile
func.o:func.cpp
(CC) -c -fPIC^ -o @

# clean
clean:
rm -fr *.o

执行make命令之后,就可以在当前目录生成libfunc.so的动态链接库了。
注意:动态链接库必须“以lib开头,以.so结尾”。
注:缺少 -fPIC错误

动态链接库的调用:如果并没有提供func.cpp和func.o,只是提供了libfunc.so这个链接库,我们如何生成可执行文件呢?

Makefile如下:
1)编译的时候需要通过INCLUDE指明头文件的路径
2)链接的时候需要通过LDFLAGS 和 LIBS指明动态库的路径和名称。这里需要注意的是,指明动态库名称时需要“掐头去尾”,例:我们需要用到 libfunc.so库,LIBS必须定义为 -lfunc 。
3)执行的时候,需要把libfunc.so动态库拷贝到系统环境变量包含的路径下(比如/lib或/usr/lib),这样程序在运行时才能调用到动态库。

#######################
# Makefile
#######################

# target
TARGET := main

# compile and lib parameter
CC := g++
LDFLAGS := -L/path/to/libfunc.so
LIBS := -lfunc
DEFINES :=
INCLUDE := -I/path/to/func.h
CFLAGS :=
CXXFLAGS:=

# link(TARGET):main.o
(CC) -o@ ^(LDFLAGS) (LI

#compile
main.o:main.cpp(CC) (INCLUDE) -c^crm -fr (TARGET)

clean:
rm -fr *.o
rm -fr(TARGET)

静态链接库的生成。将func.cpp源文件制作成静态链接库func.a,然后调用该静态库对main.cpp进行编译链接。执行make命令之后,就可以在当前目录生成func.a的静态链接库了

#######################
# Makefile
#######################

# compile and lib parameter
CC := g++
LIBS :=
LDFLAGS :=
DEFINES :=
INCLUDE := -I.
CFLAGS :=
CXXFLAGS:=

# link parameter
AR := ar
LIB := func.a

#link
(LIB):func.o(AR) -r @^
#compile
func.o:func.cpp
(CC) -c^ -o @

# clean
clean:
rm -fr *.o

静态链接库的调用
Makefile如下:
1)编译的时候需要通过INCLUDE指明头文件的路径
2)链接的时候需要通过LDFLAGS 和 LIBS指明静态库的路径和名称。这里不需要像动态库那样“掐头去尾”,直接写作func.a即可。
3)执行的时候,不需要拷贝func.a至环境变量包含的路径,直接执行即可。

#######################
# Makefile
#######################

# target
TARGET := main

# compile and lib parameter
CC := g++
LDFLAGS := -L.
LIBS := func.a
DEFINES :=
INCLUDE := -I.
CFLAGS :=
CXXFLAGS:=

# link(TARGET):main.o
(CC) -o@ ^(LIBS)
#compile
main.o:main.cpp
(CC) -c^ -o @

# clean
clean:
rm -fr *.o
rm -fr(TARGET)