RHEL8系OSとOracle Database 19cでPro*Cを使う

タイトルにある組み合わせでPro*Cのプログラムをコンパイルする際のメモ。

事前準備

Pro*Cで書かれたプログラムを利用するには、procコマンドでのプリコンパイルとCコンパイラ(gcc)でのコンパイルやリンクが必要。この作業を容易に行うために、Oracleはデモ用のMakefile(demo_proc.mk)を用意しているので今回はこれを使う。

ただ、普通にOracle DatabaseをインストールしてもこのMakefileは入手できない。Oracle Examplesに別途含まれているため、これを追加でインストールする必要がある。

Oracle Database 19c Download for Linux x86-64

Oracle Examplesのインストール

ダウンロードしてきたファイルを展開したら、runInstallerを起動し、既存のORACLE_HOMEに対してインストールする。RHEL8系の場合は、runInstaller起動前に以下の環境変数を設定しないとうまく動かない。

export LANG=C
export CV_ASSUME_DISTID=OL7

RHEL8系の場合、compat-libcap1 の不足に関するエラーが出るが、無視可能。

DatabaseのORACLE_HOMEにすでにパッチが適用されている場合、OUI-10221 が出る。

このまま継続することもできるが、そうすると既存のパッチがインベントリから消えてしまった。例えば、事前に19.18が適用済みの環境にインストールすると、以下のように19.3に戻ってしまう。

[oracle@ol8db19 examples]$ $ORACLE_HOME/OPatch/opatch lspatches
34768559;OCW RELEASE UPDATE 19.18.0.0.0 (34768559)
29517242;Database Release Update : 19.3.0.0.190416 (29517242)

パッチを再適用することはできるのだが、それがソフトウェアの状態として問題ないのかどうかは疑問。Exampleをインストールする必要がある場合は、ベースバージョンをインストールした後、パッチを当てる前に行った方がよいと思われる。

ただ、RHEL8系に19cのDatabaseをインストールするには、そもそもインストール段階で19.7以降のRUを適用する必要があり、本当に正しいインストール方法が何なのかは、サポートに問い合わせる必要があるかもしれない。

インストールが完了すると、demo_proc.mk が作成される。

[oracle@ol8db19 ~]$ ls -l $ORACLE_HOME/precomp/demo/proc/demo_proc.mk
-rw-r--r--. 1 oracle oinstall 7710  4月 16  2019 /u01/app/oracle/product/19.0.0/dbhome_1/precomp/demo/proc/demo_proc.mk

コンパイル実行

適当なPro*Cプログラムと上記Makefileを使ってコンパイルしてみる。

以下のマニュアルにサンプルプログラム(sample1.pc)があるのでこれを使う。

https://docs.oracle.com/cd/F19136_01/lnpcc/precompiler-concepts.html

コマンドとしては以下。

export LD_LIBRARY_PATH=$ORACLE_HOME/lib
make -f $ORACLE_HOME/precomp/demo/proc/demo_proc.mk build OBJS=sample1.o EXE=sample1

ただ、何も設定を変更せず実行しても、まず以下のようなエラーで失敗する。

行33、列10でエラーが発生しました。ファイル/usr/include/stdio.h
#include <stddef.h>
.........1
PCC-S-02015, 挿入ファイルをオープンできません。
行36、列10でエラーが発生しました。ファイル/usr/include/stdio.h
#include <stdarg.h>
.........1

これは、必要なヘッダファイルが読み込めていないことによるものの様子。

$ORACLE_HOME/precomp/admin/pcscfg.cfg の sys_include の設定を変更する必要がある。例えば以下のような設定。

sys_include=($ORACLE_HOME/precomp/public,/usr/include,/usr/include/linux,/usr/include/c++/8,/usr/include/c++/8/tr1,/usr/include/c++/8/x86_64-redhat-linux)

再度コンパイルを試みると、今度は以下のようなエラーで失敗する。

構文エラー(行26、列49、ファイル/usr/include/linux/stddef.h):
行26、列49でエラーが発生しました。ファイル/usr/include/linux/stddef.h
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
................................................1
PCC-S-02014, 記号"..."が見つかりました。 次のうちの1つが入るとき:

   , )
記号"," は続行のために"..."に代わりました。

これについては、コンパイルオプションに PARSE=NONE を追加することで対処可能だった。追加個所は先ほどと同じ、pcscfg.cfg ファイル内。

また、この対処方法をとる場合は以下のようにEXEC SQL BEGIN DECLARE SECTION;と EXEC SQL END DECLARE SECTION;の間でホスト変数の宣言を行うよう変更する必要がある。

EXEC SQL BEGIN DECLARE SECTION;
VARCHAR     username[20];  
varchar     password[40];    
EXEC SQL END DECLARE SECTION;

さらに、以下のエラーで失敗。

/usr/bin/ld: cannot find -lnsl
collect2: error: ld returned 1 exit status

これには以下で対処。

cd /usr/lib64
ln -s libnsl.so.1 libnsl.so

ここまでやって、ようやくコンパイルに成功、実行できるようになる。

[oracle@ol8db19 proctest]$ ./sample1

Connected to ORACLE as user: SCOTT

Enter employee number (0 to quit): 7369


Employee        Salary          Commission
--------        ------          ----------
SMITH           800.00            0.00

Enter employee number (0 to quit):

はっきり言ってRHEL8系でPro*Cを使うのは苦行だし、おそらくOracle側もろくに想定・テストはしていないと思われる。いつまでも枯れた技術にしがみつくのは考え物だと思う。

コメント