かみのメモ

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

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が競合していました。

解決策1

少し強引ですが、明示的に/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})

解決策2

そもそもcmakeを使わずに自前でビルドコマンドを書けばいいという説。。