(開発4)複雑なコンパイル手順(サービスプログラム等)

# <u>■概略</u>
オープンソースエンジニア歴30年超の筆者が2023年からIBMiを学びだした学習記録です
サービス・プログラムのように複数回コンパイルの必要な複雑なコンパイルをIFS上のbashスクリプトでまとめることで簡単に実行する手順をまとめました

この記事を実行するにはIFSに[「(開発2)yumパッケージインストール」](https://qiita.com/takami_embomajp/items/5d45b92063e1f237eda8)の環境が必要です  

### <u>■複雑なコンパイル(サービスプログラム)</u>
### ◯コンパイル回数
RPGLE,FFRPGになって、共通関数を別モジュールファイルで外出しできるようになった  
特に後述のFFRPGでCGIではサービスプログラムを使う    
Windowsの*.dll、Linuxの*.soと同様  
ただしそのために複数回のコンパイルが必要になる  

＊**非サービス・プログラム**  
1) メイン.ffrpg --**CRTBNDRPG**--> プログラム  
<BR>

＊**FFRPGのサービス・プログラム**  
1) 共通関数.srvffrpg -**CRTRPGMOD**→ 共通関数モジュール  
2) 共通モジュール -**CRTSRVPGM**→ サービスプログラム    
3) メイン.ffrpg -**CRTRPGMOD**→ メインモジュール  
4) メインモジュール -**CRTPGM**(SRVPGMを指定)→ プログラム  
<BR>

＊**SQLFFRPGのサービス・プログラム**  
1) 共通関数.srvffrpg -**CRTRPGMOD**→ 共通関数モジュール  
2) 共通モジュール -**CRTSRVPGM**→ サービスプログラム    
3) SQL.sqlffrpg -**CRTSQLRPGI**→ メインモジュール  
4) メインモジュール -**CRTPGM**(SRVPGMを指定)→ プログラム  
<BR>

サービスプログラムを作成するのに2回、メインのプログラムを作成するのに2回で合計4回のコンパイルが必要になる
=サービス・プログラムは毎回コンパイルしないとしても、プログラムをコンパイルするのに2回のコンパイルが必要になる
手間なので以下のようなbashを作成して、VSCodeのterminal画面でsshログインしてbashを実行すればコンパイルができる  
VSCodeのterminal画面にコンパイルの実行結果が出力されるのでデバッグに利用するとよい  
なお筆者は老眼なのでWindowsTerminalで文字を大きくして見ています…  

### ◯サービスプログラムをコンパイルするbash
＊プログラムは個人ライブラリ(例:{ユーザ名}LIB)に出力する  
＊ソース・ファイルのDIR変数は自分の環境に合わせて変更する  
＊念のためにコンパイル前にプログラムを削除している
＊SRVPGM="qhttpsvr/qzhbcgi"が標準入出力を使えるようにする  
　IBM標準のサービス・プログラム(CGI編で後述)
 ＊IFSのsystem関数でIBMiのコマンドを呼び出せる  

crtsrvpgm_cgilib.bash  
```
#!/bin/bash
USER=`whoami`
#---
TARGET_LIB=${USER}"LIB"
MOD1="CGILIB"
SRVPGM="qhttpsvr/qzhbcgi"
DIR="/home/${USER}/gitlab/CGIs/QFFRPGSRC"
#---
# CGIモジュール
file=$DIR"/"$MOD1".SRVFFRPG"
target=$TARGET_LIB"/"$MOD1
system "DLTMOD MODULE($target)"
system "CRTRPGMOD MODULE($target) SRCSTMF('$file') TGTCCSID(5035)" 2>&1

# サービスプログラム
system "DLTSRVPGM SRVPGM($target)"
system "CRTSRVPGM SRVPGM($target) MODULE($target) BNDSRVPGM($SRVPGM) EXPORT(*ALL)" 2>&1
```
　   
### ◯メインプログラム(ここではTEST)をコンパイルするbash

crtpgm_TEST.bash  
```
#!/bin/bash
USER=`whoami`
#---
TARGET_LIB=${USER}"LIB"
PGM="TEST"
SRVPGM="CGILIB"
DIR="/home/${USER}/gitlab/CGIs/QFFRPGSRC"
#---
# メインモジュール
file=$DIR"/"$PGM".FFRPG"
target=$TARGET_LIB"/"$PGM
target_srv=$TARGET_LIB"/"$SRVPGM
system "DLTMOD MODULE($target)"
system "CRTRPGMOD MODULE($target) SRCSTMF('$file') TGTCCSID(5035)" 2>&1

# プログラム
system "DLTPGM PGM($target)"
system "CRTPGM PGM($target) MODULE($target) BNDSRVPGM($target_srv)" 2>&1
```

### <u>■複雑なコンパイル(個人開発環境他、各環境用コンパイル)</u>
＊CGI開発では、URLとライブラリを対応させることで、個人開発環境・開発・本番環境を
　分けることができる  
＊gitのブランチとコンパイル先のライブラリを紐づけると各環境用のコンパイルbashが
　できる  

