Catalina C++:使用 <cmath>标头产生错误:全局命名空间中没有名为“signbit"的成员

2021-12-06 00:00:00 macos clang c++ toolchain macos-catalina

从 Mojave 升级到 Catalina 后,在 env 中设置:/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk.

After upgrading to Catalina from Mojave, Setuping: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk in the env.

我无法编译使用 标头的程序.

I'm unable to compile a program that use <cmath> header.

我尝试更改 CFLAGS、CCFLAGS、CXXFLAGS 以指向 MacOSSDK 位置,但没有任何变化

I tried changing CFLAGS, CCFLAGS, CXXFLAGS to point to the MacOSSDK Location that change nothing

Scanning dependencies of target OgreMain
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f OgreMain/CMakeFiles/OgreMain.dir/build.make OgreMain/CMakeFiles/OgreMain.dir/build
[  0%] Building CXX object OgreMain/CMakeFiles/OgreMain.dir/src/OgreASTCCodec.cpp.o
cd /Users/roman/Downloads/ogre-1.12.2/build/OgreMain && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  -DOgreMain_EXPORTS -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 -I/Users/roman/Downloads/ogre-1.12.2/OgreMain/src/OSX -I/Users/roman/Downloads/ogre-1.12.2/OgreMain/include/Threading -I/Users/roman/Downloads/ogre-1.12.2/OgreMain/src -I/Users/roman/Downloads/ogre-1.12.2/build/Dependencies/include -I/Users/roman/Downloads/ogre-1.12.2/OgreMain/include -I/Users/roman/Downloads/ogre-1.12.2/build/include -I/Users/roman/Downloads/ogre-1.12.2/OgreMain -isystem /usr/local/include  -Wall -Winit-self -Wcast-qual -Wwrite-strings -Wextra -Wundef -Wmissing-declarations -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers -Wno-long-long -Wno-inconsistent-missing-override  -msse -O3 -DNDEBUG -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -fPIC -fvisibility=hidden -fvisibility-inlines-hidden   -std=c++11 -o CMakeFiles/OgreMain.dir/src/OgreASTCCodec.cpp.o -c /Users/roman/Downloads/ogre-1.12.2/OgreMain/src/OgreASTCCodec.cpp
In file included from /Users/roman/Downloads/ogre-1.12.2/OgreMain/src/OgreASTCCodec.cpp:29:
In file included from /Users/roman/Downloads/ogre-1.12.2/OgreMain/src/OgreStableHeaders.h:40:
In file included from /Users/roman/Downloads/ogre-1.12.2/OgreMain/include/OgrePrerequisites.h:309:
In file included from /Users/roman/Downloads/ogre-1.12.2/OgreMain/include/OgreStdHeaders.h:10:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:314:9: error: no member named 'signbit' in the global namespace
using ::signbit;
      ~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:315:9: error: no member named 'fpclassify' in the global namespace
using ::fpclassify;
      ~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:316:9: error: no member named 'isfinite' in the global namespace; did you mean 'finite'?
using ::isfinite;

例如宏:isless 存在于全局命名空间和我的计算机上:

for example the macro: isless is present in the global namespace and on my computer:

? cat math.h | grep "isless"

#define isless(x, y) __builtin_isless((x),(y))
#define islessequal(x, y) __builtin_islessequal((x),(y))
#define islessgreater(x, y) __builtin_islessgreater((x),(y))
?  pwd
/usr/local/include
?

即使是 cmath 标头也包含它:

Even the cmath header include it:

? cat /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath | grep "math.h"
#include <math.h>

我的命令行有选项 -isystem/usr/local/include

这应该有效...

推荐答案

我很好奇:你用的是什么编译器?CMAKE_OSX_SYSROOT 的价值是什么?

I'm curious: What compiler are you using? What's the value of CMAKE_OSX_SYSROOT?

我相当确信这是错误的 CMAKE_OSX_SYSROOT 的结果.我在使用 python 绑定进行 clang 时遇到了您描述的问题(其中 CMake 不管理编译器调用),但我设法通过执行以下操作在 CMake 中重新创建错误:

I'm fairly convinced this is the result of a wrong CMAKE_OSX_SYSROOT. I had the problem you're describing when using python bindings for clang (where CMake doesn't manage the compiler call), but I managed to recreate the error in CMake by doing:

set(CMAKE_OSX_SYSROOT "")  # Reset.

我按照这个问题的答案解决了我的问题:更新到 macOS Catalina 后无法用 C++ 代码编译 R 包.

I solved my problem by following the answers to this question: Cannot compile R packages with c++ code after updating to macOS Catalina.

总结:在 Catalina 上,/usr/include 被 SIP 清除和保护.因此,任何希望在那里找到 C 头文件的项目都将无法编译.如果我没记错的话,Apple 建议向希望 /usr/include 中的 C 头文件的项目提交错误报告.

To summarise: On Catalina, /usr/include is purged and protected by SIP. Thus, any project that expects the C headers to be found there will fail to compile. If I remember correctly, Apple recommends to file bug reports to projects that expect C headers in /usr/include.

您必须将要编译的代码的构建系统指向正确的标头:

You must point the build system of the code you're trying to compile to the right headers:

(1) 确保 Xcode 是最新的.不知道 Catalina 上过时的 Xcode 会对您的构建环境造成什么影响.

(1) Make sure Xcode is up to date. There's no telling what an outdated Xcode on Catalina might do to your build environment.

(2) 使用-isysroot/sdk/path编译器标志,其中/sdk/pathxcrun --show-sdk-的结果路径.我不确定 CMake 的最佳实践是什么,但尝试做

(2) Use the -isysroot /sdk/path compiler flag, where /sdk/path is the result of xcrun --show-sdk-path. I'm not sure what CMake's best practice is, but try doing

set(CMAKE_OSX_SYSROOT /sdk/path)

set(CMAKE_CXX_FLAGS "[...] -isysroot /sdk/path")

如果这解决了问题,您可能想在 CMake 中寻找更好的方法来做到这一点.

If that solves the problem, you may want to look for a better way to do this in CMake.

当然,如果你喜欢冒险,你也可以禁用 SIP,正如我的问题的答案中所建议的:/usr/include 在 macOS Catalina 上丢失(使用 Xcode 11)

Of course, if you're adventurous, you could also disable SIP, as suggested in the answer to my question: /usr/include missing on macOS Catalina (with Xcode 11)

相关文章