[ C++で開発 ] [ TAO CORBA実装 ]

TAO1.6 Linux GCC4.1インストール記録

ACE 5.6.x + TAO 1.6.xを、CentOS 5.x(Linux OS)上にGCC 4.1.2コンパイラでインストールしたときの記録。

ソースから

付録編として、RPMソースパッケージからのビルドを記載しています。

ビルドの準備

ソースの展開

作業ディレクトリとして、$HOME/workを設け、その下に展開します。

torutk$ cd work
work$ bzcat ACE+TAO+CIAO-5.6.5.tar.bz2 | tar xvf -
    :
work$ cd ACE_wrappers
ACE_wrappers$

展開すると、約490MBのサイズとなります。ビルドすると2GB近くになります。

ビルドの実施記録

1. 設定ファイルの作成

config.hの編集

$HOME/work/ACE_wrappers/ace/config.hファイルを新規作成します。

#define ACE_HAS_IPV6
#define ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRS 1
#include "ace/config-linux.h"

IPv6を有効にするため、ACE_HAS_IPV6の定義を追加しています。

Red Hat系OS(Fedora 6/7, RHEL 5)でGCC-4.1.1以降を使用する場合、ACE_GCC_HAS_TEMPLATE_INSTANTIATION_VISIBILITY_ATTRSを定義します。

platform_macros.GNU

$HOME/work/ACE_wrappers/include/makeinclude/platform_macros.GNUファイルを新規作成します。

ssl = 1
ipv6 = 1
zlib = 1
inline = 1
ami = 1
rt_corba = 1
interceptors = 1
corba_messaging = 1
shared_libs_only = 1
probe = 0
profile = 0
debug = 1
optimize = 1
include $(ACE_ROOT)/include/makeinclude/platform_linux.GNU

default.features

$HOME/work/ACE_wrappers/bin/MakeProjectCreator/default.features

ssl=1
zlib=1

メモ1)このdefault.features に ipv6=1 と指定すると、MPCが生成するメイクファイルにCPPFLAGS += -DACE_HAS_IPV6が追加されるようになります。このとき、config.hで#define ACE_HAS_IPV6が定義されていると、再定義の警告がコンパイル時に発生します。そこで、この記事では、config.hに記述するだけとしています。 

2.環境設定

環境変数の設定

環境変数ACE_ROOT
ACE_wrappers$ export ACE_ROOT=`pwd`
ACE_wrappers$ echo $ACE_ROOT
/home/torutk/work/ACE_wrappers
ACE_wrappers$
環境変数TAO_ROOT
ACE_wrappers$ export TAO_ROOT=$ACE_ROOT/TAO
ACE_wrappers$ echo $TAO_ROOT
/home/torutk/work/ACE_wrappers/TAO
ACE_wrappers$
環境変数LD_LIBRARY_PATH
ACE_wrappers$ export LD_LIBRARY_PATH=$ACE_ROOT/lib:$LD_LIBRARY_PATH
ACE_wrappers$ 
環境変数SSL_ROOT
ACE_wrappers$ export SSL_ROOT=/usr/include
ACE_wrappers$
環境変数PATH
ACE_wrappers$ PATH=$ACE_ROOT/bin:$PATH
ACE_wrappers$

3. コンパイル・リンク

makefileの生成

MPCツールでMakefileを生成します。

