linux下用Makefile编译代码通用模板-用作以后提取

本文详细介绍了在Linux环境下使用Makefile进行代码编译的方法,涵盖了Makefile的关键字、特殊符号的用法,以及如何链接外部库。同时,提供了可执行程序、静态库和动态库的Makefile模板,适合初学者快速上手。

1 demo

CC=arm-hisiv300-linux-g++
EXEC=demo
OBJS=demo.o anjos-keba.o
CXXFLAGS:= -Wall -Wno-sign-compare -Wno-unused-local-typedefs
CXXFLAGS+= -Wno-deprecated-declarations -Winit-self
CXXFLAGS+= -O0 -g -std=c++11 -lm -lpthread -ldl -lrt -rdynamic
$(EXEC):$(OBJS)
	$(CC) $(CFLAGS) $(OBJS) -o $(EXEC)
anjos-keba.o:anjos-keba.cpp
	$(CC) $(CFLAGS) -c anjos-keba.cpp -o anjos-keba.o
demo.o:demo.cpp
	$(CC) $(CFLAGS) -c demo.cpp  -o demo.o
clean:
	rm -rf *o
//demo.cpp
#include "anjos-keba.h"
long func(int a){
        long sum = 0;
        for(int j=1;j<=a;j++){
                sum += j;
        }
        return sum;
}
int main(void){
        std::cout<<"当前时间"<<now2str()<<std::endl;//todo anjos cout只能打印string
        int a =100;
        long sum = func(a);
        printf("%ld",sum);//todo anjos printf只能打印char*
        return 0;
}

1.1 Makefile关键字

cout只能打印string,printf只能打印char*,否则均乱码
【概念理解】

命令含义
-lpthreadc++多线程库,如果报库里函数未定义,可以试用-pthread
-rdynamic -Wl,-rpath,/usr/local/cuda/lib64新增指定路径的动态库
-Wl,-rpath=./运行库指定搜索目录,会把这个搜索目录记录在打包库中,当然也可以export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:自定义目录
-lrtC++的时间统计库
-ldl加载动态库的函数
-L/kaldi-trunk/tools/OpenBLAS/install/lib也可以这么指定库目录
-l:libopenblas.a也可以这么指定库名【全名】
-lopenblas也可以这么指定库名
-Wall显示所有警
-W只显示编译器认为会出现错误的警告
-w不显示任何警告
-std=c++11启用C++11标准
-O0O代表优化级别,-O:默认O0,可选:-O0不做任何优化(调试模式),-O1低级优化,-O2中级优化(Debug可选模式),-O3高级优化(Release模式),-Os代码空间优化
-g启用gdb调试
-lm连接数学库math

1.2 Makfile中的:= ?= += =

命令含义
=最基本的赋值【以Makefile完全展开最后变量的值作为最终值】【再代入变量计算】
:=覆盖之前的值【按照程序理解,后面的值会覆盖前面的值即可】【按照先后值顺序计算】
?=如果没有被赋值过就赋予等号后面的值
+=是添加等号后面的值

【=举例】
make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:

  x = foo
  y = $(x) bar
  x = xyz

在上例中,y的值将会是 xyz bar,而不是 foo bar 。
【:=举例】
:=表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。

  x := foo
   y := $(x) bar
   x := xyz

在上例中,y的值将会是 foo bar,而不是 xyz bar 了。

1.3 Makfile中的$@ $^ $<

命令含义
$@目标文件
$^所有依赖项文件
$<第一个依赖项目文件

2 编译链接外部库

在本函数中可以直接用extern来声明库中的函数试用方法即可。也可以#include头文件

//然后用-L链接库目录 -l:libadd.a 或-ladd 指定链接库即可
extern int add(int a, int b);

g++ main.cpp -o main -I/data1/kaldi/test/include -L/data1/kaldi/test/lib -lworld
-I/data1/kaldi/test/include将/data1/kaldi/test/include目录作为第1个寻找头文件目录

寻找顺序:data1/kaldi/test/include–>/usr/include–>/usr/local/include,找不到则查找默认目录

-L/home/hello/lib:将/data1/kaldi/test/lib目录作为第1个寻找库文件目录:

寻找顺序:/data1/kaldi/test/lib–>/lib–>/usr/lib–>/usr/local/lib

