Catalina系统下C++引用<cmath>头文件报错:全局命名空间无signbit成员
我碰到过类似的Catalina下头文件冲突的坑,你的情况本质是系统SDK的标准math.h和/usr/local/include下的自定义math.h优先级搞反了:
Catalina自带的MacOSX10.15.sdk里的/usr/include/math.h完整实现了signbit、fpclassify这些全局函数,但你本地/usr/local/include/math.h只有isless相关的宏定义,缺少这些核心函数。编译时因为用了-isystem /usr/local/include,编译器会优先加载这个本地版本,导致标准库<cmath>里的using ::signbit找不到对应定义,从而报错。
快速临时解决(先完成编译再说)
先把本地的math.h临时改名,避免干扰编译流程:
sudo mv /usr/local/include/math.h /usr/local/include/math.h.bak
重新运行Ogre的编译命令,完成后再恢复文件:
sudo mv /usr/local/include/math.h.bak /usr/local/include/math.h
永久修复方案
1. 调整CMake头文件搜索顺序
在配置Ogre的CMake时,强制让系统SDK的头文件优先级高于/usr/local/include,运行cmake时加上以下参数:
cmake \ -DCMAKE_CXX_FLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include" \ -DCMAKE_C_FLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include" \ ..
这样编译器会优先搜索SDK里的系统头文件,再处理/usr/local/include的内容。
2. 补全本地math.h的缺失定义
先查看系统SDK里的math.h对缺失函数的定义:
grep -A 2 "signbit\|fpclassify\|isfinite" /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/math.h
把这些定义复制到你本地的/usr/local/include/math.h里,比如添加:
#define signbit(x) __builtin_signbit((x)) #define fpclassify(x) __builtin_fpclassify((x)) #define isfinite(x) __builtin_isfinite((x)) #define isnormal(x) __builtin_isnormal((x)) #define isnan(x) __builtin_isnan((x)) #define isinf(x) __builtin_isinf((x))
补全后本地math.h就和系统标准定义对齐了,不会再和<cmath>冲突。需要注意的是,这个math.h可能是某个Homebrew包安装的,后续更新该包时可能会被覆盖,要留意。
3. 排查并修复冲突的软件包
用Homebrew找出安装这个math.h的包:
brew list --formula | xargs -I {} brew list {} | grep "/usr/local/include/math.h"
找到对应的包后,尝试更新到兼容Catalina的版本,或者卸载后重新安装——很多旧包在Catalina下会存在头文件兼容问题。
内容的提问来源于stack exchange,提问作者roman Sztergbaum