ACE_wrappers$ cd TAO
TAO$ mwc.pl -type gnuace -genins TAO_ACE.mwc
MPC_ROOT was set to /usr/local/TAO/MPC.
Using .../work/ACE_wrappers/bin/MakeProjectCreator/config/MPC.cfg
CIAO_ROOT was used in the configuration file, but was not defined.
DDS_ROOT was used in the configuration file, but was not defined.
Generating 'gnuace' output using TAO_ACE.mwc
Skipping SSL_FOR_TAO (ssl_for_tao.mpc), it requires ace_for_tao.
Skipping ACE_FOR_TAO (ace_for_tao.mpc), it requires ace_for_tao.
Skipping QoS (qos.mpc), it requires qos.
Skipping ZlibCompressor (ZlibCompressor.mpc), it requires zlib.    
Skipping TAO_FoxResource (FoxResource.mpc), it requires fox.
Skipping tao_mcpp_exe (mcpp.mpc), it requires mcpp.
Skipping TAO_IDL_MCPP (mcpp.mpc), it requires mcpp.
Skipping wxNamingViewer (wxNamingViewer.mpc), it requires wxWindows.
Skipping NamingViewer (NamingViewer.mpc), it requires mfc.
Skipping RTCosScheduling (RTCosScheduling.mpc), it requires dummy_label.
Skipping PSDL (PSDL.mpc), it requires dummy_label.
Skipping PSDL_Datastore (PSDL.mpc), it requires dummy_label.
Skipping PSDL_Parser (PSDL.mpc), it requires dummy_label.
Generation Time: 1m 54s            
TAO$       

ビルド

TAO$ make 2>&1 | tee make.log
 :
TAO$  

makeのログをファイルに保管するため、標準エラー出力を標準出力に振り替えて、teeでコンソール出力しながらファイルに落としています。

4. インストール

ヘッダーファイル、インラインファイル、テンプレートファイル、IDLファイルのインストール

今回は、/usr/local/include の下にACE+TAOのヘッダーファイル等をインストールします。

TAO$ cd ..
ACE_wrappers$ sudo MPC/prj_install.pl /usr/local/include .
    :
ACE_wrappers$
Linux用のconfig-*.hがコピーされないので、手動でコピー

ライブラリファイルのコピー

今回は、/usr/local/lib の下にACE+TAOのライブラリファイルをインストールします。

ACE_wrappers$ sudo MPC/prj_install.pl -s lib_output /usr/local .
    :
ACE_wrappers$

実行ファイルのコピー

今回は、/usr/local/bin の下にACE+TAOのライブラリファイルをインストールします。

ACE_wrappers$ sudo MPC/prj_install.pl -s exe_output /usr/local .
    :
ACE_wrappers$

バージョンファイルのコピー

TAOがどのバージョンかを示すファイルが1つあるので、これをコピーしておきます。

ACE_wrappers$ sudo cp TAO/VERSION /usr/local/include/TAO/
ACE_wrappers$  

MPCのコピー

