前言

尝试使用 macOS 编译 OpenWrt 18.06 分支,在拉取 feeds (./scripts/feeds update -a)时出现的错误。

错误日志

Build dependency: Please install the GNU C Compiler (gcc) 4.8 or later
Build dependency: Please install the GNU C++ Compiler (g++) 4.8 or later

Prerequisite check failed. Use FORCE=1 to override.
make: *** [staging_dir/host/.prereq-build] Error 1

分析问题

macOS 中装有 gcc 且在使用 19.07 分支时并没有遇到这个问题,猜测问题应该在 18.06 分支的检测机制上。

虽然不懂写代码和原理,但通过日志中的prereq-build应该是找到问题的线索,翻译成中文是“构建前提条件”。

通过各种搜索手段找到了include/prereq-build.mk这个文件。比对两个分支的此文件发现40行和59行 gcc 与 g++ 检测的代码有区别,而且明明白白的写着Apple,那么这就是问题所在了,这也就印证了前面对于检测机制的怀疑。

在 macOS 10.15 中执行gcc --version会显示如下信息:

$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.0 (clang-1100.0.33.8)
Target: x86_64-apple-darwin19.0.0
Thread model: posix
InstalledDir: /Applications/Xcode_11.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

因为早期的 macOS 版本如果输入gcc --version会显示Apple LLVM,所以18.06分支采取了查找LLVM字段的方式去验证 GCC 的存在,而新版 macOS 的 GCC 版本信息中并没有LLVM字段,所以使用18.06分支中的检测方式必然会失败。而19.07分支的检测方式分别查找了LLVMclang,就同时兼顾了新老版本。

至于为什么会出现这个情况,就要从LLVMclang的关系说起了,但这并不是本文要讨论的内容,所以就不水了,感兴趣的小伙伴可以去搜索。

解决方案

编辑include/prereq-build.mk文件,把grep Apple.LLVM替换为grep -E 'Apple.(LLVM|clang)'

作为一个懒人,总喜欢搞一些一键命令,所以这个也不例外。这里使用的是GNU sed,因为我不会BSD sed,也懒得研究了。

gsed -i "s/grep Apple.LLVM/grep -E 'Apple.(LLVM|clang)'/g" include/prereq-build.mk

总之,如果你正在使用 macOS 编译 OpenWrt ,不论哪个源码,安装gnu-sed然后直接在源码根目录直接输入上面的命令就行了,这相当于是你开启 macOS 编译 OpenWrt 的一把钥匙。