MSYS2 VSCode gccオプション設定プログラム

MSYS2で、Rustの開発環境が作れるようになった。
```pacman -S mingw-w64-x86_64-rust```

このRustは、__rustup__が含まれておらず、__cargo__を使い、__MSYS2__の__gcc__コンパイラが使える。

Rustで画面を作ろうとすると、__gtk-rs__が簡単そうだ。
MSYS2で__GTK3__をインストールして
```pacman -S mingw-w84-x86_64-gtk3```
画面設計用の__Glade__も入れておけば、楽だろう。
```pacman -S mingw-w64-x86_64-glade```

cargo側の設定で、__cargo.toml__の__[dependencies]__にGTKを設定すれば、自動的に__crates__(クエート)がダウンロードされる。

しかし、__VSCode__で開発する際は、gccのコンパイルオプションを書くのが面倒くさい。

そこで、MSYS2に付属している、Pythonを使って、__tasks.json__などに書き込むプログラムを書いてみた。

#使い方
(1) main関数の__vscodePath__ を設定する
(2) main関数の__pkgList__ を設定する (ここでは、GTK3)
(3) setProperties関数の__jsonName__ を設定する (ここでは、C/C++用)
(4) setTasks関数の__"-mwindows"__は、win10で、コンソール画面を非表示にできる gccオプションです。必要なければ、この行をコメントアウトしてください。
(5) 後は、実行するだけ (必要なパッケージは、何度 追加して実行しても、自動で重複削除しています)

#解説
MSYS2のtoolchainに付属の__pkg-cofig__コマンドを使って、必要な情報を得て、__tasks.json__と__c_cpp_properties.json__に書き込んでいます。

__pkg-cofig__コマンドは、MSYS2でインストールできる。
```pacman -S mingw-w64-x86_64-toolchain```


このプログラムは、gccコンパイラを使うのであれば、Rust以外でも使える。
パッケージ名を設定すれば、__GTK以外__でも、いろいろ使える

```pyPkgConfig.py
# This Python file uses the following encoding: utf-8
import sys
import subprocess
import os
import json

def getFlags(pkgList):
    ListA = []
    for itemP in pkgList:
        result = subprocess.run(["pkg-config", "--cflags-only-I", itemP], encoding="utf-8", stdout=subprocess.PIPE)
        ListB = result.stdout.split()

        for itemB in ListB:
            itemB = setAbsPath("-I", itemB)
            ListA.append(itemB)

        ListA = uniList([], ListA)

    return ListA

def getLibs(pkgList):
    ListA = []
    for itemP in pkgList:
        result = subprocess.run(["pkg-config", "--libs", itemP], encoding="utf-8", stdout=subprocess.PIPE)
        ListB = result.stdout.split()

        for itemB in ListB:
            itemB = setAbsPath("-L", itemB)
            ListA.append(itemB)

        ListA = uniList([], ListA)

    return ListA

def setAbsPath(head, Path):
    result = Path
    if head == Path[:2]:
        result = Path[2:]
        result = os.path.abspath(result)
        result = head + result

    return result        

def getFullPath(flagsList):
    List = []
    for item in flagsList:
        if item[:2] == "-I":
            fullPath = item[2:]
            if os.path.isdir(fullPath):
                List.append(fullPath)

    List = uniList([], List)
    return List

def getInculdePath(pathList):
    List = []
    for item in pathList:
        fullPath = item
        lowPath = fullPath.lower()
        pos = lowPath.find("/include")
        if pos > 0:
            fullPath = fullPath[:pos + 8]
            fullPath = fullPath + "/**"
            List.append(fullPath)

    List = uniList([], List)
    return List

def uniList(ListA, ListB):
    ListC = []

    ListC = ListA
    for itemB in ListB:
        notFind = True
        for itemA in ListA:
            if itemA == itemB:
                notFind = False
                break

        if notFind:
            ListC.append(itemB)

    return ListC

def setTasks(vscodePath, flagsList, libsList):
    jsonName = "/tasks.json"
    jsonPath = vscodePath + jsonName

    with open(jsonPath, mode="r", encoding="utf-8") as rf:
        jsonFile = json.load(rf)
        for item in jsonFile["tasks"]:
            itemList = item["args"]
            itemList = uniList([], itemList)
            itemList = uniList(itemList, flagsList)
            itemList = uniList(itemList, libsList)
            itemList = uniList(itemList, ["-mwindows"])
            item["args"] = itemList

    with open(jsonPath, mode="w", encoding="utf-8") as wf:
        json.dump(jsonFile, wf, indent=4, ensure_ascii=False)

def setProperties(vscodePath, incsList):
    jsonName = "/c_cpp_properties.json"
    jsonPath = vscodePath + jsonName

    with open(jsonPath, mode="r", encoding="utf-8") as rf:
        jsonFile = json.load(rf)
        for item in jsonFile["configurations"]:
            itemList = item["includePath"]
            itemList = uniList([], itemList)
            itemList = uniList(itemList, incsList)
            item["includePath"] = itemList

    with open(jsonPath, mode="w", encoding="utf-8") as wf:
        json.dump(jsonFile, wf, indent=4, ensure_ascii=False)

def main():
    vscodePath = "C:/work/hello/.vscode"
    pkgList = ["gtk+-3.0"]

    flgsList = getFlags(pkgList)
    libsList = getLibs(pkgList)
    pathList = getFullPath(flgsList)
    incsList = getInculdePath(pathList)
    setTasks(vscodePath, flgsList, libsList)
    setProperties(vscodePath, incsList)

if __name__ == "__main__":
    main()
```

GTK3を入れてみた。

```tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: gcc.exe アクティブなファイルのビルド",
            "command": "C:\\msys64\\mingw64\\bin\\gcc.exe",
            "args": [
                "-g",
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe",
                "-IC:/msys64/mingw64/include/gtk-3.0",
                "-IC:/msys64/mingw64/include/pango-1.0",
                "-IC:/msys64/mingw64/include",
                "-IC:/msys64/mingw64/include/glib-2.0",
                "-IC:/msys64/mingw64/lib/glib-2.0/include",
                "-IC:/msys64/mingw64/include/harfbuzz",
                "-IC:/msys64/mingw64/include/freetype2",
                "-IC:/msys64/mingw64/include/libpng16",
                "-IC:/msys64/mingw64/include/fribidi",
                "-IC:/msys64/mingw64/include/cairo",
                "-IC:/msys64/mingw64/include/lzo",
                "-IC:/msys64/mingw64/include/pixman-1",
                "-IC:/msys64/mingw64/include/gdk-pixbuf-2.0",
                "-IC:/msys64/mingw64/include/atk-1.0",
                "-LC:/msys64/mingw64/lib",
                "-lgtk-3",
                "-lgdk-3",
                "-lz",
                "-lgdi32",
                "-limm32",
                "-lshell32",
                "-lole32",
                "-Wl,-luuid",
                "-lwinmm",
                "-ldwmapi",
                "-lsetupapi",
                "-lcfgmgr32",
                "-lpangowin32-1.0",
                "-lpangocairo-1.0",
                "-lpango-1.0",
                "-lharfbuzz",
                "-latk-1.0",
                "-lcairo-gobject",
                "-lcairo",
                "-lgdk_pixbuf-2.0",
                "-lgio-2.0",
                "-lgobject-2.0",
                "-lglib-2.0",
                "-lintl",
                "-mwindows"
            ],
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": "build",
            "detail": "コンパイラ: C:\\msys64\\mingw64\\bin\\gcc.exe"
        }
    ]
}
```

環境設定により、完全な動作保証は、出来ていません。