执子之手

与子偕老


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

  • 搜索
close

如何在Ubuntu上静态编译Golang+GoCV程序

时间: 2020-12-18   |   分类: 开发     |   阅读: 1869 字 ~4分钟   |   访问: 0

最近做了一个图像增强程序,用到了OpenCV。为了方便发布,我将代码使用Golang+GoCV重写,但是编译的时候发现比较麻烦,特别记录一下,以备后查。 本文对应版本如下:

  • Ubuntu 18.04.5 LTS
  • Golang 1.15.6
  • OpenCV 4.5.0
  • GoCV 0.2.5

1. Golang环境准备

1.1 安装Golang

下载对应的包,然后解压,设置PATH路径即可,不多说了。

1.2 设置GOPATH

使用go get下载的包将下载到$GOPATH目录中。 这里设置成/home/ubuntu/.go。不设置的话将自动设置成~/go目录。

1cd /home/ubuntu/.go
2export GOPATH=/home/ubuntu/.go

1.3 下载GoCV源码

1# 设置代理翻墙,要不然下载不了
2git config --global http.proxy=http://127.0.0.1:12346
3git config --global https.proxy=http://127.0.0.1:12346
4export http_proxy=http://127.0.0.1:12346
5export https_proxy=http://127.0.0.1:12346
6go get -v -u -d gocv.io/x/gocv

2. 开始编译

在GoCV的源码中,有一个Makefile文件,使用该Makefile可以简化OpenCV的编译过程。我是以此文件为基础编译的。

2.1 安装依赖库

1# 切换到源码目录
2ubuntu@testserver:~$ cd $GOPATH/src/gocv.io/x/gocv
3# 安装依赖库
4ubuntu@testserver:~/.go/src/gocv.io/x/gocv$ make deps
5sudo apt-get -y update
6sudo apt-get -y install unzip wget build-essential cmake curl git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev

2.2 下载相关源码

下载OpenCV相关源码。记得挂代理。

 1ubuntu@testserver:~/.go/src/gocv.io/x/gocv$ make download
 2rm -rf /tmp/opencv
 3mkdir /tmp/opencv
 4cd /tmp/opencv
 5curl -Lo opencv.zip https://github.com/opencv/opencv/archive/4.5.0.zip
 6unzip -q opencv.zip
 7curl -Lo opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.5.0.zip
 8unzip -q opencv_contrib.zip
 9rm opencv.zip opencv_contrib.zip
10cd -

2.3 编译

在编译之前需要对Makefile进行一些修改。因为FFMpeg、GTK、DC1394这几个功能的依赖库特别复杂,要实现静态编译非常麻烦,可能需要自己手工裁减编译这几个库。因为目前程序没有用到窗口、视频等方面的功能,所以直接裁减掉这几个功能。 修改方法是修改$GOPATH/src/gocv.io/x/gocv/Makefile这个文件。添加-D WITH_FFMPEG=OFF -D WITH_GTK=OFF -D WITH_1394=OFF -D WITH_TIFF=OFF这几个参数到目标build里面的cmake命令中即可。

 1# Build OpenCV.
 2build:
 3        cd $(TMP_DIR)opencv/opencv-$(OPENCV_VERSION)
 4        mkdir build
 5        cd build
 6        rm -rf *
 7        #cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -D OPENCV_EXTRA_MODULES_PATH=$(TMP_DIR)opencv/opencv_contrib-$(OPENCV_VERSION)/modules -D BUILD_DOCS=OFF -D BUILD_EXAMPLES=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_opencv_java=NO -D BUILD_opencv_python=NO -D BUILD_opencv_python2=NO -D BUILD_opencv_python3=NO -D WITH_JASPER=OFF -DOPENCV_GENERATE_PKGCONFIG=ON ..
 8        cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -D OPENCV_EXTRA_MODULES_PATH=$(TMP_DIR)opencv/opencv_contrib-$(OPENCV_VERSION)/modules -D BUILD_DOCS=OFF -D BUILD_EXAMPLES=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_opencv_java=NO -D BUILD_opencv_python=NO -D BUILD_opencv_python2=NO -D BUILD_opencv_python3=NO -D WITH_JASPER=OFF -D WITH_FFMPEG=OFF -D WITH_GTK=OFF -D WITH_1394=OFF -DOPENCV_GENERATE_PKGCONFIG=ON ..
 9        $(MAKE) -j $(shell nproc --all)
10        $(MAKE) preinstall
11        cd -

注意WITH_TIFF=OFF这个参数也可以不添加,不过要修改后面提到的CGO_LDFLAGS。具体看下面的介绍。

然后可以执行编译了。这个编译耗费时间会比较长。我这边花了20+分钟。

