linux下用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*,否则均乱码
【概念理解】
| 命令 | 含义 |
|---|---|
-lpthread | c++多线程库,如果报库里函数未定义,可以试用-pthread |
-rdynamic -Wl,-rpath,/usr/local/cuda/lib64 | 新增指定路径的动态库 |
-Wl,-rpath=./ | 运行库指定搜索目录,会把这个搜索目录记录在打包库中,当然也可以export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:自定义目录 |
-lrt | C++的时间统计库 |
-ldl | 加载动态库的函数 |
-L/kaldi-trunk/tools/OpenBLAS/install/lib | 也可以这么指定库目录 |
-l:libopenblas.a | 也可以这么指定库名【全名】 |
-lopenblas | 也可以这么指定库名 |
-Wall | 显示所有警 |
-W | 只显示编译器认为会出现错误的警告 |
-w | 不显示任何警告 |
-std=c++11 | 启用C++11标准 |
-O0 | O代表优化级别,-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命令

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

282

被折叠的 条评论
为什么被折叠?



