稀有猿诉

十年磨一剑,历炼出锋芒,说话千百句,不如码二行。

Assimp安装折腾记

为了学习OpenGL,在学习大名鼎鼎的LearnOpenGL时,参考它的源码时遇到了一点小小的困难,折腾了两天,感觉有必要总结一下。

LearnOpenGL是一个大神写的一整套关于OpenGL的资料,已出版成书,非常具有参考价值。不过它里面的示例都依赖于一些开源库,如assimpglfw以及glm等。在它的ReadMe中也都针对主流平台Windows, Linux/Unix以及Mac上面给出安装和编译教程。

先在Ubuntu 22.04 LTS上面搞,按照其官方教程上面说的Linux/Unix编译方法,一下子就搞定了。

但在Mac上面就遇到了困难。这里得说一下,我的MBP是2019年买的,系统版本是Mojave 10.14.6,现在来看是过点过时了,因为最新的稳定版本Mac OSX已经到了Ventura 10.22了,很多软件,像XCode等都已经不再提供对Mojave的支持了,平时安装软件以及一些开发库的时候也都有遇到不支持的情况。但仍不想升级,因为旧硬件升级大版本的新操作系统,往往会遇到问题,即使能升级成功,性能也大打折扣。对于电子产品,永远相信出厂的配置是最优的。可以进行小的升级,但绝不升级大版本。

好了,这些是背景。

brew初偿败果

仍是按照教程在Mac上面,先是安装依赖:

1
brew install cmake assimp glm glfw freetype

但安装依赖时出错了,以下是错误信息(很长,很长,只截取一部分):

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Running `brew update --auto-update`...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).

You have 3 outdated formulae installed.

Warning: You are using macOS 10.14.
We (and Apple) do not provide support for this old version.
It is expected behaviour that some formulae will fail to build in this old version.
It is expected behaviour that Homebrew will be buggy and slow.
Do not create any issues about this on Homebrew's GitHub repositories.
Do not create any issues even if you think this message is unrelated.
Any opened issues will be immediately closed without response.
Do not ask for help from Homebrew or its maintainers on social media.
You may ask for help in Homebrew's discussions but are unlikely to receive a response.
Try to figure out the problem yourself and submit a fix as a pull request.
We will review it but may or may not accept it.

==> Fetching assimp
==> Downloading https://github.com/assimp/assimp/commit/5a89d6fee138f8bc979b508719163a74ddc9a384.patch?full_index=1
Already downloaded: /Users/alexhilton/Library/Caches/Homebrew/downloads/af0c0eeaaca4991d7485bfb46ac1cb6209ce97489e6e4a94cb0debcaa03215cc--5a89d6fee138f8bc979b508719163a74ddc9a384.patch
==> Downloading https://github.com/assimp/assimp/archive/v5.2.5.tar.gz
Already downloaded: /Users/alexhilton/Library/Caches/Homebrew/downloads/17609a79a14f9163556e55125d6e9008276ba8e8bae256242c47e9dbbb4a34d2--assimp-5.2.5.tar.gz
Warning: A newer Command Line Tools release is available.
Update them from Software Update in System Preferences.

If that doesn't show you any updates, run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 11.3.1.

==> Patching
==> Applying 5a89d6fee138f8bc979b508719163a74ddc9a384.patch

==> cmake  -S . -B build -G Ninja -DASSIMP_BUILD_TESTS=OFF -DASSIMP_BUILD_ASSIMP_TOOLS=ON -DCMAKE_INSTALL_RPATH=@loader_
==> cmake --build build
Last 15 lines from /Users/alexhilton/Library/Logs/Homebrew/assimp/02.cmake:
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/math.h:769:1: note: candidate function
abs(long double __lcpp_x) _NOEXCEPT {return ::fabsl(__lcpp_x);}
^
1 error generated.

Do not report this issue to Homebrew/brew or Homebrew/homebrew-core!

Error: You are using macOS 10.14.
We (and Apple) do not provide support for this old version.
It is expected behaviour that some formulae will fail to build in this old version.
It is expected behaviour that Homebrew will be buggy and slow.
Do not create any issues about this on Homebrew's GitHub repositories.
Do not create any issues even if you think this message is unrelated.
Any opened issues will be immediately closed without response.
Do not ask for help from Homebrew or its maintainers on social media.
You may ask for help in Homebrew's discussions but are unlikely to receive a response.
Try to figure out the problem yourself and submit a fix as a pull request.
We will review it but may or may not accept it.

