Mac mini (M1, 2020) で競プロ環境構築 (VSCode)

前の記事 [mac mini の初期設定](https://qiita.com/cubinglover/items/c35b4cdae52748874af4)に続いてメモ的な記事になります。

参考にした記事です。 
https://qiita.com/OcoToOo/items/f1d0a125327f5659ad52
https://qiita.com/EngTks/items/ffa2a7b4d264e7a052c6

M1 では homebrew によるインストール先に /opt/homebrew/bin が推奨されているので上の記事とは異なる点があります。

##環境
* Mac mini (M1, 2020)
* macOS Bit Sur 11.1

##手順

* VSCode の拡張機能をインストール
    * C/C++ 
    * Code Runner

Mac にはデフォルトのコンパイラとしてclang がありますが gcc を使いたいのでここから少しがんばります。

* gcc をインストール

```zsh
% brew install gcc
```

* gcc を使えるようにする
    * /usr/local の下に bin という名前のフォルダを作ったあと、次のコマンドでその下にシンボリックリンクを貼る。C を使わないなら下のコマンドは不要。

```zsh
% ln -s /opt/homebrew/bin/g++-10 /usr/local/bin/g++
% ln -s /opt/homebrew/bin/gcc-10 /usr/local/bin/gcc
```

* 適当なところにプロジェクト用フォルダを作り .vscode のフォルダをその下にうつす


* 「c_cpp_properties.json」 を設定する
    * <kbd>commmand</kbd> + <kbd>shift</kbd> + <kbd>P</kbd> でコマンドパレットを開く
    * 「C/Cpp: Edit configurations (JSON)」を選択
    * 下のように書き換える

```json:c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Mac",
            "includePath": [
                "${workspaceFolder}/**",
                "/opt/homebrew/include/**"
            ],
            "defines": [],
            "macFrameworkPath": [
                "System/Library/Frameworks"
            ],
            "compilerPath": "/usr/local/bin/g++",
            "cStandard": "c17",
            "cppStandard": "c++17",
            "intelliSenseMode": "gcc-arm64"
        }
    ],
    "version": 4
}
```

* bits/stdc++.hを使えるようにする。
    * シンボリックリンクを貼ります

```zsh
% ln -s /opt/homebrew/Cellar/gcc/10.2.0_2/include/c++/10.2.1/aarch64-apple-darwin20/bits/stdc++.h /opt/homebrew/Cellar/gcc/10.2.0_2/include/c++/10.2.1/bits/stdc++.h
```

しかしこのままだとまだエラーが出てしまいます。

```zsh
cannot open source file "stdalign.h" (dependency of "bits/stdc++.h")
```
c_cpp_properties.jsson の cppStandard を c++17 にしたときだけ起こった (11, 14, 20 では起こらなかった) ので stdalign.h が c++17 で非推奨なことと関係しているかもしれません。まあどうせ使わないヘッダファイルなので stdc++.h を開いてそこだけコメントアウトしました。

##オートフォーマット
保存したときに自動でフォーマットしてくれるようにします。

```zsh
% brew install clang-format
```
プロジェクトのフォルダと同じ階層に .clang-format というテキストファイルを作り各種設定を書き込みます。私は Airdrop で前の設定をうつしました (参考までに貼っておきます) 。

```text
---
Language:        Cpp
# BasedOnStyle:  Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands:   true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
  AfterCaseLabel:  false
  AfterClass:      false
  AfterControlStatement: false
  AfterEnum:       false
  AfterFunction:   false
  AfterNamespace:  false
  AfterObjCDeclaration: false
  AfterStruct:     false
  AfterUnion:      false
  AfterExternBlock: false
  BeforeCatch:     false
  BeforeElse:      false
  IndentBraces:    false
  SplitEmptyFunction: true
  SplitEmptyRecord: true
  SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit:     100
CommentPragmas:  '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: true
DisableFormat:   false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
  - foreach
  - Q_FOREACH
  - BOOST_FOREACH
IncludeBlocks:   Regroup
IncludeCategories:
  - Regex:           '^<ext/.*\.h>'
    Priority:        2
    SortPriority:    0
  - Regex:           '^<.*\.h>'
    Priority:        1
    SortPriority:    0
  - Regex:           '^<.*'
    Priority:        2
    SortPriority:    0
  - Regex:           '.*'
    Priority:        3
    SortPriority:    0
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth:     4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd:   ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
RawStringFormats:
  - Language:        Cpp
    Delimiters:
      - cc
      - CC
      - cpp
      - Cpp
      - CPP
      - 'c++'
      - 'C++'
    CanonicalDelimiter: ''
    BasedOnStyle:    google
  - Language:        TextProto
    Delimiters:
      - pb
      - PB
      - proto
      - PROTO
    EnclosingFunctions:
      - EqualsProto
      - EquivToProto
      - PARSE_PARTIAL_TEXT_PROTO
      - PARSE_TEST_PROTO
      - PARSE_TEXT_PROTO
      - ParseTextOrDie
      - ParseTextProtoOrDie
    CanonicalDelimiter: ''
    BasedOnStyle:    google
ReflowComments:  true
SortIncludes:    true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles:  false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard:        Auto
StatementMacros:
  - Q_UNUSED
  - QT_REQUIRE_VERSION
TabWidth:        8
UseCRLF:         false
UseTab:          Never
...

```

##各種設定
* setting.json に書き込みます。

```json
{
    // general
    "editor.acceptSuggestionOnEnter": "off",
    "editor.fontSize": 11,
    "editor.fontFamily": "Menlo",
    "terminal.integrated.fontFamily": "Monaco",
    "workbench.editor.openPositioning": "last",

    // cpp
    "code-runner.executorMap": {
        "c": "cd $dir && gcc $fileName && $dir$fileNameWithoutExt.out",
        //"c": "cd $dir && gcc $fileName && $dir$fileNameWithoutExt.out < input.txt > output.txt",
        "cpp": "cd $dir && g++ -std=c++17 -W -Wall $fileName && $dir$fileNameWithoutExt.out",
        //"cpp": "cd $dir && g++ -std=c++17 -W -Wall -fsanitize=undefined,address $fileName && $dir$fileNameWithoutExt.out < input.txt > output.txt" ,
    },
    "code-runner.runInTerminal": true,
    "C_Cpp.clang_format_fallbackStyle": "Google",
    "C_Cpp.updateChannel": "Insiders",
    "editor.quickSuggestionsDelay": 0,
    "[cpp]": {
        "editor.formatOnSave": true,
    },
    "explorer.confirmDelete": false,
}
```

完全に私的なメモです。
ファイル入出力もできるようにコメントアウトした状態で置いています。 -fsanitize=undefined,address のコンパイルオプションもつけたかったのですが

```zsh
ld: library not found for -lasan
collect2: error: ld returned 1 exit status
```
というエラーが出るため使えませんでした、悲しい。
最適化はしていません。

```json
"code-runner.runInTerminal": true,
```
はターミナルからの標準入力のために必要です。

```json
"C_Cpp.clang_format_fallbackStyle": "file",
"[cpp]": {
   "editor.formatOnSave": true.
},
```
によって、<kbd>command</kbd>+<kbd>S</kbd>で保存する度にさっき作ったファイルを元にフォーマットされるようになります。

##おわりに
M1 で競プロの環境構築をした記事が見当たらなかったので少し大変でした。メモ用のつもりでしたがどなたかのお役に立つと幸いです。sanitizer を使えるようにできた方、cstdalign.h のエラーが出ないようにできた方はご連絡くださるととても喜びます。

###追記
2020/01/05 軽微な修正
2020/01/12 上に同じ
2020/02/08 c_cpp_properties.json を少しかきかえました