<table border="1" style="border-collapse:collapse;width:800px">
<tr><td>本番URL</td><td>http://{本番ホスト名}:8080/cgi-bin/...</td><td>本番ホストのCGILIBを参照する</td></tr>
<tr><td>開発URL</td><td>http://{開発ホスト名}:8080/cgi-bin/...</td><td>開発ホストのCGILIBを参照す</td></tr> 
<tr><td>個人開発URL</td><td>http://{開発ホスト名}:8080/~{ユーザ名}/cgi-bin/...</td><td>開発ホストの{ユーザ名}LIBを参照す</td></tr> 
</table>
  
### ◯本番URL用コンパイルbash
　本番ホストでコンパイルし、masterブランチの内容を本番ホストのCGILIBにコンパイル
する  

crtpgm_TEST_Prd.bash  
```
#!/bin/bash
USER=`whoami`
#---
TARGET_LIB='CGILIB'
PGM="TEST"
SRVPGM="CGILIB"
DIR="/home/${USER}/gitlab/CGIs/QFFRPGSRC"
#---
# gitでmasterに変更し最新に更新する
git checkout master && git pull origin --ff-only

# メインモジュール
file=$DIR"/"$PGM".SQLFFRPG"
target=$TARGET_LIB"/"$PGM
target_srv=$TARGET_LIB"/"$SRVPGM
system "DLTMOD MODULE($target)"
system "CRTSQLRPGI OBJ($target) SRCSTMF('$file') OBJTYPE(*MODULE) COMPILEOPT('TGTCCSID(5035)') RPGPPOPT(*LVL2)"

# プログラム
system "DLTPGM PGM($target)"
system "CRTPGM PGM($target) MODULE($PGM) BNDSRVPGM($SRVPGM)" 2>&1

# 元のbranchに戻る
git checkout -
```

### ◯開発URL用コンパイルbash
　開発ホストでコンパイルし、developブランチの内容を開発ホストのCGILIBにコンパイル
 する  

crtpgm_TEST_Dev.bash 
```
#!/bin/bash
USER=`whoami`
#---
TARGET_LIB='CGILIB'
PGM="TEST"
SRVPGM="CGILIB"
DIR="/home/${USER}/gitlab/CGIs/QFFRPGSRC"
#---
# gitでdevelopに変更し最新に更新する
git checkout develop && git pull origin --ff-only

# メインモジュール
file=$DIR"/"$PGM".SQLFFRPG"
target=$TARGET_LIB"/"$PGM
target_srv=$TARGET_LIB"/"$SRVPGM
system "DLTMOD MODULE($target)"
system "CRTSQLRPGI OBJ($target) SRCSTMF('$file') OBJTYPE(*MODULE) COMPILEOPT('TGTCCSID(5035)') RPGPPOPT(*LVL2)"

# プログラム
system "DLTPGM PGM($target)"
system "CRTPGM PGM($target) MODULE($PGM) BNDSRVPGM($SRVPGM)" 2>&1

# 元のbranchに戻る
git checkout -
```
### <u>■IBMiのコマンドを実行するbash</u>
上記のようにsystemコマンドでIBMiのコマンドを指定すると、VSCodeからsshログインし
IFSでIBMiのコマンドを実行できる  
プログラムの実行、環境作成のためのファイル(データベース)のコピー、ファイルや
メンバーの一覧など様々なことがbashで実行できる  
筆者はプロジェクトディレクトリの下にcmdディレクトリを作って各種bashを保存している  

例) ls_USERLIB.bash
個人ライブラリのオブジェクト一覧を取得する(UNIXでいうls相当)  
```
#!/bin/bash
USER=`whoami`
TARGET_LIB=${USER}"LIB"
system "DSPOBJD OBJ(${TARGET_LIB}/*ALL) OBJTYPE(*ALL)"
```

実行結果  
```
$ ./ls_USERLIB.bash
オブジェクト記述の表示－基本リスト                                           ページ     1
5770SS1 V7R4M0  190621                                                                            TEST02    24/06/24  23:45:02 JST
ライブラリー . . . . :   {ユーザ名}LIB                                [bﾎﾞ[ﾒｰ ASP装置 . . :   *SYSBAS
                               [bﾎﾞ[ﾒｰ ASP hﾞﾓｰﾎﾟ  . :   *SYSBAS
eﾎﾞﾆﾞｩhn       タイプ     属性                 サイズ     テキスト
PMBKNKOSU      *PGM         RPGLE                    253952     物件別戸数取得CGI
PMBKNSEI       *PGM         RPGLE                    253952     物件商品別請求フラグ取得CGI
STRSSHCLP2     *PGM         CLP                       40960     START SSH CCSID:5035 Run on QGPL/QSTRUP
TEST           *PGM         RPGLE                    155648     CGI TEST using FFRPG
CGILIB         *SRVPGM      RPGLE                    176128
CGILIB         *MODULE      RPGLE                    147456     CGI共通ライブラリ
PMBKNKOSU      *MODULE      RPGLE                    217088     物件別戸数取得CGI
PMBKNSEI       *MODULE      RPGLE                    212992     物件商品別請求フラグ取得CGI
TEST           *MODULE      RPGLE                    126976     CGI TEST using FFRPG
{ユーザ名}OUTQ  *OUTQ                                  16384     {ユーザ名}OUTQ
QCLSRC         *FILE        PF                        32768
TAKAMIJOBD     *JOBD                                   8192     {ユーザ名}JOBD
   * * * * *  リ　ス　ト　の　終　わ　り  * * * * *
```