C++ makefile
编译/链接
编译:编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。
链接:链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码Linker Error。
头文件\库文件 pkg-config --cflags --libs
我们在编译、链接的时候,必须要指定头文件和库文件的位置。 pkg-config
能够把这些头文件和库文件的位置找出来,给编译器使用。
>>> pkg-config --cflags opencv # 指定头文件
-I/usr/local/include/opencv -I/usr/local/include
>>> pkg-config --libs opencv # 指定库文件
-L/usr/local/lib -L/usr/local/cuda-8.0/lib64 -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab -lcufft -lnpps -lnppi -lnppc -lcudart -lrt -lpthread -lm -ldl
-I 表示寻找头文件的目录
-L 表示寻找库文件的目录
-l 表示在库文件目录中寻找lib.so动态库文件(优先级高),以及lib.a静态库文件
gcc/g++
对于 .c和.cpp文件,gcc分别当做c和cpp文件编译(注意: c和cpp的语法强度是不一样的),g++则统一当做cpp文件编译,使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL
注意:$@
–目标文件,$^
–所有的依赖文件,$<
–第一个依赖文件
# 一般情况
GCC = g++
EXE = Demo ##生成的执行文件
OBJ = main.o ##.obj文件
default: $(EXE)
main.o: main.cpp
$(GCC) -c -o $@ main.cpp
$(EXE): $(OBJ)
$(GCC) $(OBJ) -o $(EXE)
clean:
rm -rf *.o $(EXE) ##清除所有的文件
# 进阶模板
#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
SOURCE := $(wildcard *.c) $(wildcard *.cpp) #wildcard把 指定目录 ./ 下的所有后缀是c的文件全部展开。
OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE))) #OBJS将.c文件转化为.o文件
#target you can change test to what you want
#目标文件名,输入任意你想要的执行文件名
TARGET := test
#compile and lib parameter
#编译参数
CC := g++
LIBS := #链接库查找地址
LDFLAGS :=
DEFINES :=
INCLUDE := -I. #头文件查找路径
CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
all:$(TARGET)
$(TARGET) : $(OBJS)
$(CC) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
%.o : %.cpp
$(CC) -c $< $(CFLAGS)
clean:
rm -rf *.out *.o #清除中间文件及生成文件
.PHONY:clean
# 包含opencv库
GCC = g++ -std=c++11
CFLAGS = -Wall -Wconversion -O3 `pkg-config --cflags opencv`
LIBS = `pkg-config --libs opencv`
EXE = Demo
OBJ = main.o ScalableMST.o
default: $(EXE)
main.o: main.cpp all.h ScalableMST.h
$(GCC) $(CFLAGS) -c -o $@ main.cpp $(LIBS)
ScalableMST.o: ScalableMST.cpp all.h ScalableMST.h
$(GCC) $(CFLAGS) -c -o $@ ScalableMST.cpp $(LIBS)
$(EXE): $(OBJ)
$(GCC) $(CFLAGS) $(OBJ) -o $(EXE) $(LIBS)
clean:
rm -rf *.o $(EXE)
# 包含boost库
GCC = g++ -std=c++11
BOOST = /usr/local/boost_1_63_0/
CFLAGS = -Wall -Wconversion -O3 `pkg-config --cflags opencv` -I${BOOST} -I${BOOST}/boost
LIBS = `pkg-config --libs opencv` -L ${BOOST}/libs/ -lboost_system -lpthread -lboost_thread
EXE = Demo
OBJ = main.o ScalableMST.o
default: $(EXE)
main.o: main.cpp all.h ScalableMST.h
$(GCC) $(CFLAGS) -c -o $@ main.cpp $(LIBS)
ScalableMST.o: ScalableMST.cpp all.h ScalableMST.h
$(GCC) $(CFLAGS) -c -o $@ ScalableMST.cpp $(LIBS)
$(EXE): $(OBJ)
$(GCC) $(CFLAGS) $(OBJ) -o $(EXE) $(LIBS)
clean:
rm -rf *.o $(EXE)
编译生成动态链接库 .so 文件
-shared:该选项指定生成动态连接库
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
#target you can change test to what you want
#共享库文件名,lib*.so
TARGET := libtest.so
#compile and lib parameter
#编译参数
CC := g++
LIBS :=
LDFLAGS :=
DEFINES :=
INCLUDE := -I.
CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
SHARE := -fPIC -shared
#source file
#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
SOURCE := $(wildcard *.c) $(wildcard *.cpp)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
.PHONY : clean
all : $(TARGET)
clean :
rm -fr *.so *.o
$(TARGET): $(OBJS)
$(CC) $(CXXFLAGS) $(SHARE) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
%.o : %.cpp
$(CC) -fPIC -c $< $(CFLAGS)
编译生成静态链接库 .a 文件
ar -cru + 目标文件 + 源文件
创建并导入静态链接库
ar -t + 静态库
查看静态库中包含的目标文件
#target you can change test to what you want
#共享库文件名,lib*.a
TARGET := libtest.a
#compile and lib parameter
#编译参数
CC := gcc
AR := ar
RANLIB := ranlib
LIBS :=
LDFLAGS :=
DEFINES :=
INCLUDE := -I.
CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
#source file
#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
SOURCE := $(wildcard *.c) $(wildcard *.cpp)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
.PHONY : clean
all : $(TARGET)
clean :
rm -fr *.a *.o
$(TARGET): $(OBJS)
$(AR) cru $(TARGET) $(OBJS)
$(RANLIB) $(TARGET)
%.o : %.cpp
$(CC) -fPIC -c $< $(CFLAGS)
nvcc
CUDA
源程序为.cu
文件,对应的编译器为 nvcc
. 因此, 我们可以使用 nvcc
进行变成使得 CUDA 代码可以编译链接.
NVCC = nvcc
NVCC_FLAGS = -O3 -I/usr/local/cuda/include ##include
LD_FLAGS = -lcudart -L/usr/local/cuda/lib ##library
EXE = vecadd ##生成的执行文件
OBJ = main.o support.o ##.obj文件
default: $(EXE)
main.o: main.cu kernel.cu support.h
$(NVCC) -c -o $@ main.cu $(NVCC_FLAGS)
support.o: support.cu support.h
$(NVCC) -c -o $@ support.cu $(NVCC_FLAGS)
$(EXE): $(OBJ)
$(NVCC) $(OBJ) -o $(EXE) $(LD_FLAGS)
clean:
rm -rf *.o $(EXE) ##清除所有的文件