LoginSignup
9
9

More than 3 years have passed since last update.

VS CodeとWSLでopensource COBOLの開発とデバッグをした

Last updated at Posted at 2019-07-17

概要

前回の記事でWSL環境上にopensource COBOL環境を作りました。
今回は、前回環境をベースにVisual Studio Code(以下VSCode)でopensource COBOLの開発とデバッグができるまでをやっていこうと思います。

環境

Windows 10
Visual Studio Code version 1.36.1

VSCodeの導入

まずはインストールしますが、ダウンロードして実行するだけです。

インストール後、C/C++とCOBOLを扱うためプラグインを導入していきます。

  • C/C++

拡張機能をC/C++で検索するとMS提供の開発環境があるので、こちらをいれます。
image.png

  • COBOL

COBOLのシンタックスに対応してくれる非常に有用なプラグインが公開されています。
COBOLで調べるとトップに出てきますので、こちらも導入します。
image.png

開発環境セットアップ

VSCodeは非常にアップデートが早く、公式ドキュメントでも一部違いが吸収されていない部分があります。
しかし、ドキュメント自体はしっかりありますので、基本的には公式ドキュメントを確認すれば問題なくできるかと思います。

ここではopensource COBOL向けにドキュメントを読み替えて構築してきます。

Linux環境を構築

すでにWSL環境はできているとおもいますので、割愛します。
Linux環境上で、プロジェクトのワークスペースとするフォルダを作成していきます。

ubuntuシェルを立ち上げます。
image.png

フォルダを作ります。ここでは公式に則りhelloworldプロジェクトとしてます。

mkdir projects
cd projects
mkdir helloworld

結果はこんな感じになります。

nor51010@MSPC182:~/projects/helloworld$ pwd
/home/nor51010/projects/helloworld

ついでにデバッグ用のGDBをインストールしていきます。
build-essentialはopensource COBOLのインストール時に入れていますので、無視します。

sudo apt-get install gdb

ubuntuではwgereisコマンドで導入できているか確認できます。

nor51010@MSPC182:~/projects/helloworld$ whereis gdb
gdb: /usr/bin/gdb /etc/gdb /usr/share/gdb /usr/share/man/man1/gdb.1.gz

Windows上にワークスペースを作成する

WSLなので、LinuxもWindows上ではありますが、こちらでは普通にワークスペースを作っていきます。
ここも公式に則り、コマンドプロンプトで作成していきます。
コマンドプロンプトで以下コマンドをがしがし打っていきます。

mkdir projects
cd projects
mkdir helloworld
cd helloworld
code .

最後のcode .でカレントディレクトリでVSCodeが起動します。

コンパイラの設定

ここから、各種設定をしていきます。VSCodeでは、各種設定をJSONファイルに記載することで行います。

まず初めに、コンパイラ環境について設定していきます。

ctrl + shift + pでコマンドパレット(というらしいコマンド入力欄)を開いて、「C/C++: Editconfigurations (JSON)」を実行します。
image.png

自動で.vscode/c_cpp_properties.jsonが作成されます。
image.png

ここで設定を変更し、以下のようにWSLのLinux環境に合わせていきます。
各設定の詳細については、公式ドキュメントを参照してください。

c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Win32",
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "/usr/bin/g++",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "gcc-x64",
            "browse": {
                "path": [
                    "${workspaceFolder}"
                ],
                "limitSymbolsToIncludedHeaders": true,
                "databaseFilename": ""
            }
        }
    ],
    "version": 4
}

ビルドタスクの作成

次はビルドタスクを作成していきます。俗にいうコンパイルシェルに近いものになります。
公式ではC/C++用になっているので、ここでCOBOL用のビルドパスも用意してしまいます。

再びコマンドパレットを開いて、次の画像のように選択していきます。
※公式ドキュメントとはコマンド名が異なっていました。

Tasks: Configure Default Build Task
image.png

Create tasks,json file from template
image.png

Others
image.png

.vscode/tasks.jsonができるので、設定は以下のようにしていきます。
今回はプログラムファイル名は固定で指定しています。
"isDefault": trueとしておくことで、ビルド実行時に自動で実行されるため、COBOL側を有効にしておきます。

