VScodeでSTM32プロジェクトのライブラリを共通化するための方法 ​

# ライブラリを共通化するための方法

※自分用メモ　需要がありそうだったら後で清書します。

## やりたい事
CubeMXで生成したファイルと自前のライブラリを共通化しつつ、main.cなどのファイルはプログラムごとに分離したい

## ディレクトリ構成

```
hoge/
　├ .vscode/
　│　├ c_cpp_properties.json
　│　├ launch.json
　│　├ tasks.json
　│　└...
　│
　├ common/      ←自作ライブラリのディレクトリ
　│　├ Inc/
　│　│  └ *.h
　│　└ Src/
　│　   └ *.c
　│
　├ Drivers/     ←CubeMXにより自動生成
　├ Inc/         ←CubeMXにより自動生成
　│
　├ Project1/    ←自分で書くコード1
　│　├ main.c
　│　├ Makefile
　│　├ hogehoge.c
　│　├ hogehoge.h
　│　└...
　│
　├ Project2/    ←自分で書くコード2
　│　├ main.c
　│　├ Makefile
　│　├ hogehoge.c
　│　├ hogehoge.h
　│　└...
　│
　├ Src/        ←CubeMXにより自動生成
　├ .mxproject  ←CubeMXにより自動生成
　├ hoge.ioc    ←CubeMXにより自動生成
　├ Makefile    ←CubeMXにより自動生成
　└ ...
```

## 各種設定  

### CubeMXの設定  
Project Manager -> Code Generator -> Generate peripheral initialaization as a pair of '.c/.h' files per peripheral を有効にする。


### tasks.json  

```json
{
    "version": "2.0.0",
    "type": "shell",
    "echoCommand": true,
    "tasks": [
        {
            "label": "Build project",
            "command": "make",
            "args": [
                "all",
                "GCC_PATH=C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\bin",
                "SRC_PATH=${fileDirname}",
                "-j4"
            ],
            "options": {
                "env": {
                    "PATH": "C:\\tools\\make-3.81-bin\\bin"
                }
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "Clean project",
            "command": "Remove-Item",
            "args": [
                "${fileDirname}\\build",
                "-Recurse"
            ],
            "problemMatcher": [
                "$gcc"
            ],
            "group": "build"
        }
    ]
}
```

### launch.json

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Cortex Debug",
            "cwd": "${workspaceRoot}",
            "executable": "${fileDirname}/build/${workspaceFolderBasename}.elf",
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "openocd",
            "configFiles": [
                "board/st_nucleo_f4.cfg"
            ],
            "preLaunchTask": "Build project",
            "armToolchainPath": "C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\bin\\",
            "serverpath": "C:\\tools\\OpenOCD\\0.10.0-12-20190422-2015\\bin\\openocd.exe"
        }
    ]
}
```

### /Makefile
ルートディレクトリのMakefile

```makefile
#先頭に追加
include $(SRC_PATH)\Makefile

# Build path
BUILD_DIR = $(SRC_PATH)\build

# C sources
C_SOURCES =  \
$(C_SRC) \
$(wildcard common/Src/*.c) \
#C_SOURCES
...
```

変更点
- `include $(SRC_PATH)\Makefile` の追加
- `BUILD_DIR` の変更
- `C_SOURCES` の変更
- `C_SOURCES` からCubeMXによって記述された`C_SOURCES`の削除

### Project1/Makefile  
自分で生成した各プロジェクト内のMakefile

```makefile
C_SRC = \
Project1/main.c \
Project1/hogehoge.c \

BUILD_DIR = $(SRC_PATH)\build
```

### Project1/main.c

自分で作る各プロジェクト内の`main.c`。
CubeMXで自動生成された `Src.main.c`の内容をコピーする。
CubeMXの設定を変更してもこのファイルは更新されないので、設定の変更の度に手動で編集する必要がある。

### .vscode\c_cpp_properties.json  
必須ではないが設定しておくと便利  

```json
{
    "configurations": [
        {
            "name": "STM32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\arm-none-eabi\\include**",
                "C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\lib\\gcc\\arm-none-eabi\\9.2.1\\include"
            ],
            "defines": [
                "USE_HAL_DRIVER",
                "STM32F446xx",
                "__weak=__attribute__((weak))"
            ],
            "compilerPath": "C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\bin\\arm-none-eabi-gcc",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64"
        }
    ],
    "version": 4
}
```  


## 使い方
各プロジェクトのファイルを編集している状態で`Ctrl+Shift+B`を押すとそのプロジェクトのコンパイルが実行される。  
`.elf`などのファイルは各プロジェクトのディレクトリ内に生成される`build`以下に生成される。  

`F5`を押すとデバッグができる。

## 問題点
- どのプロジェクトをコンパイルするかは、編集中のファイルが存在するディレクトリによって決定しているため、共通ファイルを編集中にコンパイルを実行するとエラーになる。  
- 同じ理由で、各プロジェクト以下にディレクトリを追加してファイルを入れた場合、そのファイルを編集中にコンパイルを実行するとエラーになる。  
- main.cが自動更新されないため、いちいち手動で更新するのが面倒
- ルートディレクトリ以下が汚く見栄えが悪い。
- 最初に設定する項目がやや多い。