eos 是一个用现代 C++11/14 编写的轻量级三维形变人脸模型拟合库,下面介绍下编译它的步骤和遇到的一些坑坑坑坑!
- 博文的前半部分是用手动安装的 opencv 和 boost 构建和编译的,一路是坑,最终没有编译成功;
- 博文的后半部分是用 vcpkg 构建系统安装的 opencv 和 boost 然后构建和编译的,最终编译成功,但是运行失败。
至今为止,关于运行失败的 issue 作者也没有回复,希望有朝一日能填坑吧~
初期编译环境
- Windows 10
- Visual Studio 2017
- CMake 3.12.4
- OpenCV 4.0.1
- Boost 1.66.0
克隆配置
1 | git clone --recursive [email protected]:patrikhuber/eos.git |
打开 CMake-gui,设置
- Where is the source code:
D:/code/VS/BabyCreator/eos
- Where to build the binaries:
D:/code/VS/BabyCreator/eos_build
点击 Configure,设置编译器
- Specify the generator for this project: Visual Studio 15 2017
- Finish
配置过程遇到如下错误。
Found OpenCV Windows Pack but it has no binaries compatible with your configuration. 错误
问题
1 | Found OpenCV Windows Pack but it has no binaries compatible with your |
原因
能找到 OpenCV 路径,但找不到兼容的二进制文件。
出错的这个 OpenCV 是在 opencv.org/releases 下载的 Win pack。
尝试过网友的解决方案【尝试二、三、四】都不能解决,最终通过【尝试五】重新下载源码编译解决,因此可能是构建环境或者编译器的问题。
解决
【尝试一】重新设置环境变量:E:\opencv-4.0.1\opencv-4.0.1-winpack\opencv\build\x64\vc15\bin
【尝试二】在 eos/CMakeCache.txt
设置 OpenCV_DIR,不行。
1 | set(OpenCV_DIR "D:\\code\\VS\\BabyCreator\\eos\\3rdparty\\opencv\\build") |
【尝试三】在终端设置 OpenCV_DIR,不行。
1 | PS D:\code\VS\BabyCreator\eos> cmake . -DOpenCV_DIR=D:\\code\\VS\\BabyCreator\\eos\\3rdparty\\opencv\\build\\OpenCVConfig.cmake |
【尝试四】在 find_package 前设置 OpenCV_FOUND 为 1,不行。
1 | set(OpenCV_FOUND 1) |
【尝试五】下载源码编译 VS 2017 工程的 opencv,解决。
- 在 CMake Configure、Generate
- 在 VS ALL_BUILD、INSTALL
- 执行
install/setup_vars_opencv4.cmd
- 设置环境变量:
E:/opencv-4.0.1/opencv-4.0.1-vs-build/install/x86/vc15/bin
Imported targets and dependency information not available for Boost version 错误
1 | CMake Warning at E:/CMake/share/cmake-3.12/Modules/FindBoost.cmake:577 (message): |
原因
没找到 Boost 库,原因是没配置好。
解决
尝试了如下方式后,这个问题变成了 Unable to find the requested Boost libraries.
- 下载 boost
- 运行
boost_1_66_0/b2.exe
生成静态库 - 在
eos/CMakeCache.txt
配置1
2set(BOOST_ROOT "E:\\boost_1_66_0")
set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage/lib)
Unable to find the requested Boost libraries. 错误
1 | CMake Error at E:/CMake/share/cmake-3.12/Modules/FindBoost.cmake:2048 (message): |
原因
找到了 Boost 库,但是找不到 boost_system
、boost_filesystem
、boost_program_options
这三个库。
解决
这个问题太坑了,最终是把 E:\boost_1_66_0\stage\lib
里面的那三个库(每个有四个相关库)的名字分别删掉 lib
,如下对 boost_system
的修改:
libboost_system-vc141-mt-x32-1_66.lib
改为boost_system-vc141-mt-x32-1_66.lib
libboost_system-vc141-mt-gd-x32-1_66.lib
改为boost_system-vc141-mt-gd-x32-1_66.lib
libboost_system-vc141-mt-x64-1_66.lib
改为boost_system-vc141-mt-x64-1_66.lib
libboost_system-vc141-mt-gd-x64-1_66.lib
改为boost_system-vc141-mt-gd-x64-1_66.lib
现在终于可以生成工程文件了!
然而 VS 打开工程后编译,又有问题。
error C2065: “CV_BGR2BGRA”: 未声明的标识符
generate-obj.vcxproj1
eos\include\eos\render\texture.hpp(101): error C2065: “CV_BGR2BGRA”: 未声明的标识符 (undeclared identifier)
解决
这个问题可以根据这个 issue,把 CV_BGR2BGRA
改为 cv::COLOR_BGR2BGRA
,或者改为 0
解决。
error LNK2005: xxx 已经在 xxx 中定义;error LNK2019: 无法解析的外部符号
fit-model-simple.vcxproj1
2
3
4
5
6
7
81>boost_program_options-vc140-mt-gd.lib(boost_program_options-vc141-mt-gd-x32-1_68.dll) : error LNK2005: "public: __thiscall boost::program_options::value_semantic_codecvt_helper<char>::value_semantic_codecvt_helper<char>(void)" (??0?$value_semantic_codecvt_helper@D@program_options@boost@@QAE@XZ) 已经在 boost_program_options-vc141-mt-gd-x32-1_66.lib(value_semantic.obj) 中定义
1>boost_program_options-vc140-mt-gd.lib(boost_program_options-vc141-mt-gd-x32-1_68.dll) : error LNK2005: "public: virtual __thiscall boost::program_options::value_semantic_codecvt_helper<char>::~value_semantic_codecvt_helper<char>(void)" (??1?$value_semantic_codecvt_helper@D@program_options@boost@@UAE@XZ) 已经在 boost_program_options-vc141-mt-gd-x32-1_66.lib(value_semantic.obj) 中定义
1>boost_program_options-vc140-mt-gd.lib(boost_program_options-vc141-mt-gd-x32-1_68.dll) : error LNK2005: "void __cdecl boost::program_options::validate(class boost::any &,class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,int)" (?validate@program_options@boost@@YAXAAVany@2@ABV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@PAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@H@Z) 已经在 boost_program_options-vc141-mt-gd-x32-1_66.lib(value_semantic.obj) 中定义
1>boost_program_options-vc140-mt-gd.lib(boost_program_options-vc141-mt-gd-x32-1_68.dll) : error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl boost::program_options::to_internal(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?to_internal@program_options@boost@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV34@@Z) 已经在 boost_program_options-vc141-mt-gd-x32-1_66.lib(convert.obj) 中定义
1> 正在创建库 D:/code/VS/BabyCreator/eos_build/examples/Debug/fit-model-simple.lib 和对象 D:/code/VS/BabyCreator/eos_build/examples/Debug/fit-model-simple.exp
1>fit-model-simple.obj : error LNK2019: 无法解析的外部符号 "class cv::Mat __cdecl cv::imread(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,int)" (?imread@cv@@YA?AVMat@1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z),该符号在函数 __catch$_main$0 中被引用
1>fit-model-simple.obj : error LNK2019: 无法解析的外部符号 "bool __cdecl cv::imwrite(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class cv::debug_build_guard::_InputArray const &,class std::vector<int,class std::allocator<int> > const &)" (?imwrite@cv@@YA_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV_InputArray@debug_build_guard@1@ABV?$vector@HV?$allocator@H@std@@@3@@Z),该符号在函数 __catch$_main$6 中被引用
1>D:\code\VS\BabyCreator\eos_build\examples\Debug\fit-model-simple.exe : fatal error LNK1120: 2 个无法解析的外部命令
原因
这个问题可能是安装的这个版本的 boost 库与什么东西不兼容吧,又是环境问题,我已经无力吐槽 Windows 了(心累)。
解决
这个问题我在官方仓库提了个 issue。
作者的意思是:我没试过你的 boost 和 opencv 的版本,可能是本地配置问题,建议用构建系统(如 vcpkg) 或者在 StackOverflow 上提问。
我:emmm……
所以,这个问题未解决,最后是用 vcpkg 安装库解决的。
再次编译环境
- Windows 10
- Visual Studio 2017
- CMake 3.12.4
- OpenCV 3.4.3
- Boost 1.68.0
- vcpkg 2018.11.23-nohash
vcpkg 配置安装
安装 vcpkg、opencv、boost1
2
3
4git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install opencv boost
安装完成后,在 eos
同级目录下创建 build 文件夹 eos_vcpkg_build
,如下目录结构:
1 | - eos |
然后执行下面的命令构建工程:
1 | mkdir eos_vcpkg_build |
OpenCV_DIR
设为 vcpkg 安装的opencv 路径
BOOST_ROOT
设为 vcpkg 安装的boost 路径
BOOST_LIBRARYDIR
设为 vcpkg 安装的boost 库文件路径
BOOST_INCLUDEDIR
设为 vcpkg 安装的boost 头文件路径
CMAKE_INSTALL_PREFIX
即为make install 的路径
构建好后,用 VS 打开,右键 解决方案 eos
- 生成解决方案
然后选择 INSTALL
工程 - 右键 设为启动项目
- 右键 生成
居然成功编译并安装好了(喜极而泣)!
eos 运行示例
运行下 eos_vcpkg_build\install\bin\fit-model.exe
示例程序吧 ~
根据墨菲定律,必定没这么顺利,果然……
一连跳几个框,
1 | 由于找不到 opencv_core343.dll、opencv_imgcodecs343.dll、boost_filesystem-vc141-mt-x32-1_68.dll、jpeg62.dll、zlib1.dll 等,无法继续执行代码。重新安装重新可能会解决此问题。 |
既然缺少动态库,那就去 vcpkg 安装路径下找,如果没有则用 vcpkg 安装,然后把这些 dll 放到 fit-model.exe
同级目录下。
然后就……
1 | 应用程序无法正常启动(0xc000007b)。请点击“确定”关闭应用程序。 |
我:emmm……mmp
应该是动态库的链接错误,关于这个问题我再次开了 issue,但是作者不再回应了。
所以,在 Windows 上,只是编译成功库,但是示例都无法运行。
最终,在 Ubuntu 上,编译运行起来了。
心累。