かみのメモ

コンピュータビジョン・プログラムな話題中心の勉強メモ

macOSのcmakeでcmathが大量のエラーを吐いたときのメモ

MacでPCL(Point Cloud Library)のサンプルをcmakeからビルドしようとしたときに、次のようなエラーが大量発生したので原因を調べてみました。

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cmath:313:9: error: no member named 'signbit' in the global namespace
using ::signbit;
      ~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cmath:314:9: error: no member named 'fpclassify' in the global namespace
using ::fpclassify;
      ~~^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/cmath:315:9: error: no member named 'isfinite' in the global namespace; did you mean 'finite'?
using ::isfinite;
      ~~^
(以下略)

環境

macOS Mojave 10.14.1
Homebrew 1.8.2-91-g9992674
vtk: stable 8.1.1 (bottled), HEAD   (Homebrewからインストール)
pcl: stable 1.8.1 (bottled), HEAD   (Homebrewからインストール)
clang++: Apple LLVM version 10.0.0 (clang-1000.11.45.5)

原因

調べたところ、コンパイラのサーチパスが汚れているせいでcmathが意図しないmath.hを参照しているのが原因のようです。

今回の場合、brewを通してインストールしたvtkのcmakeファイルが/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/includeコンパイル時のサーチパスに追加しているせいで、clang++が参照する/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1との間でmath.hが競合していました。

解決策

少し強引ですが、明示的に/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1の方を先に探索させるように書くことでビルドが通るようになりました。

include_directories(SYSTEM "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1")

find_package(PCL REQUIRED COMPONENTS common io)
include_directories(AFTER SYSTEM ${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

こういうライブラリの開発元が用意している設定ファイルに問題があるケースは困りものですよね…。

そもそも、XCodeが管理しているclang++とbrewで管理しているclang++が共存しているのがよくないんですが、XCode Toolchainを入れないとXCode周りの一部の機能が使えないし、でもlinterやcompletion系のツールはbrew管理のパッケージの方が充実してるし、どっちもつかいたんですよね。