Error: A newer Command Line Tools release is available.
Update them from Software Update in System Preferences.

If that doesn't show you any updates, run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 11.3.1.

总结起来就是一句话,你的操作系统太旧了,brew已经不支持了,自已解决吧,别向brew来报问题。。。

傻掉了,因为看到需要升级系统,有了放弃的想法,因为有Ubuntu上能跑就也差不多够用了,也很晚了,就休息了。

尝试解决

第二天,仍不想轻易放弃,想再折腾一下。因为不确定是哪个库安装失败了,所以就一个一个的单独安装。单独安装cmake, glfw, glm, freetype都成功了。就是assimp会出错,错误信息与昨晚一样。

它里面也有提示,说可以尝试升级一下Command Line Tools,这货是XCode带的命令行编译工具集。因为最新版本XCode已不支持Mojave了,并不会提示更新Command Line Tools,其实我的Command Line Tools已经是支持Mojave中最新的了。

按错误信息中的提示,强行把xcode-select重装一遍也还是出错。

折腾环境这条路就断了,只能找找其他方式。回到问题本身,仔细看了下错误信息,似乎是一个编译错误:

1
2
3
4
5
6
Last 15 lines from /Users/alexhilton/Library/Logs/Homebrew/assimp/02.cmake:
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/math.h:769:1: note: candidate function
abs(long double __lcpp_x) _NOEXCEPT {return ::fabsl(__lcpp_x);}
^
1 error generated.

但是这个信息仍不够明确,没有指出是assimp的哪句编译出错的。

于是就想换条路吧,用brew不可以,那直接找assimp编译好的库,或者直接手动去编译它的源码,应该可行吧?找了一下,没找到可用的已编译好的库,于是就去手动编译assimp的源码。

直接编译assimp源码

把assimp源码直接下载下来,下载最新稳定版本5.2.5,这与brew的版本是一致的,然后按官程编译,也出错了,但错误信息非常详细:

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
➜  assimp-5.2.5 cmake --build .
[  0%] Building CXX object code/CMakeFiles/assimp.dir/Common/Assimp.cpp.o
[  0%] Building CXX object code/CMakeFiles/assimp.dir/CApi/CInterfaceIOWrapper.cpp.o
[  0%] Building CXX object code/CMakeFiles/assimp.dir/Common/Compression.cpp.o
[  1%] Building CXX object code/CMakeFiles/assimp.dir/Common/BaseImporter.cpp.o
[  1%] Building CXX object code/CMakeFiles/assimp.dir/Common/BaseProcess.cpp.o
In file included from /Users/alexhilton/opensource/assimp-5.2.5/code/Common/BaseProcess.cpp:44:
In file included from /Users/alexhilton/opensource/assimp-5.2.5/code/Common/BaseProcess.h:46:
In file included from /Users/alexhilton/opensource/assimp-5.2.5/include/assimp/GenericProperty.h:50:
/Users/alexhilton/opensource/assimp-5.2.5/include/assimp/Hash.h:99:25: error: call to 'abs' is ambiguous
                hash ^= abs(data[sizeof(uint16_t)]) << 18;
                        ^~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/math.h:761:1: note:
      candidate function
