VSCode on Mac OS Xで<bits/std++.h>をclangでincludeして楽しくC++を書けるようにする
自分がハマったのでアウトプット用に書いています。「なんでそんなことするんだ!もっといいやり方があるぞ!」というのがあったら教えてほしいです。
経緯
「C++でもやるか!」と思って、AtCoderのこの初心者向けガイドを見ました。
ここの概要部では、「計算」について主に焦点をあてているようで、最初からC++の環境構築すると詰みかねないみたいなことが書かれていました。まあそれはそうだなと思ったのですが、せっかくならちゃんとやりたいなと思って、環境構築することにしました。
自分はスクリプト言語でてきとーにプログラミングしてきたので、そういえばリンカとかオブジェクトファイルとかヘッダファイルとか、あんまりちゃんと理解できてなかったなと思って、まずそこから調べ始めました。
やってたこと
エディタ探し
ふだん使っているエディタ/IDEはvimとVSCode(Visual Studio Code)なのですが、C++に最適なものはどれかなと思っていろいろ調べました。
どれがいいのか全然わからなかったのでとりあえず適当にググっていました。
いろいろ見てて、Visual Studioがいいのかなと思って入れてみたのですが、MacだとC++は使えないことにあとから気付きました。
C++対応と書かれてなくて、単にぼくのPCのストレージ領域が使われただけなことに気付いたときの図
→ https://www.incredibuild.com/blog/best-c-ides
→ https://www.educative.io/blog/best-cpp-ides-code-editors
そのあといろいろ見ていたら、普段使っているVSCodeでいいんじゃないかと思って、VSCodeで書くことにしました。Visual Studio CodeとVisual Studioは、名前が悪いのかよく混同されて使われているような気がします。
C++ならこれがベストとかいうのがあればおしえてほしいです。
Macのclangって何。gccとかは何
このへんが雑な理解だったのでしらべました。gccは、GNUが作ったコンパイラのコレクションのことで、CやC++やObjective-CやFortranやGoやらのコンパイラが入っているみたいです。
一方でclangは、LLVMプロジェクトで作られたコンパイラとかツールチェーン(ツールのチェーンのこと)のコレクションのようです。
clangは、GCC拡張だったり、ANSI standard C/C++をサポートしているらしいです。(ANSI standard C/C++のことはよく知りません)
(→ https://www.llvm.org/Features.html)
それで、とにかくMacはclangがデフォルトのコンパイラになっているみたいです。
Macでgccが無いのに、gccって打っても動くのは、エイリアスになっていて、互換があるからのようです。
「gccじゃないじゃないか!」と思いました。
リンカとかヘッダファイルとかオブジェクトファイルとかを調べた
おぼろげな理解だったので、↓の記事でおさらいしていました。実は昔に「苦しんで覚えるc言語」という本を読んでいたり、業務でMakefileを使ったりしていたので全く何もわからないという状態ではなくて、「ほへ〜〜」と感じながら読んでいました。ついでに記事で言及されていたCMakeも見て使ってみました。
コンパイラという語についての所感
ぼくの雑な理解ですが、あるものが「これはコンパイラだ」と言われているとき、それは
- コンパイラそのものを表しているのか
- ↑のコンパイラ・アセンブラ・リンカ、全部ひっくるめてコンパイラと言っているのか
そういうのを見極めないといけないような気がしました。
Clangにはbits/std++.hというファイルが無い問題の解決
以下の記事に書かれているのですが、clangにはbits/stdc++.hが最初からついてないので、自分で入れるしかないらしいです。もしくは諦めてGCCをインストールして、それでやっている人が多いみたいです。ぼくはClangで頑張ることにしました。
そういうわけで、ここのサイトにある、このヘッダファイルの中身をコピペしてファイルを作るのがいいそうです。
↓でもぼくはこちらのヘッダファイルの中身をコピペして作成しました。
[Ref]
- https://stackoverflow.com/questions/28994148/how-can-i-include-bits-stdc-in-xcode
- https://apple.stackexchange.com/questions/148401/file-not-found-error-while-including-bits-stdc-h
作ったヘッダファイルをどこに置けばいいのか問題と、どう読み込めばいいのか問題の解決
ぼくはヘッダファイルを自分のホームディレクトリの下に作って、そこに置きました。
↓こんな感じです。本当はこのやり方はよくないのかもしれませんが、とにかく他のライブラリとかを汚したくなかったのでここに書くことにしました。
この書いたヘッダファイルの場所を、CPLUS_INCLUDE_PATH
という環境変数で指定してあげると、clangでincludeすることができるみたいです。
(→ https://atcoder.jp/contests/apg4b/tasks/APG4b_ak#local_setting)
最近のMac OS Xの環境は、zshがデフォルトシェルになっているので、みなさん基本的にはzshを使っていることと思います。なので ~/.bash_profile
ではなくて、 ~/.zshenv
とかに書くと良さそうです。~/.zshrc
ではなくて、~/.zshenv
です。
↓こんな感じで書きました。C_INCLUDE_PATHの方はぼくの趣味でつけたオマケなのでなくていいです。
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/Users/harukaeru/harukaerucplus/include/
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/Users/harukaeru/harukaerucplus/include/
VSCodeでC++書くぞ編
C++をVSCodeで書く場合は、以下の公式のページを絶対に見たほうがいいと思います。逆に見ないと詰むと思います。
→ https://code.visualstudio.com/docs/languages/cpp
ただ、このガイドは、clangとかGCCとかMinGWとか、そういう関係性がわかってる人向けに書かれているっぽいので、あんまりC++初心者向けっぽい感じではない気がします。
ここでは全部を説明せず、だいじだなーと思ったことだけ抜粋します。
- Extensionは言われるがままに全部インストールする
- .vscode/launch.jsonはデバッグ時(Run)に発動するやつ
- .vscode/tasks.jsonはビルド時に発動するやつ
- .vscode/c_cpp_properties.jsonは、どうやってincludeとかするのか指定するやつ
そうすると、↓のような感じで特にエラーなど出ることなくRunできるようになりました。
このファイルを作ったりすると、F5キーでStart Debuggingできたりして嬉しいです。書き方はVSCodeの公式リファレンスがあったり、先達たちが書いてくれているのでそれを見ると良さそうです。
↓参考情報ですが、ぼくはこうやって書きました。変かもしれないのでツッコミあればお待ちしています。
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "clang++ - Build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "clang++ build active file",
"internalConsoleOptions": "openOnSessionStart"
}
]
}
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-std=c++17",
"-stdlib=libc++",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
{
"configurations": [
{
"name": "Mac",
"includePath": ["${workspaceFolder}/**"],
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
ただ、c_cpp_properties.jsonでエラーが出ていて、これはVSCodeのローカライズ周りのバグっぽい感じがしています。%3A
とは……???
これのせいで、c_cpp_properties.jsonがちゃんと読み込まれていないようなのですが、詳しくはわかってないです。本来ここにinclude pathを指定して動かすもんだと思うのですが、誰かおしえてください。これを消しても関係なく動くし、ターミナルで実行するときにinclude pathの情報が出てこないので絶対おかしいです。
↓ここで言及されてます。
うごいた!
ともあれ動くようになりました。
おわりに
「環境構築で満足して終わってしまう」のはあるあるなので、ちゃんとチョコチョコ触っていきたいなとおもいます。
追記(2022/04/18)
競プロではGCCが主流らしいので、Clangは諦めた方がいいかもしれません(しらんけど)
Discussion