colmapCompile - colmap windows的编译
编译colmap
1 前期准备
1 github上下载colmap稳定版源码:
https://github.com/colmap/colmap/archive/refs/tags/3.6.zip
之后解压进入,执行: git init
2 确保编译环境
- 1 确保你的vs不是vs2019 16.9.3以及以上,否则会有奇怪的cuda错误, 解决方案是:
- 1.1 将vs2019卸载
- 1.2 去https://docs.microsoft.com/en-us/visualstudio/releases/2019/history#installing-an-earlier-release下载vs2019 16.8.5,然后安装v140,v141的生成工具
- 2 如果本篇博客所有内容都详细读完,任然无法成功编译colmap,那就装VS2015,然后用他的生成工具(cmake -G 参数指定编译器版本,命令行里输入cmake -G),项目打开还是可以用vs2019的。
然后将编译器加入环境变量:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.16.27023\bin\HostX64\x64
输入cl能看到输出即可.
2 依赖安装
2.1 boost 直接安装(推荐下载vs2015版本,我用的是v_1_73)
https://boostorg.jfrog.io/artifactory/main/release/1.64.0/binaries/
1 | boost使用源码编译的静态方式编译: |
2.2 安装GMP和MFPR
0 不想要自己折腾: 参考: https://github.com/emphasis87/libmpfr-msys2-mingw64,这里面应该有现成的库。
1 安装Cygwin
1
2
3
4
5
6
7
8
9
10
11
12Setup Environment
Install Cygwin, add the following packages to the default installation:
gcc-core
gcc-g++
libgcc
m4
make #不知为何安装后在Cygwin根目录下搜不到make程序,见下面步骤2安装make
cmake
bash
Add the following Environment Variable to the User PATH: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.15.26726\bin\Hostx64\x64
This is so you can use the lib command. Your lib.exe may be located elsewhere.安装好Cygwin以及一些依赖以后,在其根目录(方便说明记为: CygwinRoot=”D:\CygwinRooto”)下的bin/minnty.exe是其终端入口,然后每次打开该终端,进入的是:$CygwinRoot/home/$(userName), 运行”cd /“后就可以理解了;
2 下载并安装make
- 2.1 从如下网址下载make的源码,https://ftp.gnu.org/gnu/make/,然后解压
- 2.2 打开Cygwin64 Terminal命令行,进入源码根目录,然后运行:configure && ./build.sh
- 2.3 编译得到了make.exe后将其移动到Cygwin的bin目录下
3 编译gmp
运行两个: ./configure 和 make install1
2
3
4
5
6
7
8
9
10./configure --prefix=/home/chenxy/mylibs/newTry/gmp-6.2.0/build/static --enable-static --disable-shared
configure: summary of build options:
Version: GNU MP 6.2.0
Host type: skylake-pc-cygwin
ABI: 64
Install prefix: /home/chenxy/mylibs/newTry/gmp-6.2.0/build/static
Compiler: gcc
Static libraries: yes
Shared libraries: no编译结果(默认生成的是static的数据):
1
2
3
4
5
6
7@nash-5 ~/mylibs/gmp-6.2.0
$ ls /usr/local/include/
gmp.h
@nash-5 ~/mylibs/gmp-6.2.0
$ ls /usr/local/lib/
libgmp.a libgmp.la pkgconfig生成动态连接库(注意: 动态连接库和静态连接库的.h文件不同,所以注意分成2个文件夹,至少对于gmp是如此):
1
./configure --prefix=/home/chenxy/mylibs/gmp-6.2.0/build/shared --enable-shared --disable-static
4 编译mfpr(需要gmp的依赖,而且是动态连接库)
进入mfpr的根目录:
运行./configure:1
2checking for gmp.h... no
configure: error: gmp.h can't be found, or is unusable.运行./configure –help
1
2
3
4···
--with-gmp-include=DIR GMP include directory
--with-gmp-lib=DIR GMP lib directory
···所以:
1
2
3
4
5
6./configure --prefix=/home/chenxy/mylibs/newTry/mpfr-4.1.0/build/static \
--enable-static --disable-shared \
--with-gmp-include=/home/chenxy/mylibs/newTry/gmp-6.2.0/build/static/include \
--with-gmp-lib=/home/chenxy/mylibs/newTry/gmp-6.2.0/build/staic/lib
make install1
2
3
4./configure --prefix=/home/chenxy/mylibs/mpfr-4.1.0/build/static \
--with-gmp-include=/home/chenxy/mylibs/gmp-6.2.0/build/static/include \
--with-gmp-lib=/home/chenxy/mylibs/gmp-6.2.0/build/static/lib \
--enable-static --disable-shared
2.3 其他依赖build.py会帮你下载编译
确保你能够流畅访问github,否则需要你自己下载然后修改build.py。
3 编译colmap
3.1 对编译文件和某些源文件的修改如下:
1 | diff --git a/CMakeLists.txt b/CMakeLists.txt |
3.2 编辑CmakeList.txt
set(Boost_DEBUG ON),打开boost的调试信息,boost的链接最容易出问题。(以下的内容仅供了解,无需修改)
主要注意: -DBoost_USE_STATIC_RUNTIME=ON 这个设置是指boost的库在使用cpp的runtime时候将会使用静态库,如果这个选项打开了,则需要往CmakeList.txt(colmap的根目录)中添加:
1 | # set the used type of runtime lib to be static |
上面意味着运行时库调用时选择静态运行时库(vs中,在项目->cpp->代码生成中有MT/MD的配置), 而且对应的编译出来的boost库,编译时需要带上: –link=static –runtime-link=static –build-type=complete 参数;
3.3 编译执行:
注意我们使用静态的boost避免boost 的链接错误;
1 | python scripts/python/build.py \ |
上述命令会失败,但是没关系,用code打开F:/prjs/colmap-3.6/build/colmap/__build__:
全局替换的方式删除: BOOST_ALL_DYN_LINK=1,
然后在F:/prjs/colmap-3.6/build/colmap/__build__里找到COLMAP.sln,然后手动用vs打开然后编译;
推荐使用VS2015的工具对colmap进行编译.
4 给出我编译后的库目录结构(最重要的是__install__/lib下面的内容):
其中: install/lib下面的platform中必须要有qwindows.dll,参考问题4。
然后: install/lib里面的cgal*.dll也是不必须的,因为本博客使用的cgal是5.x,5.x的cgal都是header only 的库,所以该dll可以没有,但是其他的dll像是libgmp-10.dll确是必要的,否则将无法运行。
1 | sagar@DESKTOP-QM75KNS MINGW64 /f/prjs/colmap-3.6/build |
5 可能遇到的问题:
- Q 1 一切都能正常编译通过,但是出现“程序无法正常启动, 0xc000007b”
- 解决方案: 仔细核对我提供的目录,看看是否是dll少了,一般libgmp-10.dll少了就会报这个错误,可以参照问题4
- Q 2 boost总是报link2005的重定义错误:
- 解决方案: 打开colmap.sln,你会发现: 项目->属性c++预处理(宏定义) 中多了BOOST_ALL_DYN_LINK=1,用如下方法全局删除即可:用code打开F:/prjs/colmap-3.6/build/colmap/__build__:
全局替换的方式删除: BOOST_ALL_DYN_LINK=1,然后vs会让你重载项目配置,再次编译应该可以直接通过。造成的原因可能是boost总是默认enable了autolink,这导致你必须把你的boost库的版本和你的vs版本对上,而且可能默认是全部动态链接(即使你配置了静态链接以后),可能的解决方案是,在项目根目录下面的CMAKELIST.txt中添加: - Q 3 libcpmt.lib(ppltasks.obj) : error LNK2001: 无法解析的外部符号 __CxxFrameHandler4报错:
- 解决方案: 是因为你的库用的是vs2019编译的,然后colmap又用vs2015编译,就会报这个错误。
- Q 4 Qt platform plugin ‘windows’ not found
- 解决方案: 是因为你虽然安装了qt,但是没有复制相关的dll到./build/colmap/install/lib下(colmap的运行直接双击__install__/COLMAP.BAT即可),复制方案:(也就是build.py中的编译后处理部分做的事情)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49def build_post_process(args):
if PLATFORM_IS_WINDOWS:
lapack_paths = glob.glob(
os.path.join(args.install_path, "lib64/lapack_blas_windows/*.dll"))
if lapack_paths:
for lapack_path in lapack_paths:
copy_file_if_not_exists(
lapack_path,
os.path.join(
args.install_path, "lib",
os.path.basename(lapack_path)))
if args.qt_path:
copy_file_if_not_exists(
os.path.join(args.qt_path, "bin/Qt5Core.dll"),
os.path.join(args.install_path, "lib/Qt5Core.dll"))
copy_file_if_not_exists(
os.path.join(args.qt_path, "bin/Qt5Gui.dll"),
os.path.join(args.install_path, "lib/Qt5Gui.dll"))
copy_file_if_not_exists(
os.path.join(args.qt_path, "bin/Qt5Widgets.dll"),
os.path.join(args.install_path, "lib/Qt5Widgets.dll"))
mkdir_if_not_exists(
os.path.join(args.install_path, "lib/platforms"))
copy_file_if_not_exists(
os.path.join(args.qt_path, "plugins/platforms/qwindows.dll"),
os.path.join(args.install_path, "lib/platforms/qwindows.dll"))
if args.with_cuda and args.cuda_path:
cudart_lib_path = glob.glob(os.path.join(args.cuda_path,
"bin/cudart64_*.dll"))[0]
copy_file_if_not_exists(
cudart_lib_path,
os.path.join(args.install_path, "lib",
os.path.basename(cudart_lib_path)))
if args.cgal_path:
gmp_lib_path = os.path.join(
args.cgal_path, "auxiliary/gmp/lib/libgmp-10.dll")
if os.path.exists(gmp_lib_path):
copy_file_if_not_exists(
gmp_lib_path,
os.path.join(args.install_path, "lib/libgmp-10.dll"))
cgal_lib_path = glob.glob(os.path.join(
args.cgal_path, "bin/CGAL-vc*-mt-*.dll"))
copy_file_if_not_exists(
cgal_lib_path[0],
os.path.join(args.install_path, "lib",
os.path.basename(cgal_lib_path[0]))) - Q 5 莫名其妙报了cuda的编译的错误:error : identifier “__floorf” is undefined in device code
- 解决方案: vs2019 16.9.3以及以上有这个问题,你需要卸载然后回退到16.8.5
- Q 6 C2132 编译器错误:表达式的计算结果不是常数
- 解决方案: 可能是你的编译器对cpp的新特性支持的不够好?,修改 src/retrieval/utils.h 的 55行为:
1
2// static const size_t kMaxHammingDistance = static_cast<size_t>(1.5f * kSigma);
static const size_t kMaxHammingDistance = static_cast<size_t>(24);