abs(float __lcpp_x) _NOEXCEPT {return ::fabsf(__lcpp_x);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/math.h:765:1: note:
      candidate function
abs(double __lcpp_x) _NOEXCEPT {return ::fabs(__lcpp_x);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/math.h:769:1: note:
      candidate function
abs(long double __lcpp_x) _NOEXCEPT {return ::fabsl(__lcpp_x);}
^
1 error generated.
make[2]: *** [code/CMakeFiles/assimp.dir/Common/BaseProcess.cpp.o] Error 1
make[1]: *** [code/CMakeFiles/assimp.dir/all] Error 2
make: *** [all] Error 2

这个编译错误比较直接,不像brew给出的不直观,可以清楚的看到是头文件include/assimp/Hash.h出错了。打开include/assimp/Hash.h查看,这只是用了一个abs函数,但引用的头文件是#include ,通过搜索找到了原因,cmath中定义了三个重载abs(float) abs(double)等。而Hash.h用的是整数,整数的abs定义是在stdlib中,也就是头文件要引用。但Hash.h只引用了,所以导致找不到整数的abs。那就简单了,直接把include/assimp/Hash.h中的头文件从cmath改成cstdlib,就可以了,再次编译,成功了。

看起来是个版本兼容性的问题,估计新版本的C++兼容了cmath和cstdlib,所以只引用cmath也不会出错。Anyway,这说明只是一个小小的问题,到不了放弃或者重装系统的地步。这个可以作为Plan B,如果最后用brew仍不成功,就把手动把刚编译好的库放到项目能链接 到的地方就行了。

brew install assimp的折腾过程

既然小修改就能成功,那么如果找到brew使用的源码包,稍加修改,不就能安装成功了么,这是值得折腾的,可以加深了解一下brew的具体过程。

brew是一个软件包管理工具,它会找某一个软件的最新稳定版本,如果本地未安装的话,会把其源码下载下来,打重要的patches,然后再编译,最后执行安装。

找到了brew会把临时文件放在HOME/Library/Caches/Homebrew下面,并且如果已下载过了就不会重新再下载源码包,太好了。于是找到assimp的源码包,解压,修改Hash.h然后再压缩。然后再运行brew install assimp,发现它确实会直接用下载好的源码 包,不会重新下载,太好了,这离成功就相当近了。

但,还是会报错,它会对源码包做校验,为了防止源码包被篡改,当然需要做校验了。

1
2
3
4
5
6
7
8
9
10
==> Fetching assimp
==> Downloading https://github.com/assimp/assimp/commit/5a89d6fee138f8bc979b508719163a74ddc9a384.patch?full_index=1
Already downloaded: /Users/alexhilton/Library/Caches/Homebrew/downloads/af0c0eeaaca4991d7485bfb46ac1cb6209ce97489e6e4a94cb0debcaa03215cc--5a89d6fee138f8bc979b508719163a74ddc9a384.patch
==> Downloading https://github.com/assimp/assimp/archive/v5.2.5.tar.gz
Already downloaded: /Users/alexhilton/Library/Caches/Homebrew/downloads/17609a79a14f9163556e55125d6e9008276ba8e8bae256242c47e9dbbb4a34d2--assimp-5.2.5.tar.gz
Error: assimp: SHA256 mismatch
Expected: b5219e63ae31d895d60d98001ee5bb809fb2c7b2de1e7f78ceeb600063641e1a
  Actual: b99489f8d142769dda720f4d250da31214efad3460f92b3d3ec71919de196dd1
    File: /Users/alexhilton/Library/Caches/Homebrew/downloads/17609a79a14f9163556e55125d6e9008276ba8e8bae256242c47e9dbbb4a34d2--assimp-5.2.5.tar.gz
To retry an incomplete download, remove the file above.

这也好办,得到我们修改过的压缩包的sha256的值,然后想办法找到校验配置的文件,改一下就可以了。试了下,未成功,估计校验文件配置会被brew覆盖掉。

然后发现,brew有跳过校验的方法,运行brew edit assimp会出现关于assimp的一些meta信息,把sha256的值改一下,改成我们修改后的就可以了,然后就安装成功了。

总结

还是要找到问题的根因,多从源码出发进行hack,然后解决问题。像这个问题,一开始安装一坨依赖的时候失败了,这时就要一个一个的安装,然后看是哪个失败了。先把成功的装上,留下失败的这个慢慢解决。然后就要找到它编译失败的根本原因。如果brew安装的错误信息不够明确,那么就要直接去找它的源码,然后手动编译,看出错在哪里,这时一般能够发现问题,一般来说都是一些编译器版本兼容的小问题,这本身也能当作Plan B,因为可以手动安装。

之后就是要研究一下包管理工具的工作流程,看能否修改它使用的源码包,然后一一把流程跑通就可以了。

切忌不要一上来就轻易的去升级电脑,先尝试解决软件包本身,而不是去改运行环境,流行的开源库兼容性会很好,通常都只会是一些小的兼容问题,不要轻易的去改电脑本身的运行环境。

参考

Comments