总体来说,这一过程还是比较简单。耐心点就可以完成。其他的系统也可以对照官方的wiki去完成编译过程。
编译过程(RaspberryPi 4b)
- 打开你的项目文件夹,然后拉
ncnn
源代码,此外你还需要拉glslang
的代码; cd ncnn && git clone https://github.com/KhronosGroup/glslang.git
mkdir build && cd build
- 安装一些需要的依赖软件包;运行
sudo apt install build-essential git cmake libprotobuf-dev protobuf-compiler libvulkan-dev vulkan-utils libopencv-dev
cmake -DCMAKE_BUILD_TYPE=Release -DNCNN_VULKAN=ON -DNCNN_BUILD_EXAMPLES=ON ..
make -j8
- 在编译完后,会生成一些包和库;所以你需要建立文件夹把他们存起来;我这里是在
ncnn/build
下面新建一个lib文件夹用来存所有生成的静态库.a
文件,如下图所示,找到生成的libxxx.a
,拷贝到lib
下面就行了; - 你还需要拷贝的是
ncnn/build/src
文件夹下的platform.h
和ncnn_export.h
,找到它们,然后拷贝到ncnn/src
目录下。之后引用头文件的时候,直接引用到ncnn/src
下面就可以了。不然会报找不到这俩头文件的错。 - 这样我们就能把它当作库来使用了。
使用
使用过程我遇到了很多库会有连接不上的问题,例如
undefined reference to `glslang::InitGlobalLock()'
/usr/bin/ld: ShaderLang.cpp:(.text+0x2430): undefined reference to `glslang::GetGlobalLock()'
/usr/bin/ld: ShaderLang.cpp:(.text+0x2454): undefined reference to `glslang::ReleaseGlobalLock()'
官方的issue给出了解决方案;g++在编译的时候记得链接下面这些库:
-lncnn -lvulkan -lglslang -lOSDependent -lSPIRV -lOGLCompiler -lGenericCodeGen -lMachineIndependent
# 文件夹层级结构
.
├── Makefile
├── src
│ └── main.cpp
└── workspace
├── 3.jpg
├── xxxx
├── xxxx.bin
├── xxxx.onnx
├── xxxx.param
└── result.jpg
这里我贴出makefile来,仅供大家参考
cc := g++
name := fastdet
workdir := workspace
srcdir := src
objdir := objs
stdcpp := c++11
syslib := /usr/lib
cpp_srcs := $(shell find $(srcdir) -name "*.cpp")
cpp_objs := $(cpp_srcs:.cpp=.cpp.o)
cpp_objs := $(cpp_objs:$(srcdir)/%=$(objdir)/%)
cpp_mk := $(cpp_objs:.cpp.o=.cpp.mk)
link_opencv := opencv_core opencv_imgproc opencv_imgcodecs
link_ncnn := ncnn glslang OSDependent OGLCompiler SPIRV GenericCodeGen MachineIndependent
link_vulkan := vulkan
link_sys := stdc++ dl
link_librarys := $(link_sys) $(link_opencv) $(link_vulkan) $(link_ncnn)
include_opencv := /usr/include/opencv4
lib_opencv := /lib/aarch64-linux-gnu/lib
# ncnn config
include_ncnn := /home/pi/Documents/ncnn/src
lib_ncnn := /home/pi/Documents/ncnn/build/lib
include_paths := src \
$(include_protobuf) \
$(include_opencv) \
$(include_ncnn)
library_paths := $(lib_all) $(lib_opencv) $(lib_ncnn)
empty :=
library_path_export := $(subst $(empty) $(empty),:,$(library_paths))
run_paths := $(foreach item,$(library_paths),-Wl,-rpath=$(item))
include_paths := $(foreach item,$(include_paths),-I$(item))
library_paths := $(foreach item,$(library_paths),-L$(item))
link_librarys := $(foreach item,$(link_librarys),-l$(item))
defined := $(foreach item,$(defined),-D$(item))
cpp_compile_flags := -std=$(stdcpp) -w -g -O0 -fPIC -fopenmp -pthread $(defined)
link_flags := -pthread -fopenmp -Wl,-rpath='$$ORIGIN'
cpp_compile_flags += $(include_paths)
link_flags += $(library_paths) $(link_librarys) $(run_paths)
ifneq ($(MAKECMDGOALS), clean)
-include $(cpp_mk) $(cu_mk)
endif
$(name) : $(workdir)/$(name)
all : $(name)
run : $(name)
@cd $(workdir) && ./$(name) $(run_args)
$(workdir)/$(name) : $(cpp_objs)
@echo Link $@
@mkdir -p $(dir $@)
@$(cc) $^ -o $@ $(link_flags) -lncnn -lvulkan -lglslang -lOSDependent -lSPIRV -lOGLCompiler -lGenericCodeGen -lMachineIndependent
$(objdir)/%.cpp.o : $(srcdir)/%.cpp
@echo Compile CXX $<
@mkdir -p $(dir $@)
@$(cc) -c $< -o $@ $(cpp_compile_flags)
$(objdir)/%.cpp.mk : $(srcdir)/%.cpp
@echo Compile depends C++ $<
@mkdir -p $(dir $@)
@$(cc) -M $< -MF $@ -MT $(@:.cpp.mk=.cpp.o) $(cpp_compile_flags)
clean :
@rm -rf $(objdir) $(workdir)/$(name)
.PHONY : clean run $(name)
export LD_LIBRARY_PATH:=$(library_path_export)