LoginSignup
0
0

More than 1 year has passed since last update.

clang を使った VSCode のビルドタスクで起こったエラーを解決した(Mac, C++)

Posted at

環境

  • OS
    • macOS Monterey バージョン 12.4
  • CPU, GPU
    • M1
  • コンパイラ
    • Apple clang version 13.1.6 (clang-1316.0.21.2.5)

トラブル

"Hello" を標準出力するだけの main.cpp を、既定のビルドタスク設定(コンパイラは clang )でビルドしたところ、下記のエラーが発生しました。

Undefined symbols for architecture arm64:
/* 中略 */
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 {use -v to see invocation}
main.cpp
main.cpp
#include <iostream>
using namespace std;

int main() {
    cout << "Hello" << endl;
}
tasks.json
tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "process",
            "label": "C/C++: clang アクティブなファイルのビルド",
            "command": "/usr/bin/clang",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "コンパイラ: usr/bin/clang"
        }
    ]
}

解決法

コンパイラ(コマンド)を clang ではなく clang++ にします。
tasks.json の変更点は以下のようになります。(既定の設定)

tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "process",
-           "label": "C/C++: clang アクティブなファイルのビルド",
+           "label": "C/C++: clang++ アクティブなファイルのビルド",
-           "command": "/usr/bin/clang",
+           "command": "/usr/bin/clang++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
-           "detail": "コンパイラ: usr/bin/clang"
+           "detail": "コンパイラ: usr/bin/clang++"
        }
    ]
}

余談

clang コマンドを使った理由

clang は C のコンパイルコマンドだから C++ のコンパイルに使うのは不適切では?(最初から clang++ 使っとけよ)
という声が聞こえてきそうですが、

  • clangclang++ の実行ファイルの inode 番号が同じだったので、どっち使っても同じやろ! と考えた
  • clang の方が clang++ よりも美しい(主観)名前で好き

という2点から clang を採用しました。
clang にしたことが原因で沼るとは思いもよらなかった……

エラーについて

エラーメッセージにもあるように、リンカー(ld)がはたらく段階でしくじっています。
つまり、(狭義の)コンパイルは成功していますが、その後のリンクで失敗しています。
詳しい説明は省きますが、clang は C++ の標準ライブラリのオブジェクトファイルを自動的にリンクしてくれないらしいです。
それゆえ clang++ では出ないエラーが clang では出てしまうということでした。

コンパイルエラーに関してはインターネット上に情報がたくさんありますが、リンクエラーに関してはあまりなく、解決に苦労しました……

参考資料

解決法はこちらで知りました。「おまけ」の項にあります。
コンパイルとリンクについての説明もこちらに。

0
0
0

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
0
0