-ladd :寻找动态链接库文件libword.so(是文件名去掉前缀和后缀所代表的库文件)
CFLAGS = CFLAGS=-Wall -Wno-sign-compare -Wno-unused-local-typedefs -Wno-deprecated-declarations -Winit-self
CFLAGS+= -O0 -g -std=c++11 -lm -lpthread -ldl -lrt -rdynamic

2 Makefile可执行程序模板

该程序目前还只是仅仅支持单目标,(使用只需要修改TARGET即可)

#所有的源文件.c、.cpp
SRC  := $(wildcard *.c) $(wildcard *.cc) $(wildcard *.cpp)
#所有目标文件.o
OBJS   :=$(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(patsubst %.cpp,%.o,$(SRC))))

$(info $(OBJS))

#目标
TARGET   :=demo

#编译参数
CC       :=g++
LIBS     :=
LDFLAGS  :=
DEFINES  :=
INCLUDE  := -I.
CXXFLAGS := -Wall -Wno-sign-compare -Wno-unused-local-typedefs
CXXFLAGS += -Wno-deprecated-declarations -Winit-self
CXXFLAGS += -O0 -g -std=c++11 -lm -lpthread -ldl -lrt -rdynamic
CXXFLAGS += $(DEFINES) $(INCLUDE)

all      :  $(TARGET)
objs     : $(OBJS)

clean:
	rm -rf *.so *.o *.a $(TARGET)

$(TARGET):$(OBJS)
	$(CC) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS) 

3 Makefile静态库模板

在Makefile可执行程序模板基础上,只修改了 3 处:(使用只需要修改TARGET即可)
(1) 增加AR :=ar,并增加到$(CC)目标处
(2) 增加RANLIB :=ranlib,并增加到$(CC)目标处
(2) TARGET :=libdemo.a 修改为后缀.a的文件:

#所有的源文件.c、.cpp
SRC      := $(wildcard *.c) $(wildcard *.cc) $(wildcard *.cpp)
#所有目标文件.o
OBJS     :=$(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(patsubst %.cpp,%.o,$(SRC))))

#目标
TARGET   :=libdemo.a

#编译参数
CC       :=g++
AR       :=ar
RANLIB   :=ranlib
LIBS     :=
LDFLAGS  :=
DEFINES  :=
INCLUDE  := -I.
CXXFLAGS := -Wall -Wno-sign-compare -Wno-unused-local-typedefs
CXXFLAGS += -Wno-deprecated-declarations -Winit-self
CXXFLAGS += -O0 -g -std=c++11 -lm -lpthread -ldl -lrt -rdynamic
CXXFLAGS += $(DEFINES) $(INCLUDE)

all      :  $(TARGET)
objs : $(OBJS)

clean:
	rm -rf *.so *.o *.a $(BINS)

$(TARGET):$(OBJS)
	$(AR) cru $(TARGET) $(OBJS)
	$(RANLIB) $(TARGET)
hello:
	echo "hello worlod"

这里做了一个测试,自己新定义一个目标叫hello,然后make hello即可。

4 Makefile 动态库模板

在Makefile可执行程序模板基础上,只修改了 2 处:(使用只需要修改TARGET即可)
(1) 增加CXXFLAG += -fPIC -share,并增加到$(CC)目标处
(2) TARGET :=libdemo.so 修改为后缀.so的文件:

#所有的源文件.c、.cpp
SRC      := $(wildcard *.c) $(wildcard *.cc) $(wildcard *.cpp)
#所有目标文件.o
OBJS     :=$(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(patsubst %.cpp,%.o,$(SRC))))

#目标
TARGET   :=libdemo.so

#编译参数
CC       :=g++
LIBS     :=
LDFLAGS  :=
DEFINES  :=
INCLUDE  := -I.
CXXFLAGS := -Wall -Wno-sign-compare -Wno-unused-local-typedefs
CXXFLAGS += -Wno-deprecated-declarations -Winit-self
CXXFLAGS += -O0 -g -std=c++11 -lm -lpthread -ldl -lrt -rdynamic
CXXFLAGS += $(DEFINES) $(INCLUDE)
#动态库配置
CXXFLAG += -fPIC -share

all      :  $(TARGET)
objs : $(OBJS)

clean:
	rm -rf *.so *.o *.a $(BINS)

$(TARGET):$(OBJS)
	$(CC) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)

Reference

Makefile 中:= ?= += =的区别
Makefile常用万能模板(包括静态链接库、动态链接库、可执行文件)
运行时动态库:not found 及介绍-linux的-Wl,-rpath命令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值