LoginSignup
37
23

More than 3 years have passed since last update.

C++のコードを何も考えずにclangでコンパイルしたらこけた

Last updated at Posted at 2016-10-04

プログラミングの授業で、C++のコードが公開されていた。
Mac環境でターミナルからコンパイルしようとしてこけたのでメモ

>>> TL;DR (解決法) <<<

Disclaimer

  • 学校でLinuxでC言語の課題をやる際に使っていたコンパイル用コマンドは以下の通り。C言語の時は、 Macでも通っていた。
    • gcc -Wall -o exec_name source_1_name.c source_2_name.c ....
  • 学校でやった流れで家のMacでもgccと打ち込んだが、中身はclangである。
  • 以前この記事は、「Windows環境で書かれたC++コード(WINAPIを利用するように見えて実は利用しないコード)」に対して書いていましたが、WINAPIが必要なコードは結局Macでもコンパイルすることはないだろう(少なくともこの記事の解決法はそれを回避する方法が書いていない)と考えたのでもう少し一般的なところに書き直しました
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

コードの構造

Project
|- subclass.cpp (main.cppで使うクラスを定義)
|- subclass.h (↑のヘッダファイル)
|- main.cpp (int main()はここ)

何も考えずにgcc (or clang)

$ clang -Wall main.cpp subclass.cpp
Undefined symbols for architecture x86_64:
  "std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
      _main in main-f40c0c.o
  "std::__1::ios_base::getloc() const", referenced from:
      _main in main-f40c0c.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::put(char)", referenced from:
      _main in main-f40c0c.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush()", referenced from:
      _main in main-f40c0c.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(int)", referenced from:
      _main in main-f40c0c.o
  "std::__1::cout", referenced from:
      _main in main-f40c0c.o
  "std::__1::ctype<char>::id", referenced from:
      _main in main-f40c0c.o
  "std::__1::locale::~locale()", referenced from:
      _main in main-f40c0c.o
  "std::terminate()", referenced from:
      ___clang_call_terminate in main-f40c0c.o
  "operator delete[](void*)", referenced from:
      IntArray::~IntArray() in IntArray-0d8654.o
      IntArray::~IntArray() in IntArray-0d8654.o
  "operator new[](unsigned long)", referenced from:
      IntArray::IntArray(int) in IntArray-0d8654.o
      IntArray::IntArray(int) in IntArray-0d8654.o
  "___cxa_begin_catch", referenced from:
      ___clang_call_terminate in main-f40c0c.o
  "___gxx_personality_v0", referenced from:
      _main in main-f40c0c.o
      Dwarf Exception Unwind Info (__eh_frame) in main-f40c0c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

WTF?!?!?!?
Xcodeでの開発の経験があったので、こういうパターンの出力は何らかのライブラリがない(か、ヘッダで宣言だけして実装を忘れるというポカをやった)可能性があるということはわかったのだが、includeの必要なものは全てやったはずだった。

少し調べてみると何も考えずにclangでコンパイルした場合C++ライブラリが使われないことが判明した。

正しいコンパイル方法

明示的にlibc++とリンクする

$ clang -Wall main.cpp subclass.cpp -lc++

clang++を使う

$ clang++ -Wall main.cpp subclass.cpp

こいつはコンパイル時に-lc++をつけてくれる。-vで処理を詳しくみるとわかる。
出力はかなり長いが、注目すべき場所はclangldを呼んだ時の-lSystemフラグの前だ。

  • clangの出力内容の一部
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.11.0
...(中略)...
-lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a
  • clang++の出力内容の一部
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.11.0
...(中略)...
-lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a

追記 2019/10/23: Apple LLVM Version 10.0.0でも対処法は同じことを確認済みです。

・ω)┌┘’,;’;≡三<ClpsPLUG R1 (H31) 10/23 10:58:32)
> 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/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
37
23
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
23