1# 默认方式编译,编译出来动态库。我不用这种方式。
2ubuntu@testserver:~/.go/src/gocv.io/x/gocv$ make build
3#  我要编译静态库,所以添加BUILD_SHARED_LIBS=OFF
4ubuntu@testserver:~/.go/src/gocv.io/x/gocv$ make build BUILD_SHARED_LIBS=OFF

漫长的等待。

2.4 安装

1# 将编译好的库安装到系统中
2ubuntu@testserver:~/.go/src/gocv.io/x/gocv$ make sudo_install
3cd /tmp/opencv/opencv-4.5.0/build
4sudo make install
5sudo ldconfig
6cd -
7[sudo] password for ubuntu: 

2.5 编译Golang程序

直接编译是无法通过的,需要设置CGO_CPPFLAGS, CGO_LDFLAGS两个环境变量,然后使用go build -tags customenv编译。

CGO_CPPFLAGS这个环境变量用于指定include文件的路径;可以通过pkg-config --cflags这个命令获得其内容。 CGO_LDFLAGS这个环境变量用于连接时期,主要指定lib文件路径及需要连接的库。可以通过pkg-config --libs获得其主要内容。见下面的注释。

1# 使用`pkg-config --cflags opencv4`获得
2export CGO_CPPFLAGS="-I/usr/local/include/opencv4"
3# 使用`pkg-config --libs --static opencv4`获得主要内容。然后添加上`--static`这个参数。
4export CGO_LDFLAGS="--static -L/usr/local/lib -L/usr/local/lib/opencv4/3rdparty -L/tmp/opencv/opencv-4.5.0/build/lib -lopencv_gapi -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm -lopencv_highgui -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs -lopencv_img_hash -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot -lopencv_videostab -lopencv_videoio -lopencv_xfeatures2d -lopencv_shape -lopencv_ml -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core -littnotify -llibprotobuf -llibwebp -llibopenjp2 -lIlmImf -lquirc -lippiw -lippicv -lade -ljpeg -lpng -lz -ltiff -lfreetype -lharfbuzz -ljbig -llzma -lm -lpthread -lrt -lc -ldl"

另外,如果要支持TIFF格式(前面Makefile中没有添加WITH_TIFF=OFF选项),则CPP_LDFLAGS中还要加上:-ljbig -llzma这两个参数,否则编译Go代码的时候会报错。

最后使用go build -v -tags customenv .命令就可以编译了。

3. 编译中碰到的一些错误

编译Go代码的时候经常碰到各种undefined reference to错误,这都是因为要链接的库没有在CPP_LDFLAGS中指定。找到对应的库,添加到参数中就好了。

3.1 jbg

1(.text+0x45): undefined reference to `jbg_enc_init'
2(.text+0x4d): undefined reference to `jbg_enc_out'
3(.text+0x55): undefined reference to `jbg_enc_free'

以上错误是需要libjbig这个库,应该是TIFF格式需要的。如果关闭了TIFF格式支持,应该不会报上面的错误。添加-ljbig就可以了。

3.2 lzma

1(.text+0x1a0): undefined reference to `lzma_code'

以上错误是需要liblzma这个库,应该也是TIFF格式需要的。添加上-llzma参数解决。

3.3 dlopen、getaddrinfo

1warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

libc

1Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

这两个警告信息暂时找不到解决办法。

4. 其他一些CGO编译相关的指令

go clean -cache 可以清除已经编译的缓存。

附录、参考资料

  • GoCV Home
  • GoCV @Github
  • Building OpenCV as a static library leads to thousands of undefined references
  • Pls add static link opencv #217
  • Golang 1.9 build warning : Using ‘getaddrinfo’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking #21421
  • OpenCV configuration options reference
  • ubuntu安装opencv无法下载IPPICV的问题 ippicv_2020_lnx_intel64_20191018_general.tgz
  • How to build more compact OpenCV applications on Linux
#Ubuntu# #Golang# #GoCV# #静态编译#
Linux常用命令介绍 05 - unzip
删除启动台Launchpad上无效的图标
  • 文章目录
  • 站点概览
Orchidflower

Orchidflower

Do one thing at a time, and do well.

76 日志
6 分类
83 标签
GitHub 知乎 OSC 豆瓣
  • 1. Golang环境准备
    • 1.1 安装Golang
    • 1.2 设置GOPATH
    • 1.3 下载GoCV源码
  • 2. 开始编译
    • 2.1 安装依赖库
    • 2.2 下载相关源码
    • 2.3 编译
    • 2.4 安装
  • 2.5 编译Golang程序
  • 3. 编译中碰到的一些错误
    • 3.1 jbg
    • 3.2 lzma
    • 3.3 dlopen、getaddrinfo
  • 4. 其他一些CGO编译相关的指令
  • 附录、参考资料
© 2009 - 2022 执子之手
Powered by - Hugo v0.104.3
Theme by - NexT
ICP - 鲁ICP备17006463号-1
0%