2018-09-30:目前慎用CGAL的header-only模式

因为这个模式是新出来的,好像不是那么完善

今天我尝试在mingw-w64下编译一个带CGAL的程序,结果msys2里面自带的包管理器里面的CGAL有问题,虽然二进制文件是好的,但cmake文件中还残留了不少编译时留下的绝对路径信息,显然是没法用了。

于是下载CGAL源码自己编译。CGAL新版中有那么一个header-only模式,也就是不编译,就把源文件放在那里,等真正要用时一起。考虑到以前CGAL动不动就要编译几十分钟,毫不犹豫选了这个模式——其实,这个模式我之前已经用过好多次了。

然而这次就出了幺蛾子,程序编译到98%进入链接阶段时,报了一堆undefined reference错误类似这样:

c:/ming64gcc48/projects/CGAL/rel-mpfr-3.1.2w64gcc48/lib/libmpfr.a(init2.o):init2.c:(.text+0x70): undefined reference to `__gmp_get_memory_functions'
c:/ming64gcc48/projects/CGAL/rel-mpfr-3.1.2w64gcc48/lib/libmpfr.a(clear.o):clear.c:(.text+0x1e): undefined reference to `__gmp_get_memory_functions'
c:/ming64gcc48/projects/CGAL/rel-mpfr-3.1.2w64gcc48/lib/libmpfr.a(div.o):div.c:(.text+0x234): undefined reference to `__gmpn_divrem'
c:/ming64gcc48/projects/CGAL/rel-mpfr-3.1.2w64gcc48/lib/libmpfr.a(round_prec.o):round_prec.c:(.text+0xa76): undefined reference to `__gmp_get_memory_functions'
c:/ming64gcc48/projects/CGAL/rel-mpfr-3.1.2w64gcc48/lib/libmpfr.a(mulders.o):mulders.c:(.text+0x5c2): undefined reference to `__gmpn_divrem'
c:/ming64gcc48/projects/CGAL/rel-mpfr-3.1.2w64gcc48/lib/libmpfr.a(mulders.o):mulders.c:(.text+0x94c): undefined reference to `__gmpn_divrem'
c:/ming64gcc48/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.0/../../../../x86_64-w64-mingw32/bin/ld.exe: c:/ming64gcc48/projects/CGAL/rel-mpfr-3.1.2w64gcc48/lib/libmpfr.a(mulders.o): bad reloc address 0x0 in section `.pdata'
collect2.exe: error: ld returned 1 exit status

然而nm查看库文件时,明明时有那些符号的。没办法,放狗搜吧,找到两个信息:

我首先尝试了第三种做法,把MPRFGMP的依赖项去掉,再配置CGALheader-only模式,结果一样。但是那俩选项明明已经去掉了。研究cmake日志发现这俩货仍然出现再日志文件中。清除CGAL目录重新配置,未果。在CGALcmake脚本里交换这俩货的顺序,未果。

走投无路,我甚至怀疑是同时用上的libigl又把这俩选项偷偷打开了(libigl有这样搞boost的黑历史,当时我还提供了一个PR作为临时解决方案),但找了半天也没证据。

反复研究之后,cmake的输出里面有个地方引起了我的兴趣:

Requested component: MPFR
Requested component: GMP
Requested component: MPFR

为啥MPRF被请求了两次呢?加了几条输出,确定这句话是第一包含CGAL时输出的,并非libigl搞鬼。那么是不是按上面前两条链接里面写的,最后一次MPRF引用搞坏事了?

于是决定编译一个正常版本的CGAL,编译前灵光一现,决定先试试带MPRFGMP的编译版。编译出来CGAL之后,再在自己的程序里引用,编译,链接,一切正常。

所以,msys库里带的MPRFGMP一点问题都没有,CGAL的经典版本也没问题,但CGALheader-only版本就会在mingw-w64平台下闹出上面那个顺序依赖。

P.S. 其实现在的`CGAL 4.12`版本,编译也只需要一分钟,比后面的安装过程还快。
  • 最后更改: 2019/05/27 13:45