ACE_wrappers$ sudo cp -r MPC /usr/local
ACE_wrappers$ sudo cp -r bin/MakeProjectCreator/* /usr/local/MPC/
ACE_wrappers$ sudo cp -r TAO/MPC/* /usr/local/MPC
ACE_wrappers$

RPMパッケージの作成

Linuxの多くのディストリビューションでは、ソフトウェアのインストール管理にパッケージ管理システムを使用しています。有名なのはRPMとDEBです。ここでは、RPMパッケージを作成します。

ACE+TAOでは、まだRPMパッケージの作成が確立されていないので、いくつかの方法を紹介します。

  1. Ken Sedgwick氏が公開しているRPMソースパッケージからRPMパッケージを作成する
  2. ゼロからRPMスペックファイルを記述し、RPMパッケージを作成する
  3. 最近のACE+TAO(svnリポジトリ上2008.5.22〜)に付属のrpmbuild用設定ファイルを使ってRPMパッケージを作成する
    (1.のKen Sedgwick氏が貢献しているようです)

1.Ken Sedgwick氏のRPMソースパッケージからのインストール

下記URLにて、RPMソースパッケージを作成・配布しています。

このサイトから、ソースRPMパッケージをダウンロードします。

fc9となっていますが、RHEL 5でもビルドできるとあります。CentOS 5はRHEL 5クローンなので、これをビルドすることとします。気になるIPv6対応ですが、上記URLには以下の記述があるのでIPv6対応でビルドされているようです。

Starting with version 5.5.1-4 I've enabled ACE_HAS_IPIV6 and ACE_USES_IPV4_IPV6_MIGRATION by default.

生成されるパッケージ

上記ソースパッケージをRPMビルドすると、以下のパッケージが生成されます。(ここまで細分化するのでしょうか・・・)

ace
ace-devel
ace-xml
ace-xml-devel
ace-kokyu
ace-kokyu-devel
ace-flreactor
ace-flreactor-devel
ace-qtreactor
ace-qtreactor-devel
ace-tkreactor
ace-tkreactor-devel
ace-xtreactor
ace-xtreactor-devel
tao
tao-devel
tao-cosnaming
tao-cosevent
tao-cosnotification
tao-costrading
tao-rtevent
tao-cosconcurrency
tao-flresource
tao-flresource-devel
tao-qtresource
tao-qtresource-devel
tao-tkresource
tao-tkresource-devel
tao-xtresource
tao-xtresource-devel

ソースRPMからのビルド

これから作業するユーザ環境に、RPMパッケージ作成用の設定をしていなければ、先に設定を行います。設定方法は、CentOS 5 RPMパッケージ作成メモを参照下さい。CentOSでなくてもRPMを使う場合は同じです。

入手したソースRPMパッケージを適当な作業ディレクトリに置き、以下を実行します。

work$ rpmbuild --rebuild --without guilibs ace-tao-5.6.5-5.fc9.src.rpm
    :

トラブルシュート

CentOS 5.2で以下のエラーが発生しました。

コンパイルオプションを見ると、

-fvisibility=hidden
グローバルなシンボルが、デフォルトで他のライブラリから不可視になります。ソースコード中で、__attribute__((visibility("default"))のように明示的に指定したシンボルのみ他のライブラリから可視となります。
-fvisibility-inline-hidden
メンバ関数アドレスが異なるリンク単位で使用されているとき、ポインタをインラインメンバ関数と照合しない。コマンドラインに-fvisibility=hiddenも同時に指定されているとこのオプションは無意味である。
-D_FORTIFY_SOURCE=2
書籍「Binary Hacks(オライリー・ジャパン刊)」の#45で解説のあるバッファオーバーフロー検出機能です。-O1以上の最適化と組み合わせて使用します。=1が基本的な検出で、=2にするとさらに厳しく検出します。
-fstack-protector
スタックに詰まれた関数の戻り値が書き換えられた場合に検出します。カナリア方式

specファイルを見てみましたが、うーん、ちょっと対応は難しそうです。

メモ

インストールするヘッダーファイル等

ヘッダーファイルの中で、*.cppファイルを#includeしていたりするので、これらもインクルードパスにインストールする必要があります。ken氏のソースRPMに含まれるspecファイルには、これらインクルードに必要なファイルを識別するために、GCCでプリプロセッサ処理を行い、インクルードするファイル一覧を取得しています。

BASEHDR=`find \
    ace \
    ACEXML/common \
    ACEXML/parser/parser \
    Kokyu \
    TAO/tao \
    TAO/orbsvcs/orbsvcs \
    -name '*.h' -not -name 'config-*'`
for j in $BASEHDR; do
        echo $j >> rawhdrs.log
        echo '#include <'$j'>' | \
        g++ -I . \
            -I protocols \
            -I TAO \
            -I TAO/orbsvcs \
            -I TAO/orbsvcs/orbsvcs \
            -x c++ - -MM -MF mmout 2>> rawhdrs.log && cat mmout || true;
done > mmraw.list      

2.ソースからRPMパッケージ作成

ということで、ゼロからspecファイルを作成しRPMパッケージ化してみます。

インストール・ディレクトリ構成

まず、インストール後のディレクトリ構成を決めます。ACE+TAOのような開発用ライブラリの場合、インストールする場所によって、コンパイル時・実行時にインクルードパス、ライブラリパスが必要になります。

このようなパスを設定するのはプログラマやプログラムのユーザにとってはかなりわずらわしい作業です。そこで、RPMパッケージ化したライブラリは一般的に、こうしたパス設定をしなくてもいいように、システム・インクルードパスおよびシステム・ライブラリパスにインストールすることが多いようです。

今回は、ACE+TAOもパス設定不要なシステムディレクトリにインストールするパッケージとして作成します。

/usr
  +-- bin
  |     +-- ace_gperf 他の実行コマンド
  +-- sbin
  |     +-- tao-basiclogging 他の実行コマンド(デーモン実行)
  +-- lib
  |     +-- libACE.so (libACE.so.5.6.6へのシンボリックリンク)
  |     +-- libACE.so.5.6.6
  |     +--   ;  (他の共有ライブラリファイルとシンボリックリンクファイル)
  +-- include
  |     +-- ace
  |     |     +-- ACE.h 他のヘッダーファイル
  |     +-- ACEXML
  |     |     +-- common
  |     |     |     +-- ACEXML_Export.h 他のヘッダーファイル
  |     |     +-- parser
  |     |           +-- parser
  |     |                 +-- Parser.h 他のヘッダーファイル
  |     +-- Kokyu
  |     |     +-- Kokyu.h 他のヘッダーファイル
  |     +-- protocols
  |     |     +-- ace
  |     |           +-- HTBP
  |     |                 +-- HTBP_Addr.h 他のヘッダーファイル
  |     +-- tao
  |     |     +-- AnyTypeCode
  |     |     +-- BiDir_GIOP
  |     |     +-- CDS_Framework
  |     |     +-- CDS_ThreadPool
  |     |     +-- CodecFactory
  |     |     +-- Codeset
  |     |     +-- Compression
  |     |     +-- DiffServPolicy
  |     |     +-- DynamicAny
  |     |     +-- DynamicInterface
  |     |     +-- ETCL
  |     |     +-- EndpointPolicy
  |     |     +-- FlResource
  |     |     +-- FoxResource
  |     |     +-- IFR_Client
  |     |     +-- IORTable
  |     |     +-- ImR_Client
  |     |     +-- Messaging
  |     |     +-- Monitor
  |     |     +-- ObjRefTemplate
  |     |     +-- PI
  |     |     +-- PI_Server
  |     |     +-- PortableServer
  |     |     +-- QtResource
  |     |     +-- RTCORBA
  |     |     +-- RTPortableServer
  |     |     +-- RTScheduling
  |     |     +-- SmartProxies
  |     |     +-- Strategies
  |     |     +-- TkResource
  |     |     +-- TransportCurrent
  |     |     +-- TypeCodeFactory
  |     |     +-- Utils
  |     |     +-- Valuetype
  |     |     +-- XtResource
  |     |     +-- diffs
  |     +-- orbsvcs
  |           +-- AV
  |           |     +-- AVStreams.h 他のヘッダーファイル
  |           +-- Concurrency
  |           |     +-- CC_Lock.h 他のヘッダーファイル
  |           +-- CosEvent
  |           |     +-- CEC_ConsumerAdmin.h 他のヘッダーファイル
  |           +-- ESF
  |           |     +-- ESF_Busy_Lock.h 他のヘッダーファイル
  |           +-- Event
  |           |     +-- ECG_Adapters.h 他のヘッダーファイル
  |           +-- FaultTolerance
  |           |     +-- FT_ClientORBInitializer.h 他のヘッダーファイル
  |           +-- FtRtEvent
  |           |     +-- ClientORB
  |           |     |     +-- FTRT_ClientORB_Initializer.h 他のヘッダーファイル
  |           |     +-- EventChannel
  |           |     |     +-- FTEC_ConsumerAdmin.h 他のヘッダーファイル
  |           |     +-- Utils
  |           |           +-- FTEC_Gateway.h 他のヘッダーファイル
  |           +-- HTIOP
  |           |     +-- HTIOP_Acceptor.h 他のヘッダーファイル
  |           +-- IFRService
  |           |     +-- AbstractInterfaceDef_i.h 他のヘッダーファイル
  |           +-- LifeCycle
  |           |     +-- lifecycle_export.h ヘッダーファイル
  |           +-- LoadBalancing
  |           |     +-- LB_CPU_Load_Average_Monitor.h 他のヘッダーファイル
  |           +-- Log
  |           |     +-- BasicLogFactory_i.h 他のヘッダーファイル
  |           +-- Naming
  |           |     +-- Bindings_Iterator_T.h 他のヘッダーファイル
  |           +-- Notify
  |           |     +-- Admin.h 他のヘッダーファイル
  |           +-- PortableGroup
  |           |     +-- GOA.h 他のヘッダーファイル
  |           +-- Property
  |           |     +-- CosPorpertyService_i.h 他のヘッダーファイル
  |           +-- RTCosScheduling
  |           |     +-- RTCosScheduling_ClientScheduler_i.h 他のヘッダーファイル
  |           +-- SSLIOP
  |           |     +-- IIOP_SSL_Acceptor.h 他のヘッダーファイル
  |           +-- Sched
  |           |     +-- Config_Scheduler.h 他のヘッダーファイル
  |           +-- Security
  |           |     +-- CSI_Utils.h 他のヘッダーファイル
  |           +-- Time
  |           |     +-- TAO_TIO.h 他のヘッダーファイル
  |           +-- Trader
  |           |     +-- Constraint_Interpreter.h 他のヘッダーファイル

tao.specファイルの作成

ランタイム・ライブラリと開発用の2つのRPMパッケージを生成します。

RPMパッケージ作成に必要なものを以下に挙げます。

rpmパッケージの作成

$HOME/rpmディレクトリに、RPM作業ディレクトリ構成を作成している場合の例です。

  1. tao.specを、$HOME/rpm/SPECS/に置く
  2. ACE+TAO+CIAO-5.6.6.tar.bz、tao-config.patch および tao-platform-macros.patch を、$HOME/rpm/SOURCES/に置く
  3. $HOME/rpm/SPECSディレクトリで、rpmbuild -ba tao.spec を実行
  4. ビルドの経過を数時間待つ
  5. 以下のパッケージファイルが生成される
    $HOME/rpm/RPMS/i386/tao-1.6.6-1.i386.rpm
    $HOME/rpm/RPMS/i386/tao-devel-1.6.6-1.i386.rpm
    $HOME/rpm/SRPMS/ace+tao-5.6.6-1.src.rpm

SPECファイル記述メモ

イントロダクションセクション
%define ace_version 5.6.6
%define tao_version 1.6.6
%define ciao_version 0.6.6
Summary: The ADAPTIVE Communication Environment (ACE) ant The ACE ORB (TAO)
Name: ace+tao
Version: %{ace_version}
Release: 1
License: DOC License
Group: Development/Libraries
URL: http://www.cs.wustl.edu/~schmidt/TAO.html
Packager: Toru Takahashi <torutk@gmail.com>
Source0: ACE+TAO+CIAO-%{version}.tar.bz2
Patch0: tao-config.patch
Patch1: tao-platform-macros.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: openssl-devel

%description
    : 略

 ビルドするソースアーカイブファイルをSource0で指定しています。ビルド前に作成するファイルが2つ、ace/config.hとinclude/makeinclude/platform_macros.GNU とがありますが、これはpatch形式であらかじめ作成しておき、Patch0およびPatch1で指定します。

 C++ライブラリは、開発時に必要なヘッダーファイルおよびその他ツールと、開発および実行時に必要なライブラリファイルとがあります。Linuxのパッケージシステムでは大半が実行時用のファイルと開発時用のファイルを別々なパッケージで提供している慣習があるので、TAOも同じスタイルで実行時用のパッケージ tao と、開発時用のパッケージ tao-devel と分けて作成します。イントロダクションセクションには、分割するパッケージの宣言も記述します。

%package -n tao
Summary: The ADAPTIVE Communication Environment (ACE) ant The ACE ORB (TAO)
Version: %{tao_version}
Group: Development/Libraries
Requires: openssl

%description -n tao
   : 略
%package -n tao-devel
Summary: Header files and development components for TAO
Version: %{tao_version}
Group: Development/Libraries
Requires: tao = %{tao_version}

%description -n tao-devel
    : 略
prepセクション
%prep
%setup -q -n ACE_wrappers

export ACE_ROOT=`pwd`
export TAO_ROOT=$ACE_ROOT/TAO
export CIAO_ROOT=$TAO_ROOT/CIAO

(cd $ACE_ROOT/ace; rm -f config.h)

%patch0 -p 0
%patch1 -p 0

# optimization enabled
cat >> $ACE_ROOT/include/makeinclude/platform_macros.GNU <<EOF
OCFLAGS = %{optflags}
OCCFLAGS = %{optflags}
EOF

(cd $TAO_ROOT && $ACE_ROOT/bin/mwc.pl -type gnuace TAO_ACE.mwc)

 ソースアーカイブ ACE+TAO+CIAO-5.6.6.tar.bz2を展開すると、通常期待される ACE+TAO+CIAO-5.6.6ディレクトリではなく、ACE_wrappersというディレクトリが生成されます。そこで、%setup に-nでソース展開後 cd するディレクトリ名を明示的に指定しています。
 prepセクション最後にMPCツールでMakefileを生成するために必要な環境変数である、ACE_ROOT、TAO_ROOTおよびCIAO_ROOTを定義します。
 パッチ適用はこのprepセクションで実施します。
 最適化オプションは、実行するマシン・コンパイラによって異なるので、上記パッチで記述せずに、ここでシェルを実行して追記します。
 最後に、MPCツールを使ったMakefile生成を実行します。

buildセクション
%build
export ACE_ROOT=`pwd`
export TAO_ROOT=$ACE_ROOT/TAO
export CIAO_ROOT=$TAO_ROOT/CIAO
export LD_LIBRARY_PATH=$ACE_ROOT/lib

(cd $TAO_ROOT && make)

 prepセクションで定義した環境変数は、他のセクションには引き継がれないので、ここでも環境変数を定義しています。そして、makeを実行します。

installセクション

 記述は省略

ACE+TAOには、インストールという概念がないので、地道にインストールイメージのディレクトリ構成を作成しています。このあたりの記述は、既にACE+TAOのRPMパッケージを提供しているサイトで使われているSPECファイルを参考・流用しています。

cleanセクション
%clean
rm -rf $RPM_BUILD_ROOT
filesセクション
%files -n tao
%defattr(0755,root,root,-)
%{_libdir}/libACE*
%{_libdir}/libKokyu*
%{_libdir}/libTAO*

%doc ACE-INSTALL.html
%doc AUTHORS
%doc COPYING
%doc FAQ
%doc PROBLEM-REPORT-FORM
%doc README
%doc THANKS
%doc VERSION

%doc TAO/COPYING
%doc TAO/PROBLEM-REPORT-FORM
%doc TAO/TAO-INSTALL.html
%doc TAO/VERSION
%doc TAO/README
%files -n tao-devel
%defattr(0755,root,root,-)
%{_bindir}/ace_gperf
%{_bindir}/tao_idl
%{_bindir}/tao_imr
%{_bindir}/tao_ifr
%{_bindir}/tao_catior
%{_bindir}/tao_nsadd
%{_bindir}/tao_nsdel
%{_bindir}/tao_nslist

%{_sbindir}/tao-*

%attr(0644,root,root) %{_mandir}/man1/ace_gperf.1.gz
%attr(0644,root,root) %{_mandir}/man1/tao_idl.1.gz

%defattr(-,root,root,-)
%{_includedir}/ace
%{_includedir}/ACEXML
%{_includedir}/Kokyu
%{_includedir}/tao
%{_includedir}/orbsvcs

3.ACE+TAOのrpmbuild設定からRPMパッケージを作成

ACE_wrappers/rpmbuildディレクトリに含まれる設定ファイルを用いてRPMパッケージを作成します。ACE+TAOで正式対応するこの方法が今後主流になると思います。

以下のように実行するのですが、CentOS 5.2/GCC 4.1.2では、上述のソースRPMからのビルド同様エラーが発生します。

torutk$ cd work
work$ rpmbuild -ta ACE+TAO+CIAO-5.6.5.tar.bz2
    :
work$

メモ

Changes

ACE+TAO 5.6.7

ACE+TAO 5.6.6