tasks.json
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "windows": {
        "options": {
            "shell": {
                "executable": "c:\\Windows\\System32\\bash.exe",
                "args": ["-c"]
            }
        }
    },
    "tasks": [
        {
            "label": "build hello world on WSL",
            "type": "shell",
            "command": "g++",
            "args": [
                "-g",
                "-o",
                "/home/nor51010/projects/helloworld/helloworld.out",
                "helloworld.cpp"
            ]
        },
        {
            "label": "build cobol hello world on WSL",
            "type": "shell",
            "command": "cobc",
            "args": [
                "-g",
                "--save-temp=/home/nor51010/projects/helloworld/",
                "-o",
                "/home/nor51010/projects/helloworld/HELLO.so",
                "HELLO.cbl"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

C/C++用のbuild hello world on WSLと、COBOL用にbuild cobol hello world on WSLを追加しています。
違いとしては、コンパイルに使うコマンドをcobcに変更したこと、デバッグで追いかけるソースコードを表示するため、--save-tempオプションを有効にしています。
パスで指定している/home/nor51010の部分は各自のユーザー名設定に読み替えてください。

デバッグ用の設定

最後にデバッガを起動する設定を行っていきます。
ここはメニューからDebug > Add Configuration...を選択します。
選択肢がでてくるのでC++ (GDB/LLDB).を選択すると、.vscode/launch.jsonが作成されます。
今回も同様にC/C++とCOBOL用の設定を行います。

設定ファイルは以下のようにします。

launch.json
{
    // 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": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "/home/nor51010/projects/helloworld/helloworld.out",
            "args": [""],
            "stopAtEntry": true,
            "cwd": "/home/nor51010/projects/helloworld/",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "windows": {
                "MIMode": "gdb",
                "miDebuggerPath": "/usr/bin/gdb",
                "setupCommands": [
                    {
                        "description": "Enable pretty-printing for gdb",
                        "text": "-enable-pretty-printing",
                        "ignoreFailures": true
                    }
                ]
            },
            "pipeTransport": {
                "pipeCwd": "",
                "pipeProgram": "c:\\windows\\sysnative\\bash.exe",
                "pipeArgs": ["-c"],
                "debuggerPath": "/usr/bin/gdb"
            },
            "sourceFileMap": {
                "/mnt/c": "${env:systemdrive}/",
                "/usr": "C:\\Users\\nor51010\\AppData\\Local\\Packages\\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\\LocalState\\rootfs\\usr\\"
            }
        },
        {
            "name": "(gdb) cobol Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "/usr/local/bin/cobcrun",
            "args": ["HELLO"],
            "stopAtEntry": true,
            "cwd": "/home/nor51010/projects/helloworld/",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "windows": {
                "MIMode": "gdb",
                "miDebuggerPath": "/usr/bin/gdb",
                "setupCommands": [
                    {
                        "description": "Enable pretty-printing for gdb",
                        "text": "-enable-pretty-printing",
                        "ignoreFailures": true
                    },
                    {
                        "description": "args",
                        "text": "--args",
                        "ignoreFailures": true
                    }
                ]
            },
            "pipeTransport": {
                "pipeCwd": "",
                "pipeProgram": "c:\\windows\\sysnative\\bash.exe",
                "pipeArgs": ["-c"],
                "debuggerPath": "/usr/bin/gdb"
            },
            "sourceFileMap": {
                "/mnt/c": "${env:systemdrive}/",
                "/usr": "C:\\Users\\nor510101\\AppData\\Local\\Packages\\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\\LocalState\\rootfs\\usr\\"
            }
        }
    ]
}

"sourceFileMap"."/usr"では、WSL環境のフォルダをWindows上から見えるパスで設定します。このパスの取得方法については後ほど。

COBOL側の設定では、"program"cobcrunを、"args"にアプリケーション名を指定しています。
ビルドタスクにて、-xを指定してビルドしている場合は必要ありませんが、SOファイルを作成して、cobcrunから起動する場合は上記のようにする必要があります。

ここまでで環境構築は完了です。

C++の開発

C++コードの追加

まずはC++のコードを作ってみます。メニューのFile > New Fileからhelloworld.cppを作成します。このとき、間違えて.vscodeの下に作るのではなく、ワークスペース直下に作るようにします。

ファイルの内容は公式通りにします。

helloworld.cpp
 #include <iostream>
 #include <vector>
 #include <string>

 using namespace std;

 int main()
 {

     vector<string> msg {"Hello", "C++", "World", "from", "VS Code!", "and the C++ extension!"};

     for (const string& word : msg)
     {
         cout << word << " ";
     }
     cout << endl;
 }

/usrの取得

先ほど作ったプログラムコードで、vector<string> msgをマウスでドラッグして選択したあと、F12キーを押して定義へと移動します。(または右クリックからのGo to Definition
すると、OPEN EDITORSに定義されている箇所のヘッダーファイル等が表示されます。
これを右クリックし、Copy Pathを選択します。

image.png

結果として以下のようなパスがとれます。

C:\Users\nor510101\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs\usr\include\c++\7\bits\stl_vector.h

ここの...\usr\までが必要な部分です。JSONに転記する際には、\をエスケープするのを忘れないようにしましょう。

C++コードのコンパイル

設定したビルドタスクを呼び出します。今回はデフォルトタスクではないため、以下の順番で呼び出します。
コマンドパレットを呼び出します。

Tasks: Run Taskを選択
image.png

build hello world on WSLを選択
image.png

実行するとTERMINALが表示されて結果が表示されます。
image.png

正常に終わっていると、Linux側のコンソールからもファイルが確認できます。

nor51010@MSPC182:~/projects/helloworld$ ls
helloworld.out

C++コードのデバッグ

それでは実際にデバッグしていきます。
左側から虫マークへ移動し、起動するデバッグの種類を上部で選択、実行します。
今回はC/C++のため、(gdb) Launchを選択します。
image.png

緑の右三角を押すとデバッグが開始されます。
image.png

あとはブレークポイントを仕掛けたり、値を確認してみたり、ステップ実行したり、いつも通りのデバッグをおこなうことができます。
image.png

COBOLの開発

前置き(?)が非常に長くなりましたが、本番のopensource COBOLの開発に移ります。

COBOLコードの追加

C/C++の時と同様に、メニューのFile > New FileからHELLO.cblを追加していきます。

HELLO.cbl
       IDENTIFICATION              DIVISION.
       PROGRAM-ID.                 HELLO.
       DATA                        DIVISION.
       WORKING-STORAGE             SECTION.
       PROCEDURE                   DIVISION.
       MAIN-RTN.
           DISPLAY "HELLO WORLD!".
       MAIN-EXT.
           STOP RUN.

プラグインのおかげで、ちゃんとハイライト等がされてたり、OUTLINEが表示されたりいい感じです。
image.png

COBOLコードのコンパイル

今回はデフォルトタスクとして追加していたため、パレットからTasks: Run Build Taskを選択するだけでビルドが実行されます。(またはctrl + shift + B)

問題なくビルドが実行され
image.png

Linux上にもファイルができてます。

nor51010@MSPC182:~/projects/helloworld$ ls
HELLO.so  helloworld.out

また、VSCode上で、HELLO.cなどの一時ファイルが残っていることが確認できます。(詳しくは次で)

COBOLコードのデバッグ

お待ちかねのCOBOLコードのデバッグではありますが、残念ながら、opensource COBOLを直接GDBでデバッグすることはできません。
そのため、先ほど生成したCソースであるHELLO.cをデバッグの対象とします。

HELLO.cを開いて入口あたりでブレークポイントを追加しておきます。
Cのコメントを参考に、DISPLAYのとこでブレークポイントを仕掛けてみます。
image.png

この状態でデバッグを開始していきます。C/C++のときと同様に、虫マークから、今度は(gdb) cobol Launchを選択し、実行していきます。

image.png

起動時に一時停止しますが、cobcrunがないので、さっさと先にすすめます。
image.png

すると、HELLO.cの指定したポイントでとまっていることが確認できます。
image.png

このようにして、COBOLプログラム(からできたC)のデバッグができるようになりました。

次回予告

とりあえず今回は環境構築までは行えたので、次回はCOBOLプログラムをGDBでデバッグする際、自分がよく行うことをまとめていこうと思います。
具体的には、

  • COBOL変数の参照
  • 呼び出し階層の確認
  • etc..

こうご期待

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