|
Packit Service |
8bf002 |
<html>
|
|
Packit Service |
8bf002 |
<head>
|
|
Packit Service |
8bf002 |
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
|
|
Packit Service |
8bf002 |
<style> pre {color: navy} tt {color: maroon} </style>
|
|
Packit Service |
8bf002 |
<style> table {border-collapse: separate; border-spacing: 0px; empty-cells: show; background-color: #f0f0ff} </style>
|
|
Packit Service |
8bf002 |
<style> th, td {text-align: left; padding-left: 15px; padding-right: 15px} </style>
|
|
Packit Service |
8bf002 |
</head>
|
|
Packit Service |
8bf002 |
<body>
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
MCPP-PORTING
|
|
Packit Service |
8bf002 |
== How to Port MCPP ==
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
for V.2.7.2 (2008/11)
|
|
Packit Service |
8bf002 |
松井 潔 (kmatsui@t3.rim.or.jp)
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
== 目次 ==
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
1.1. OSや処理系を選ばない portable なソース
|
|
Packit Service |
8bf002 |
1.2. 正確な Standard C モードに加えてその他の各種モードも
|
|
Packit Service |
8bf002 |
1.3. このドキュメントの表記法
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
2. 履歴
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
3. 各処理系に移植する方法:概要
|
|
Packit Service |
8bf002 |
- 3.1. 移植ずみの処理系: compiler-specific-build のコンパイル
|
|
Packit Service |
8bf002 |
3.1.1. どの処理系でも必要な設定
|
|
Packit Service |
8bf002 |
3.1.2. FreeBSD / GCC V.2.*, V.3.*, V.4.*
|
|
Packit Service |
8bf002 |
3.1.3. Linux / GCC V.2.*, V.3.*, V.4.*
|
|
Packit Service |
8bf002 |
3.1.4. Mac OS X / Apple-GCC V.4.*
|
|
Packit Service |
8bf002 |
3.1.5. CygWIN / GCC V.2.*, V.3.*
|
|
Packit Service |
8bf002 |
3.1.6. MinGW / GCC V.3.*
|
|
Packit Service |
8bf002 |
3.1.7. LCC-WIN32 2003-08, 2006-03
|
|
Packit Service |
8bf002 |
3.1.8. Visual C++ V.6.0, 2002, 2003, 2005, 2008
|
|
Packit Service |
8bf002 |
3.1.9. Borland C V.5.*
|
|
Packit Service |
8bf002 |
3.2. DECUS cpp で対応していた処理系
|
|
Packit Service |
8bf002 |
3.3. noconfig.H, configed.H, system.H
|
|
Packit Service |
8bf002 |
3.4. system.c
|
|
Packit Service |
8bf002 |
3.5. ライブラリ関数
|
|
Packit Service |
8bf002 |
3.6. 標準ヘッダ
|
|
Packit Service |
8bf002 |
3.7. makefile と mcpp を使ったリコンパイル
|
|
Packit Service |
8bf002 |
3.8. mcpp をコンパイルできる処理系
|
|
Packit Service |
8bf002 |
3.9. コンパイルする処理系とターゲットの処理系
|
|
Packit Service |
8bf002 |
3.10. MS-DOS 上の処理系、DJGPP 等
|
|
Packit Service |
8bf002 |
3.11. Compiler-independent-build のコンパイル
|
|
Packit Service |
8bf002 |
- 3.12. Subroutine-build のコンパイル
|
|
Packit Service |
8bf002 |
3.12.1. configure する場合
|
|
Packit Service |
8bf002 |
3.12.2. noconfig/*.mak を使う場合
|
|
Packit Service |
8bf002 |
3.12.3. static library と shared library および DLL
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
4. 各処理系に移植する方法:詳細
|
|
Packit Service |
8bf002 |
- 4.1. noconfig.H, configed.H, system.H の設定
|
|
Packit Service |
8bf002 |
- 4.1.1. PART 1 ターゲットシステムの設定: compiler-specific-build
|
|
Packit Service |
8bf002 |
4.1.1.1. 事前定義マクロ
|
|
Packit Service |
8bf002 |
4.1.1.2. Include ディレクトリ等
|
|
Packit Service |
8bf002 |
4.1.1.3. 行番号情報の出力形式その他
|
|
Packit Service |
8bf002 |
4.1.1.4. 処理系の言語仕様に応じた設定
|
|
Packit Service |
8bf002 |
4.1.1.5. Multi-byte character
|
|
Packit Service |
8bf002 |
4.1.1.6. ターゲットとホストに共通の設定
|
|
Packit Service |
8bf002 |
4.1.2. PART 2 ホストシステムの設定
|
|
Packit Service |
8bf002 |
- 4.1.3. PART 3 mcpp の動作仕様の設定
|
|
Packit Service |
8bf002 |
4.1.3.1. 新旧各種の動作モード
|
|
Packit Service |
8bf002 |
4.1.3.2. 動作モードの細部の指定
|
|
Packit Service |
8bf002 |
4.1.3.3. Translation limits の指定
|
|
Packit Service |
8bf002 |
4.2. system.c
|
|
Packit Service |
8bf002 |
4.extra. malloc()
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
5. バグ報告と移植の報告
|
|
Packit Service |
8bf002 |
5.1. バグかどうか?
|
|
Packit Service |
8bf002 |
5.2. malloc() 関連のバグチェック
|
|
Packit Service |
8bf002 |
5.3. バグ報告を
|
|
Packit Service |
8bf002 |
5.4. 移植の報告を
|
|
Packit Service |
8bf002 |
5.5. GCC 以外の処理系での configure の情報を
|
|
Packit Service |
8bf002 |
5.6. データを送ってくれれば移植してみます
|
|
Packit Service |
8bf002 |
5.7. 検証セットによる他の処理系のテスト報告を
|
|
Packit Service |
8bf002 |
5.8. 改善のご意見を
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
6. mcpp の長い道のり
|
|
Packit Service |
8bf002 |
6.1. 構想3日、制作6年
|
|
Packit Service |
8bf002 |
6.2. V.2.3 へ
|
|
Packit Service |
8bf002 |
6.3. 「未踏ソフトウェア創造事業」に採択
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp は Martin Minow の DECUS cpp を元に kmatsui(松井 潔)が全面的に書き直したCプリプロセッサです。mcpp という名前は Matsui cpp という意味です。これはソースで提供するもので、各処理系で使うには、その処理系に合わせてソースに若干の変更を加えた上でコンパイルして、mcpp の実行プログラムを作る必要があります。*1
|
|
Packit Service |
8bf002 |
このドキュメントはソースを各処理系に移植する方法を説明しています。できあがった実行プログラムの動作仕様については、mcpp-manual.html というマニュアルを参照してください。
|
|
Packit Service |
8bf002 |
これらのソース、ドキュメントはすべてオープンソース・ソフトウェアとして提供します。
|
|
Packit Service |
8bf002 |
mcpp は次のような特徴を持っています。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 mcpp V.2.6.3 からはコンパイルずみの何種類かのバイナリ・パッケージも次のサイトで提供するようにした。しかし、このドキュメントではそれには触れない。バイナリ・パッケージについてはこの web page を参照のこと。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
http://mcpp.sourceforge.net/
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Linux, FreeBSD, Windows 等の多くのOSをサポートしている portable なプリプロセッサであり、そのソースは Standard C (ANSI/ISO/JIS C) の処理系でさえあればコンパイルできる広い portability を持っています。ライブラリ関数は古典的なものしか使っていません。
|
|
Packit Service |
8bf002 |
各処理系に移植するためには、多くの場合、ヘッダファイル中のいくつかのマクロ定義を書き替えてコンパイルするだけですみます。最悪の場合でもソースファイルに数十行書き足す程度です。
|
|
Packit Service |
8bf002 |
Multi-byte character(漢字)の処理は日本の EUC-JP, shift-JIS, ISO2022-JP、中国の GB-2312、台湾の Big-5、韓国の KSC-5601 (KSX 1001) に対応しており、UTF-8 も使えます。Shift-JIS, ISO2022-JP, Big-5 の場合、コンパイラ本体が漢字を認識しない処理系では、mcpp がそれを補います。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Standard C 準拠の動作モードのほかに、K&R 1st. のモードや "Reiser" model cpp のモードもあり、さらには自称 post-Standard 仕様のモードまであります。C++ のプリプロセッサとして動作する実行時オプションもあります。
|
|
Packit Service |
8bf002 |
Standard C モードは既存の多くのプリプロセッサと違って、規格を完全に実装しているつもりです。C90, C95, C99, C++98 のすべてに対応しています。Standard C プリプロセスの reference model となるものを目指して作ってあります。これらの規格のバージョンは実行時オプションで指定することができます。*1
|
|
Packit Service |
8bf002 |
ほかにいくつかの有用な拡張機能も持っています。マクロの展開機序や #if 式の評価機序をトレースする #pragma MCPP debug もあります。ヘッダファイルを "pre-preprocess" しておくこともできます。
|
|
Packit Service |
8bf002 |
いくつかの有用な実行時オプションも備えています。ウォーニングのレベルを指定するオプションや、include directory を指定するオプション等です。
|
|
Packit Service |
8bf002 |
ソースにどんな間違いがあっても mcpp は暴走したり見当外れなメッセージを出したりせず、正確でわかりやすい診断メッセージを出して適切な処理をします。移植上で問題となる点についても警告を発します。
|
|
Packit Service |
8bf002 |
高品質でありながら、コードサイズは比較的小さく、メモリ消費も比較的少なくてすみます。
|
|
Packit Service |
8bf002 |
詳細なドキュメントも付属しています。
|
|
Packit Service |
8bf002 |
mcpp の欠点を強いて挙げれば、速度がやや遅いことです。GCC 3.*, 4.* / cc1 に比べると2倍から3倍の時間がかかります。しかし、Borland C 5.5 / cpp と同じくらいの速度で、ヘッダファイルの pre-preprocess の機能を使うともう少し速くなるので、特に遅いほうではありません。正確であること、portable なソースであること、少ないメモリでも動作すること等のためには、この程度の処理時間はやむをえないと考えています。
|
|
Packit Service |
8bf002 |
なお、プリプロセッサの Standard C 準拠度をテストするための検証セットである "Validation Suite for Standard C Preprocessing"、その解説およびそれを使ってテストした各種プリプロセッサの採点簿 cpp-test.html を mcpp とともに公開しています。これを見ると、「Standard C 準拠」と称する既存のプリプロセッサにいかに多くの問題があるかがわかります。*2
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 C言語の規格としては ISO/IEC 9899:1990 (JIS X 3010-1993) が長く使われてきたが、1999 年には ISO/IEC 9899:1999 が採択された。ここでは前者を C90、後者を C99 と呼ぶ。前者は ANSI X3.159-1989 が移行したものなので、一般には ANSI C または C89 と呼ばれることもある。また、ISO/IEC 9899:1990 + Amendment 1995 を C95 と呼ぶことがある。C++ の規格は ISO/IEC 14882:1998 およびその正誤訂正版である ISO/IEC 14882:2003 で、この両者をここでは C++98 と呼ぶ。
|
|
Packit Service |
8bf002 |
*2 この cpp は V.2.2 までは単に cpp と呼んでいたが、一般の cpp と紛らわしいので、V.2.3 からは mcpp と呼ぶことにした。このドキュメントでは V.2.2 までのバージョンも mcpp と呼ぶ。また、このドキュメントの名前は V.2.2 までは cpp.doc としていたが、V.2.3 からは porting.txt と変更し、V.2.5 からは mcpp-porting.txt と変更し、さらに V.2.6.2 からは mcpp-porting.html と変更した。私自身の名前も、V.2.2 までは Psycho としていたが、V.2.3 からは kmatsui に変更した。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
このドキュメントはかつてはテキストファイルでしたが、V.2.6.2 からは html ファイルに変わりました。
|
|
Packit Service |
8bf002 |
このドキュメントでは次のようにフォントを使い分けています。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<tt style="color:navy">source</tt>:
|
|
Packit Service |
8bf002 |
<tt style="color:navy">紺色</tt>の等幅フォントは、
|
|
Packit Service |
8bf002 |
ソースコードの断片およびコマンドラインの入力を示すのに使われます。
|
|
Packit Service |
8bf002 |
<tt>__STDC__</tt>:
|
|
Packit Service |
8bf002 |
<tt style="color:maroon">くり色</tt>の等幅フォントは、標準事前定義マクロおよび何らかのマクロを示すのに使われます。
|
|
Packit Service |
8bf002 |
STD:
|
|
Packit Service |
8bf002 |
Italic フォントは mcpp の <samp>system.H</samp> というソースファイルで定義されるマクロを表します。このドキュメントではこれらの名前を mcpp の種々の設定を表記するためにも使います。これらのマクロは mcpp をコンパイルする時に使われるだけで、mcpp の実行プログラムには存在していないことに注意してください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
DECUS cpp は Martin Minow によって作られ、1984/05 に usenet / net.sources で公開されました。DECUS というのは、DEC Users' Society という DEC 社のコンピュータのユーザグループだそうです。DECUS cpp は DEC の PDP-11 / RT11, PDP-11 / RSX, VAX / VMS, VAX / ULTRIX 等のシステムの当時のC言語処理系のために書かれたCプリプロセッサです。移植性の良い書き方がされているので、他のシステムに移植することは比較的容易で、オリジナル版でもすでに DEC 以外のいくつかの UNIX システムに対応していたようです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
私が mcpp の出発点としたのは、C Users' Group の配付ディスク #243 でした。このソース中にある修正履歴を見ると、原作者による最終修正が 85/06 となっています。その後、原作者がバージョンアップをしているという話は聞きません。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
その後 88/12 までに何人かによって MS-DOS 上のいくつかの処理系にも移植されました。CUG のディスクに入っているのはこのバージョンです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ftp.oreilly.com/pub/examples/imake/DECUS-cpp.tar.gz にもソースがあり、その time-stamp は 93/02 となっていますが、実際の内容は CUG のものより古く、85/01 のものです。なお、これに含まれている Martin Minow の README によると、このプログラムは public domain となっています(この README 自体も 84 または 85 年のものと思われる)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
89/04 に Gigo らによって OS-9/6x09 の Microware C に移植されたものが NIFTY-SERVE / FOS9 / lib 2 に登録されていました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp V.2 は、私がこれらを元に全面的に書き直したものです。移植性をさらに向上させ、Standard C に完全に対応させるため、ソースファイルの分割の仕方も変え、多くのマクロを追加し、関数と変数の追加・分割・書き換え・改名を大幅に行っています。ソースの量もオリジナル版の3倍になっています。ドキュメントと検証セットはすべて、私がまったく新しく書いたものです。
|
|
Packit Service |
8bf002 |
私はこれらをオープンソース・ソフトウェアとして公開します。私自身は DECUS とは何の関係もありません。
|
|
Packit Service |
8bf002 |
なお、オリジナル版には版数が付けられていませんが、mcpp と対比する時には、そちらを DECUS cpp と呼ぶことにします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Standard C のマクロ展開の実装方法については、E. Ream 作の MS-DOS 上の PDS である CPP V.5.3 (1989/08, CUG #319) のソースも参考にしました。そのほか、GCC / cpp の動作や、J. Roskind の JRCPP のドキュメントからもいくつかの示唆を得ています。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp V.2.0 は検証セット V.1.0 とともに 1998/08 に NIFTY SERVE / FC / LIB 2 で公開され、ベクター社のサイトにも転載されました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp V.2.1 は、V.2.0 に C99 1998/08 draft に対応するための修正を加えたものです。検証セット V.1.1 とともに 1998/09 に NIFTY SERVE / FC / LIB 2 およびベクター社のサイトに同時にアプロードされました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp V.2.2 は V.2.1 を 1998/07 に決まった C++ Standard (ISO/IEC 14882:1998) に対応して update したものです。検証セット V.1.2 とともに 1998/11 に NIFTY SERVE / FC / LIB 2 およびベクター社のサイトに同時にアプロードされました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp V.2.3 は V.2.2 を C99 に対応して update し、さらに Linux / GCC 2.95, GCC 3.2 等への移植を追加して、GCC / cpp との互換性を向上させたものです。また、実行時オプションを追加し、一部を変更しました。V.2.3 ではドキュメントの英語版も作成されました。mcpp に付属する検証セットには、GCC / testsuite の一部として自動的にテストを実行することのできる edition が追加されました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp は V.2.3 の開発の途中で、検証セット V.1.3 とともに、情報処理推進機構(IPA) の平成14年度「未踏ソフトウェア創造事業」に新部 裕・プロジェクトマネージャによって採択され、2002/07 - 2003/02 の間は IPA の資金援助と新部PMの助言のもとに開発が進められました。英語版ドキュメントもこのプロジェクトの中で、有限会社・ハイウェル(東京)に翻訳を委託し、それに私が修正とテキスト整形を加えてできあがったものです。このプロジェクトの中で cvs repository と ftp site が用意され、V.2.3 はそこで 2002/08 に pre-release 1 が、2002/12 に pre-release 2 が、2003/02 にリリース版が開発されました。その後、2003/03 に V.2.3 patch 1 が出されています。*1
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp はさらに平成15年度にも「未踏ソフトウェア創造事業」に伊知地 宏 PM によって継続して採択され、2003/06 - 2004/02 の間は IPA の資金援助と伊知地PMの助言のもとに V.2.4 への update 作業が進められました。そして、2003/11 には V.2.4 prerelease が開発されました。このバージョンでは Visual C++ 2003 への移植が追加され、また、mcpp の make を自動化する configure スクリプトが作成されました。なお、mcpp はそれまで明確なライセンス表示をしていませんでしたが、この時から BSD スタイルのライセンス表示をするようになりました。さらに、2004/02 にはリリース版が開発されました。このバージョンでは multi-byte character の処理が拡張されました。また、英語版ドキュメントもハイウェルに翻訳を委託し、日本語版に合わせて update されました。
|
|
Packit Service |
8bf002 |
2004/03 には mcpp V.2.4.1 がリリースされました。これは再帰的マクロの展開方法を修正したものです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
2005/03 には mcpp V.2.5 がリリースされました。このバージョンでは、POST_STANDARD というコンパイル時のモードは STANDARD モードにその実行時オプションの一つとして吸収され、OLD_PREPROCESSOR というコンパイル時の設定は PRE_STANDARD モードの実行時オプションとして吸収されました。再帰的マクロの展開方法は再修正されて完全なものとなりました。また、GCC V.3.3, 3.4 に対応した一方で、16 ビットシステムでの処理系に関するドキュメントの多くを削除しました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
2006/07 には mcpp V.2.6 がリリースされました。このバージョンでは、STANDARD モードと PRE_STANDARD モードが1つの実行プログラムにまとめられました。compiler-independent-build の仕様は処理系に依存しないものに改められました。いくつかの処理系の新しいバージョンへの対応が追加された一方で、pre-C90 の仕様の処理系に移植するための設定は削除されました。MS-DOS 上のコンパイラへの移植も削除されました。ソースの書き換えは大幅なものになりました。今後はソースの追加や細部の修正はあっても、大幅な書き換えは発生しない見込みです。
|
|
Packit Service |
8bf002 |
2006/08 には mcpp V.2.6.1 がリリースされました。このバージョンでは、MinGW への移植が追加されました。そのほか、バグ修正といくつかの比較的小さい改良がありました。
|
|
Packit Service |
8bf002 |
2006/11 には mcpp V.2.6.2 がリリースされました。このバージョンでは、いくつかのバグが修正されるとともに、テキストファイルのドキュメントが html に変更されました。また、Juergen Mueller の contribution による subroutine-build が実装されました。
|
|
Packit Service |
8bf002 |
2007/04 には mcpp V.2.6.3 がリリースされました。このバージョンでは、GCC-specific-build の GCC との互換性が強化されました。Subroutine-build では Greg Kress の contribution によってメモリ上のバッファへの出力が実装されました。また、このバージョンからいくつかのシステム用のバイナリ・パッケージが提供されるようになりました。
|
|
Packit Service |
8bf002 |
2007/05 には mcpp V.2.6.4 がリリースされました。これは V.2.6.3 のバグフィックス版です。
|
|
Packit Service |
8bf002 |
2008/03 には mcpp V.2.7 がリリースされました。
|
|
Packit Service |
8bf002 |
マクロに関する情報をコメントに書き込んで出力する「マクロ注釈モード」(macro notification mode) というものが実装され、コードがかなり増えました。このモードでは、プリプロセス後の出力から元のソース上のマクロの位置を知ることができます。このモードは C/C++ の refactoring tool のために実装されたものです。
|
|
Packit Service |
8bf002 |
また、Mac OS X / Apple-GCC への移植が追加されました。
|
|
Packit Service |
8bf002 |
Visual C++ 2008 への移植もされました。
|
|
Packit Service |
8bf002 |
GCC-specific-build はさらに GCC に近いものになりました。
|
|
Packit Service |
8bf002 |
前バージョンのいくつかのバグも修正されました。
|
|
Packit Service |
8bf002 |
2008/05 には mcpp V.2.7.1 がリリースされました。
|
|
Packit Service |
8bf002 |
これは V.2.7 のバグフィックス版で、前バージョンのいくつかのバグが修正されました。
|
|
Packit Service |
8bf002 |
また、UNIX 系システムのバイナリ・パッケージはすべて shared library または DLL と、それをリンクした実行プログラムを提供するようになりました。
|
|
Packit Service |
8bf002 |
2008/11 には mcpp V.2.7.2 がリリースされました。
|
|
Packit Service |
8bf002 |
これは前バージョンのバグフィックス版です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 「未踏ソフトウェア創造事業」(Exploratory Software Project) の概要は次のところで知ることができる。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
http://www.ipa.go.jp/jinzai/esp/
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp V.2.3 から V.2.5 までは次のところに置いてきたが、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
http://www.m17n.org/mcpp/
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
2006/04 に次のところに移った。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
http://mcpp.sourceforge.net/
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
cpp V.2.2 はベクター社のサイトの次のところにある。dos/prog/c というディレクトリに入れられているが、MS-DOS 専用ではない。ソースは UNIX, WIN32/MS-DOS 等に対応している。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
http://www.vector.co.jp/soft/dos/prog/se081188.html
|
|
Packit Service |
8bf002 |
http://www.vector.co.jp/soft/dos/prog/se081189.html
|
|
Packit Service |
8bf002 |
http://www.vector.co.jp/soft/dos/prog/se081186.html
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
これらのアーカイブファイル中のテキストファイルは、Vector のものは DOS/Windows 系に合わせて、改行コードは [CR]+[LF]、漢字は shift-JIS で encode してある。SourceForge のものは V.2.5 までは UNIX 系に合わせて改行コードは [LF]、漢字は EUC-JP である。V.2.6 からは [CR]+[LF] / shift-JIS の zip 版と [LF] / EUC-JP の tar.gz 版の2種類のアーカイブファイルを置くようにした。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp のソースは5本のヘッダファイルと7本の *.c ファイルからなっています。OSや処理系に依存する部分は <samp>configed.H, noconfig.H, system.H, system.c</samp> の4本のソースにまとめてあります。<samp>configed.H</samp> と <samp>noconfig.H</samp> とは同時に使われることはなく、必ずどちらか一方が使われます。また、ライブラリ関数の一部のCによるソースが <samp>system.c</samp> にあります。したがって、mcpp を何らかの処理系で使うには、それに合わせてこれらのソースファイルに変更を加える必要があります。
|
|
Packit Service |
8bf002 |
mcpp の実行プログラムは build する方法に応じて何種類かあります。
|
|
Packit Service |
8bf002 |
Build する方法には次の2つの次元があります。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
stand-alone-build vs subroutine-build
|
|
Packit Service |
8bf002 |
compiler-independent-build vs compiler-specific-build
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
stand-alone-build: 1つのコマンドとして単体で動くプリプロセッサです。
|
|
Packit Service |
8bf002 |
処理系のコンパイラ・ドライバから呼び出されるものもあります。
|
|
Packit Service |
8bf002 |
subroutine-build: 他のメインプログラムの中からサブルーチンとして
|
|
Packit Service |
8bf002 |
(必要なら繰り返し)呼び出されるものです。
|
|
Packit Service |
8bf002 |
これについては 3.12 で述べます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
compiler-independent-build: 処理系からは独立して動くプリプロセッサです。
|
|
Packit Service |
8bf002 |
実行時オプションなどの仕様は処理系のいかんによらず一定です。
|
|
Packit Service |
8bf002 |
プリプロセスだけすることができますが、処理系の一部として動作することはできません。*1
|
|
Packit Service |
8bf002 |
これは多くの場合、コンパイルさえ通ればすむのでごく簡単です。これについては 3.11 で述べます。*2
|
|
Packit Service |
8bf002 |
compiler-specific-build: 特定の処理系のプリプロセッサを(もし可能なら)代替するためのものです。
|
|
Packit Service |
8bf002 |
その処理系に専用の仕様を持ち、その処理系の専用のディレクトリにインストールされます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
以下の 3.1 - 3.9 ではこの stand-alone の compiler-specific-build を説明します。「GCC 版」「Visual C 用」等と表記しているのはすべて、それぞれ GCC-specific-build, Visual C-specific-build のことです。
|
|
Packit Service |
8bf002 |
mcpp をコンパイルするには2つの方法があります。1つは configure スクリプトを実行して、<samp>config.h</samp> というヘッダファイルと Makefile を自動生成する方法です。あとは単に make; make install とするだけですみます。<samp>configed.H</samp> というヘッダファイルはこの場合に使われます。しかし、configure は UNIX 系のシステムと CygWIN, MinGW でしか使えません。
|
|
Packit Service |
8bf002 |
もう1つは各処理系用の差分ファイルを使ってヘッダファイルに変更を加え、必要ならさらにヘッダファイルを編集した上で、その処理系専用の makefile を使って make する方法です。<samp>noconfig.H</samp> というヘッダファイルはこの場合に使われます。差分ファイルと makefile は noconfig というディレクトリにあります。Configure の使えるシステムでも、ヘッダファイルを直接、編集することで細かい制御をすることができます。しかし、差分ファイルはすでに移植ずみの処理系用のものしかありません。
|
|
Packit Service |
8bf002 |
この章では差分ファイルを使う方法について説明します。Configure については INSTALL を見てください。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 これを V.2.6, V.2.6.1 では stand-alone-build と呼んでいた。
|
|
Packit Service |
8bf002 |
V.2.6.2 で subroutine-build ができたのに伴って、呼称を変更した。
|
|
Packit Service |
8bf002 |
*2 mcpp V.2.6.3 からは mcpp.sourceforge.net で何種類かのバイナリ・パッケージが提供されるようになったが、これはすべて stand-alone の compiler-independent-build である。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
私自身が動かすことのできるC処理系は次のもので、このいずれにも mcpp を移植してあります。すなわち、このソースをコンパイルでき、生成されたプリプロセッサがそれぞれの処理系の上で正しく動作することを確認しています。いずれも CPU は x86 系を使っています。Ubuntu だけが 64 ビット版で、他は 32 ビット版です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
FreeBSD 6.3 GCC V.3.4.6
|
|
Packit Service |
8bf002 |
Vine Linux 4.2 GCC V.2.95.3, V.3.2, V.3.3.6, V.3.4.3, V.4.1.1
|
|
Packit Service |
8bf002 |
Fedora Linux 9 GCC V.4.3.0
|
|
Packit Service |
8bf002 |
Debian LInux 4.0 GCC V.4.1.2
|
|
Packit Service |
8bf002 |
Ubuntu Linux 8.04 / x86_64 GCC V.4.2.3
|
|
Packit Service |
8bf002 |
Mac OS 10.5 GCC V.4.0.1
|
|
Packit Service |
8bf002 |
CygWIN 1.3.10 GCC V.2.95.3
|
|
Packit Service |
8bf002 |
CygWIN 1.5.18 GCC V.3.4.4
|
|
Packit Service |
8bf002 |
MinGW (MSYS 1.0.11)GCC V.3.4.5
|
|
Packit Service |
8bf002 |
WIN32 Visual C++ 2003, 2005, 2008
|
|
Packit Service |
8bf002 |
WIN32 Borland C++ V.5.5J
|
|
Packit Service |
8bf002 |
WIN32 LCC-Win32 2003-08, 2006-03
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
また、他のユーザから提供された Visual C++ V.6.0, Visual C++ 2002, C++Builder 2007 (aka BCC V.5.9) の情報もあり、それらの処理系でコンパイルすることもできます。
|
|
Packit Service |
8bf002 |
これらの処理系で mcpp をコンパイルするための修正は簡単で、<samp>noconfig.H</samp> の数個のマクロ定義を変更するだけです。
|
|
Packit Service |
8bf002 |
noconfig ディレクトリの *.dif というファイルは FreeBSD 6.* / GCC 3.4 用の <samp>noconfig.H</samp> を各処理系用に修正する差分ファイルです。Visual C++ 2005 を例にとると、src ディレクトリで
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
patch -c < ..\noconfig\vc2005.dif
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
とすると、修正されます。patch は UNIX の標準的なコマンドで、Windows 等にも移植されています。patch を使わなくても、差分ファイルを見てエディタで修正してもかまいません。
|
|
Packit Service |
8bf002 |
Include ディレクトリの指定などは、差分ファイルによる修正とは別に、ユーザが自分のシステムに合わせて修正しなければなりません。
|
|
Packit Service |
8bf002 |
こうして修正したソースをコンパイルするための各処理系用の makefile も添付してあります(3.7 参照)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
copy ..\noconfig\visualc.mak Makefile
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
として src ディレクトリにコピーします。
|
|
Packit Service |
8bf002 |
以下の作業も src ディレクトリで行います。作業は特に断らない限り、<samp>noconfig.H</samp> の修正です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
以下のどの処理系でも、compiler-specific-build を作るためには、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define COMPILER INDEPENDENT
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
となっている行を
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define COMPILER MSC
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
等と、その処理系を表すマクロに変更します。そして、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define VERSION_MSG "GCC 3.4"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
という行を次のように適宜書き換えます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define VERSION_MSG "Visual C 2005"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
COMPILER の定義は make のオプションで上書きすることもできます。
|
|
Packit Service |
8bf002 |
例えば、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
nmake COMPILER=MSC
|
|
Packit Service |
8bf002 |
nmake COMPILER=MSC install
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
等とします。差分ファイルで <samp>noconfig.H</samp> を書き換えた場合は、compiler-specific-build のための設定もその処理系用に書き換えられるので、COMPILER は書き換える必要はありません。make で COMPILER を指定すると compiler-specific-build が生成され、指定しないと compiler-independent-build が生成されます。
|
|
Packit Service |
8bf002 |
また、デフォルトの include directory の設定が <samp>noconfig.H</samp> のものと異なる場合は、それを C_INCLUDE_DIR1, C_INCLUDE_DIR2 というマクロに書いておきます。C と異なる C++ 固有の include directory がある場合は、それを CPLUS_INCLUDE_DIR1, CPLUS_INCLUDE_DIR2, CPLUS_INCLUDE_DIR3 に書きます(これらのディレクトリは実行時に環境変数や -I オプションで指定することもできる)。<samp>noconfig.H</samp> で設定するのは処理系固有の include directory です。
|
|
Packit Service |
8bf002 |
Include directory はこのほか、<samp>system.c</samp> でも設定されています。UNIX で言えば <samp>system.c</samp> で設定されるのはいわゆる OS-specific なもの(通常は /usr/include)といわゆる site-specific なもの(通常は /usr/local/include)です。Windows では <samp>system.c</samp> では include directory は何も設定されません。Windows では <samp>noconfig.H</samp> でもデフォルトでは include directory は設定されないので、自分で書くか、または環境変数 INCLUDE, CPLUS_INCLUDE で指定する必要があります。
|
|
Packit Service |
8bf002 |
また、必要なら COMPILER_STD1, COMPILER_STD2 等で定義される組み込みマクロ名も変更します。
|
|
Packit Service |
8bf002 |
Multi-byte character の encoding はデフォルトでは、UNIX 系では EUC-JP、Windows では shift-JIS としていますが、必要なら MBCHAR というマクロを書き換えて他の encoding に変更します(Multi-byte character encoding は実行時に環境変数・オプション・#pragma で変更することもできる)。
|
|
Packit Service |
8bf002 |
処理系によっては shift-JIS や Big5 等の encoding に対応していないため、multi-byte character の中に '\\' と同じ 0x5c の値のバイトがあると tokenization でエラーになることがありますが、そういう処理系では mcpp は特殊な処理をしてコンパイラの欠陥を補います。この設定については 4.1.1.5 を見てください。
|
|
Packit Service |
8bf002 |
添付の makefile については、BINDIR という変数で処理系のバイナリの置かれているディレクトリを書きます。
|
|
Packit Service |
8bf002 |
GCC V.3, V.4 ではプリプロセスがコンパイラ (cc1, cc1plus) に吸収されてしまったので、GCC-specific-build の mcpp を使うには、gcc, g++ の呼び出しを shell-script に置き換えて、mcpp => cc1, mcpp => cc1plus の順序で実行されるようにしなければなりません。添付の makefile では、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
make COMPILER=GNUC
|
|
Packit Service |
8bf002 |
make COMPILER=GNUC install
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
とすると、これが自動的に設定されます。詳細は mcpp-manual.html#3.9.7 を見てください。
|
|
Packit Service |
8bf002 |
ユーザが BINDIR 等への書き込み権限を持っていない場合は、UNIX 系では sudo make COMPILER=GNUC install とします。Windows ではあらかじめ administrator アカウントで、そのディレクトリの permission を変更しておきます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ソースは FreeBSD 6.* 上の GCC (GNU C) V.3.4.* でコンパイルして compiler-independent-build の mcpp を生成する状態になっています。FreeBSD 6.* / GCC V.3.4.* 用の compiler-specific-build を作るには、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define COMPILER INDEPENDENT
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
となっている行を
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define COMPILER GNUC
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
として、コンパイルすればできあがりです。
|
|
Packit Service |
8bf002 |
COMPLIER は make COMPILER=GNUC で上書きすることもできます。
|
|
Packit Service |
8bf002 |
GCC の他のバージョンであれば、VERSION_MSG というマクロおよび
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define COMPILER_EXT_VAL "3"
|
|
Packit Service |
8bf002 |
#define COMPILER_EXT2_VAL "4"
|
|
Packit Service |
8bf002 |
#define COMPILER_CPLUS_VAL "3"
|
|
Packit Service |
8bf002 |
#define GCC_MAJOR_VERSION 3
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
となっているところのバージョン番号を変更します。
|
|
Packit Service |
8bf002 |
COMPILER_EXT_VAL は GCC の major version number を、COMPILER_EXT2_VAL は minor version number をいずれも文字列リテラルで書きます。COMPILER_CPLUS_VAL は <tt>__GNUG__</tt> マクロの値で、COMPILER_EXT_VAL と同じになります。
|
|
Packit Service |
8bf002 |
また、GCC_MAJOR_VERSION は COMPILER_EXT_VAL と同じ値を数値で書きます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
FreeBSD のバージョンが 6.* でなければ、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define SYSTEM_EXT_VAL "6" /* V.5.*: 5, V.6.*:6 */
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
の値を変更します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
さらに include directory が FreeBSD 6.* の標準と違っている場合は、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define CPLUS_INCLUDE_DIR1 "/usr/include/c++/3.4"
|
|
Packit Service |
8bf002 |
#define CPLUS_INCLUDE_DIR2 "/usr/include/c++/3.4/backward"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
となっているディレクトリを変更します。CPLUS_INCLUDE_DIR3, C_INCLUDE_DIR1 の設定も必要かもしれません。
|
|
Packit Service |
8bf002 |
GCC V.2.7-2.95 であれば次のマクロの定義を 199409L に変更します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define STDC_VERSION 0L
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
他の UNIX 系 OS でもコンパイラが GCC であれば、このバージョン表示や、include ディレクトリの設定、OS固有の組み込みマクロの設定、等を変えるだけですむかもしれません(4.1.1 参照)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Linux / GCC ではまず、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define SYSTEM SYS_FREEBSD
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
を
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define SYSTEM SYS_LINUX
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
に変更します。
|
|
Packit Service |
8bf002 |
そして、FreeBSD の場合と同じように、COMPILER, VERSION_MSG, COMPILER_EXT_VAL, COMPILER_EXT2_VAL, COMPILER_CPLUS_VAL, GCC_MAJOR_VERSION CPLUS_INCLUDE_DIR1, CPLUS_INCLUDE_DIR2, C_INCLUDE_DIR1 等のマクロの値を変更します。
|
|
Packit Service |
8bf002 |
GCC 2.* では STDC_VERSION の値を変更し、さらに、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define COMPILER_SP3_VAL "int"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
を
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define COMPILER_SP3_VAL "long int"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
に変更します。
|
|
Packit Service |
8bf002 |
include directory は
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
gcc -xc -E -v /dev/null
|
|
Packit Service |
8bf002 |
g++ -xc++ -E -v /dev/null
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
として確かめてから設定してください。
|
|
Packit Service |
8bf002 |
noconfig ディレクトリの linux_gcc2953.dif, linux_gcc32.dif, linux_gcc336.dif, linux_gcc343.dif は FreeBSD 6.* / GCC V.3.4 用のソースを VineLinux 4.0 / GCC V.2.95.3, V.3.2, V.3.3.6, V.3.4.3 用に修正する差分ファイルです。
|
|
Packit Service |
8bf002 |
また、linux_gcc412.dif は Debian 4.0 / GCC V.4.1.2 用に修正するものです。
|
|
Packit Service |
8bf002 |
それぞれ compiler-specific-build ではさらに COMPILER を変更します。Distribution の標準の GCC と追加インストールした GCC とで include directory がかなり異なる点に注意してください。
|
|
Packit Service |
8bf002 |
なお、glibc の getopt() は POSIX 等の標準のものとは仕様が異なるので、使わずに、<samp>system.c</samp> の mcpp_getopt() を使ってください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Mac OS X では Xcode というパッケージをインストールすると GCC もインストールされます。
|
|
Packit Service |
8bf002 |
/usr/bin に多くの gcc, cc, g++, c++ 等々が現れますが、Intel-Mac の Mac OS X 10.5 (Leopard) の場合は、i686-apple-darwin9-gcc-4.0.1, i686-apple-darwin9-g++-4.0.1 というのがそのマシン用の native code を生成するコンパイラです。
|
|
Packit Service |
8bf002 |
同時にクロスコンパイラもインストールされます。
|
|
Packit Service |
8bf002 |
Intel-Mac の場合は、powerpc-apple-darwin9-gcc-4.0.1, powerpc-apple-darwin9-g++-4.0.1 というのが powerpc 用のバイナリを生成するクロスコンパイラです。
|
|
Packit Service |
8bf002 |
単なる gcc (g++) は gcc-4.0 (g++-4.0) へのリンクで、これはデフォルトでは native compiler として動作しますが、-arch ppc というオプションを付けて起動すると powerpc 用のコンパイラ本体が呼び出されます。
|
|
Packit Service |
8bf002 |
また、/Developer/usr/bin にも /usr/bin と同じコンパイラ一式がインストールされます。
|
|
Packit Service |
8bf002 |
これらはいずれも Apple によって多くの拡張を施された Mac OS X 専用の GCC です。
|
|
Packit Service |
8bf002 |
他のシステムの GCC と異なるのは、1つは framework と呼ばれる独特なディレクトリを system header directory としていることです。
|
|
Packit Service |
8bf002 |
もう1つは Intel-Mac と PowerPC-Mac の双方のバイナリを片方の(1台の)マシン上で生成できるようになっていることです。
|
|
Packit Service |
8bf002 |
さらに双方のバイナリを1つにバンドルしてどちらのマシンでも動くようにした universal binary というものを生成するしくみもあります。
|
|
Packit Service |
8bf002 |
実は gcc-4.0, i686-apple-darwin9-gcc-4.0.1, powerpc-apple-darwin9-gcc-4.0.1 等や、そこから呼び出されるコンパイラ本体である /usr/libexec/gcc/SYSTEM/4.0.1 の cc1, cc1plus 等々もすべて i386 用と ppc 用との universal binary なのです(SYSTEM は i686-apple-darwin9 または powerpc-apple-darwin9)。
|
|
Packit Service |
8bf002 |
これらをそのまま x86 マシンから powerpc マシンに持っていけば、native と cross の関係が逆転した状態で動くようになっているものと思われます。
|
|
Packit Service |
8bf002 |
その上、Intel-Mac は ppc 用のバイナリを x86 のコードに変換しながら自動的に動かすようになっています。
|
|
Packit Service |
8bf002 |
こういうことで、/usr/bin と /Developer/usr/bin に多くの gcc, g++ があり、それらへのリンクがあり、x86 用と ppc 用の libexec ディレクトリがあり、1つの実行プログラムに2つのバイナリがバンドルされており、ppc 用のバイナリが x86 で動き、拡張機能があり、非常に紛らわしいので注意してください。
|
|
Packit Service |
8bf002 |
ここでは Intel-Mac 上の Mac OS X 10.5 (Leopard) を例にとりますが、ppc-Mac では i686 と powerpc (ppc) を入れ替えて読んでください。
|
|
Packit Service |
8bf002 |
また、Mac OS X 10.4 (Tiger) では darwin9 を darwin8 と読み替えてください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ネイティブコンパイラ用の mcpp のインストールは簡単です。
|
|
Packit Service |
8bf002 |
noconfig.H に mac_gcc401_i686.dif の変更を加えると、Intel-Mac 上の Mac OS X 10.5 / GCC 4.0.1 用の設定になります。
|
|
Packit Service |
8bf002 |
Makefile としては mac_osx.mak を使います。
|
|
Packit Service |
8bf002 |
make; sudo make install とすると compiler-independent-build が、make COMPILER=GNUC; sudo make COMPILER=GNUC install とすると GCC-specific-build ができます。
|
|
Packit Service |
8bf002 |
/Developer/usr/bin には通常は PATH は通っていないので、コンパイラは /usr/bin のものが使われます。
|
|
Packit Service |
8bf002 |
Intel-Mac 上で powerpc 用のクロスコンパイラにインストールするには、まず noconfig.H に mac_gcc401_powerpc.dif の変更を加えます。
|
|
Packit Service |
8bf002 |
さらに Makefile を修正します。
|
|
Packit Service |
8bf002 |
compiler-independent-build では NAME, CC, CXX という変数の定義を、いずれも mac_osx.mak 中のコメントにあるように powerpc を含む文字列に変更します。
|
|
Packit Service |
8bf002 |
そして make; sudo make install とします。
|
|
Packit Service |
8bf002 |
これは「クロスコンパイラで」コンパイルされたもので、ppc-Mac 上で動くはずです。
|
|
Packit Service |
8bf002 |
GCC-specific-build では NAME, INCDIR, BINDIR, target_cc, arch を、やはり powerpc (ppc) を含む名前に変更します(CC, CXX は変更しない)。
|
|
Packit Service |
8bf002 |
そして、make COMPILER=GNUC; sudo make COMPILER=GNUC install とします。
|
|
Packit Service |
8bf002 |
これは Intel-Mac 上で動く「クロスコンパイラのための」ものなので、Intel-Mac 上で動きます。
|
|
Packit Service |
8bf002 |
ppcMac 上では、Intel-Mac とは逆に、mac_gcc401_powerpc.dif でネイティブコンパイラ用の設定になり、mac_gcc401_i686.dif でクロスコンパイラ用の設定になるはずです。
|
|
Packit Service |
8bf002 |
クロスコンパイラ用では、上記の Intel-Mac の Makefile の設定で変数に powerpc を含む名前を使ったところを、すべて i686 に変更します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Universal binary を作るには、mac_osx.mak の UFLAGS という変数定義をコメントアウトしている # を外して、これを有効にするだけです。
|
|
Packit Service |
8bf002 |
あとは前節の設定のままです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
CygWIN V.1.3.10 / GCC V.2.95.3 では <samp>noconfig.H</samp> に cyg1310.dif にあるような変更を加えます。
|
|
Packit Service |
8bf002 |
CygWIN V.1.5.18 / GCC V.3.4.4 では cyg1518.dif を使います。
|
|
Packit Service |
8bf002 |
さらに CYGWIN_ROOT_DIRECTORY というマクロを自分の環境に合わせて修正します。これは CygWIN の存在する Windows 上のディレクトリを次の形式で定義するものです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define CYGWIN_ROOT_DIRECTORY "c:/pub/compilers/cygwin"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
path-list 中の大文字・小文字は関係ありません。
|
|
Packit Service |
8bf002 |
他の version でも、VERSION_MSG, CYGWIN_ROOT_DIRECTORY、および include directory のマクロを変更することで対応できるでしょう。
|
|
Packit Service |
8bf002 |
CygWIN は Windows 上のシステムですが、UNIX のファイルシステムがシミュレートされているので、mcpp では UNIX 系システムの GCC とほぼ同様に扱います。Include directories も UNIX 系と同様に組み込まれます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
MinGW / GCC V.3.4.5 では <samp>noconfig.H</samp> に mingw345.dif のような変更を加えます。
|
|
Packit Service |
8bf002 |
さらに MSYS_ROOT_DIRECTORY, MINGW_DIRECTORY という2つのマクロを自分の環境に合わせて修正します。これは次のように、それぞれ /, /mingw ディレクトリの Windows 上の位置に定義するものです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define MSYS_ROOT_DIRECTORY "C:/Program Files/MSYS/1.0"
|
|
Packit Service |
8bf002 |
#define MINGW_DIRECTORY "C:/Program Files/MinGW"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
path-list 中の大文字・小文字は関係ありません。
|
|
Packit Service |
8bf002 |
他の version でも、これらのマクロと VERSION_MSG、および include directory のマクロを変更することで対応できるでしょう。Include directory のマクロ定義は "C:/dir/mingw/include" という絶対パスでも、"/mingw/include" という MinGW 内のディレクトリでもかまいません。
|
|
Packit Service |
8bf002 |
MinGW では symbolic link がサポートされていないので、gcc から GCC-specific-build の mcpp を起動するのに symbolic link が使えません。その上、MinGW / gcc はたとえ cc1 という名前でも shell-script の起動は拒否します。そこで、mcpp のコンパイルでは cc1.exe という実行プログラムを生成して、この中から mcpp.exe または GCC の cc1.exe, cc1plus.exe を呼び出します。
|
|
Packit Service |
8bf002 |
MinGW の GCC-specific-build では include directories は mcpp が設定しますが、compiler-independent-build では設定されないので、環境変数 INCLUDE, CPLUS_INCLUDE で指定する必要があります。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
LCC-WIN32 2003-08-*, 2006-03-* ではそれぞれ lcc0308.dif, lcc0603.dif のような変更を加えます。
|
|
Packit Service |
8bf002 |
他の version では VERSION_MSG マクロを変更します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Visual C++ 2008, 2005, 2003, 2002, 6.0 ではそれぞれ vc2008.dif, vc2005.dif, vc2003.dif, vc2002.dif, vc6.dif のような変更を加えます。もちろん、compiler-specific-build では COMPILER マクロを書き換えるか、nmake -DCOMPILER=MSC オプションで上書きします。
|
|
Packit Service |
8bf002 |
Visual C の他のバージョンでは、VERSION_MSG マクロを変更するほか、<tt>_MSC_VER</tt> および <tt>_MSC_FULL_VER</tt> という組み込みマクロの値をそれぞれ COMPILER_EXT_VAL, COMPILER_EXT2_VAL というマクロの設定を変えることで対応させます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Borland C V.5.5, V.5.9 (C++Builder 2007) / bcc32 ではそれぞれ bc55.dif, bc59.dif のような変更を加えます。
|
|
Packit Service |
8bf002 |
Borland C/C++ の別のバージョンでは VERSION_MSG のほか、<tt>__TURBOC__</tt>, <tt>__BORLANDC__</tt>, <tt>__BCPLUSPLUS__</tt> という組み込みマクロの値をそれぞれ <samp>noconfig.H</samp> の COMPILER_STD2_VAL, COMPILER_EXT_VAL, COMPILER_CPLUS_VAL というマクロの設定を変えることで、対応させます(4.1.1.1 参照)。Digraphs の実装されているバージョンであれば、HAVE_DIGRAPHS の設定を変更します。<tt>__STDC_VERSION__</tt> の実装されているバージョンであれば、STDC_VERSION の設定を変更します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
PDP-11 上の RT-11 / DECUS C, RSX / DECUS C、VAX 上の VMS / VAX-11 C、PDP-11 / UNIX, VAX / ULTRIX の何かのCには DECUS cpp が対応していたようです。MS-DOS 上の Microsoft C, Lattice C のかなり古い版にも対応していたようです。これらはさすがにもう不要と思われ、また私自身がメンテナンスできないので、削除しました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>system.H</samp> は HAVE_CONFIG_H というマクロが non-0 に定義されていると <samp>configed.H</samp> を include し、そうでなければ <samp>noconfig.H</samp> を include します。<samp>configed.H, noconfig.H</samp> には mcpp の設定の PART 1 と PART 2 という部分があり、<samp>system.H</samp> には PART 3 があります。
|
|
Packit Service |
8bf002 |
これらのファイルには、各処理系に移植する時に必要ないくつかのマクロが定義されています。まだ移植されていない処理系に移植するには、PART 1 に数行ないし十数行を書き足します。
|
|
Packit Service |
8bf002 |
PART 1 はOSと target 処理系に依存する定義で、PART 2 は host 処理系に依存する定義、そして PART 3 は mcpp の動作仕様の定義です。
|
|
Packit Service |
8bf002 |
<samp>configed.H, noconfig.H</samp> ではターゲット処理系とホスト処理系とが同じであると仮定していますが、異なる場合は PART 2 を編集する必要があります。
|
|
Packit Service |
8bf002 |
デフォルトの設定と違う設定で移植する場合は、これらのファイルの全体に必ず目を通してください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>configed.H (noconfig.H), system.H</samp> のマクロだけでは吸収できないOSや処理系の差異は、<samp>system.c</samp> で吸収しています。未実装の処理系に移植するには、ここに数十行のソースを書き足すことが必要になるでしょう。
|
|
Packit Service |
8bf002 |
このファイルに記述されているのは、mcpp 起動時のオプション、usage 文、include ディレクトリ、ヘッダファイルやソースファイルをオープンする時のOS固有のディレクトリパスの扱い、#pragma の処理、処理系固有の拡張ディレクティブの処理、等です。ほとんどは target OS と target 処理系の設定です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ライブラリ関数のうち、Standard C にない getopt(), stpcpy() のCによるソースも system.c に書いてあります。mcpp は getcwd(), stat() も使い、UNIX 系では readlink() も使いますが、この3つは OS に依存する関数であり portable に書くことができないので、ここには含めていません。この3つは Standard C にはありませんが、POSIX では規定されています。mcpp の使う低水準関数はこの3つだけです。これらを持たない処理系はないでしょう。
|
|
Packit Service |
8bf002 |
このほか、MSC では stricmp() を、Mac OS X, CygWIN, MinGW では strcasecmp() も使います。*1, *2
|
|
Packit Service |
8bf002 |
ライブラリ関数はいずれも、処理系によって微妙に違う恐れのある仕様に依存した使い方はしていないので、どの処理系のものでもバグさえなければ大丈夫です。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 MinGW 版に限って spawnv() も使われる。
|
|
Packit Service |
8bf002 |
*2 mcpp V.2.6.4 までは lib.c というソースファイルを独立させていたが、その内容が getopt(), stpcpy() の2つだけになったので、V.2.7 から system.c に吸収した。
|
|
Packit Service |
8bf002 |
そして、getopt() は mcpp_getopt() と名前を変えて、リンクのトラブルを解消した。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp のソースでは <samp>stdio.h, ctype.h, errno.h, stdlib.h, string.h, stddef.h, limits.h, time.h, sys/types.h, sys/stat.h</samp> を無条件で include しています。UNIX 系のシステムでは <samp>unistd.h</samp> も include します。これらを持たない処理系はまずないでしょう。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
noconfig ディレクトリにある *.mak は個別の処理系用の makefile です。詳細な設定ができます。make そのものは各処理系に付属のもの、またはそのシステムの標準的なものを想定しています。Visual C では make ではなく nmake を使います。
|
|
Packit Service |
8bf002 |
まず、処理系を xyz とすると、FreeBSD / GCC 以外では
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
patch -c < ../noconfig/xyz.dif
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
として <samp>noconfig.H</samp> を修正します。次に、<samp>noconfig.H</samp> の COMPILER と VERSION_MSG というマクロを書き換えます。さらに自分のシステムに合わせて <samp>noconfig.H</samp> の C_INCLUDE_DIR? 等のマクロを修正します。そして、使用する noconfig/xyz.mak を Makefile にコピーし、ディレクトリ指定等を自分のシステムに合わせて修正した上で、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
make
|
|
Packit Service |
8bf002 |
make install
|
|
Packit Service |
8bf002 |
make clean
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
としてください。
|
|
Packit Service |
8bf002 |
他の処理系では、これらを参考に必要な makefile を書いてください。ソースの依存関係は単純で、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>main.c, directive.c, eval.c, expand.c, support.c, system.c, mbchar.c</samp> は <samp>system.H, internal.H</samp> に依存する
|
|
Packit Service |
8bf002 |
<samp>system.H</samp> は <samp>configed.H (noconfig.H)</samp> に依存する
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
という関係になっています。
|
|
Packit Service |
8bf002 |
<samp>system.H</samp> は <samp>internal.H</samp> より先に include する必要があります。
|
|
Packit Service |
8bf002 |
<samp>internal.H</samp> はさらに <samp>mcpp_lib.h</samp> を include します。
|
|
Packit Service |
8bf002 |
mcpp 自身を使って mcpp をリコンパイルするには、処理系のプリプロセッサのある場所にこの実行プログラムをおきます。例えば GCC V.2.95 であれば、処理系付属の cpp0 を cpp0_gnuc とでも rename しておき、その時に使うものを cpp0 にリンクするのが良いでしょう。すなわち、使うプリプロセッサを mcpp とすると、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ln -sf mcpp cpp0
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
とします。Windows では使うものを cpp32.exe 等にコピーします。*1
|
|
Packit Service |
8bf002 |
mcpp 実行プログラムの名前は
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
make NAME=mcpp
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
等として指定することができます(同じことを BC make では make -DNAME=mcpp とする。UCB make では -D は付けても付けなくても良い。GNU make では -D は付けてはいけない)。
|
|
Packit Service |
8bf002 |
添付の makefile では GCC 用(freebsd.mak, linux.mak, mac_osx.mak, cygwin.mak, mingw.mak)以外は make install ではこまかい処理はしないので、手で補ってください。処理系付属のプリプロセッサは、make install で消してしまうことのないように、あらかじめ別名のファイルにコピーしておいてください。
|
|
Packit Service |
8bf002 |
Visual C, Borland C のような1パスコンパイラで mcpp を使ってリコンパイルする場合は、mcpp の出力ファイルをコンパイラに与えるソースファイルとします(例えば <samp>main.c</samp> というソースをプリプロセスしたものを <samp>main.i</samp> といった名前で出力して、それを cl や bcc32 にコンパイルさせる)。
|
|
Packit Service |
8bf002 |
mcpp を使ってリコンパイルする時は、ヘッダファイルの "pre-preprocess" の機能を使うと、プリプロセス時間が大幅に短縮されます。添付の makefile を使う場合は、UCB make, GNU make, MS nmake では、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
make PREPROCESSED=1
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
BC make では
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
make -DPREPROCESSED=1
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
とすると、自動的にヘッダファイルを pre-preprocess した上でプリプロセスし、それからコンパイルします。LCC-Win32 の make では if 文による場合分けができないので、makefile を修正してリコンパイルする必要があります。修正の内容は makefile そのものにコメントとして書いてあります。
|
|
Packit Service |
8bf002 |
UCB make, GNU make, MS nmake では、MALLOC=KMMALLOC というオプションを付けて make すると、私が書いた malloc() をリンクします。これについては 4.extra を見てください。BC make では同じことを -DKMMALLOC というオプションで指定します。LCC-Win32 make で私の malloc() をリンクするためには、makefile を修正する必要があります。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 FreeBSD では cpp0, cc1 を置く標準のディレクトリは /usr/libexec である。Linux では /usr/lib/gcc-lib/i686-redhat-linux/3.3.2 といったひどく奥深いディレクトリになっている。Linux / GCC では distribution やその version に応じて makefile のこのディレクトリの指定を書き換える必要がある。Include directory もいろいろあるので、確かめなければならない。
|
|
Packit Service |
8bf002 |
また、Linux や FreeBSD では /usr/bin/cpp というものがあるが、これは実際には cpp0 または cc1 を呼び出す。gcc も cpp0 または cc1 を呼び出す。
|
|
Packit Service |
8bf002 |
なお、mcpp-manual.html#3.9.5, mcpp-manual.html#3.9.7 も参照のこと。GCC 3.*, 4.* ではプリプロセスがコンパイラ (cc1, cc1plus) に吸収されてしまったので、mcpp を使うには gcc, g++ の呼び出しを shell-script に置き換える必要がある。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
各処理系に移植するためにはいくつかの設定が必要ですが、mcpp のソースをコンパイルすること自体は、C90 (ANSI C) の仕様を満たしている処理系であれば十分できます。プリプロセッサも同様です。*1, *2
|
|
Packit Service |
8bf002 |
char 型は符号付きでも符号なしでもかまいません。
|
|
Packit Service |
8bf002 |
浮動小数点演算は不要です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
このソースは処理系の微妙な差に影響されないように書いてあります。
|
|
Packit Service |
8bf002 |
もっとも、実際に各処理系でコンパイルするためには、さらにその処理系のバグも回避する必要があります。これはやってみないと何が出てくるかわかりません。私が移植したいくつかの処理系でも、バグであることを確かめその回避方法を見つけるまでにかなりの時間がかかってしまったことが何回かあります。
|
|
Packit Service |
8bf002 |
mcpp が対応していないのは、pre-C90 の処理系のほか、特殊な文字セットを持つ処理系と特殊な CPU です。
|
|
Packit Service |
8bf002 |
EBCDIC には対応していません。
|
|
Packit Service |
8bf002 |
また、整数演算が2の補数でない
|
|
Packit Service |
8bf002 |
CPU にも、対応していません。2の補数でない場合は、#if 式でオーバーフローが発生した時に、おかしくなるかもしれません。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 mcpp V.2.5 までは K&R 1st. の処理系でもコンパイルできるようにしていたが、すでにその必要はなくなっていると思われるので、V.2.6 からは C90 を前提とするように改めた。それに伴ってソースを整理し、このドキュメントも整理した。
|
|
Packit Service |
8bf002 |
*2 V.2.6.2 までは C++ でもコンパイルできるようにしていたが、V.2.6.3 からは C だけとした。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp のソースをコンパイルする処理系(ホスト)と、それによって生成された mcpp の実行プログラムを使う処理系(ターゲット)とは、必ずしも同じである必要はありません。これが違っている場合は、<samp>noconfig.H (configed.H)</samp> の SYSTEM, COMPILER でターゲットを指定し、HOST_SYSTEM, HOST_COMPILER はホストを指定します。また、PART 1 にある諸定義はターゲット用のもので、PART 2 にあるものはホスト用の設定です。<samp>system.c</samp> は主としてターゲット用のものです。
|
|
Packit Service |
8bf002 |
ホストとターゲットの関係には、次のような制限があります。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ホスト処理系はターゲット処理系と同じOS上のものであるか、またはクロスコンパイラであることが必要です。
|
|
Packit Service |
8bf002 |
ホスト処理系とターゲット処理系の文字セットとはともに ASCII であることが必要です。
|
|
Packit Service |
8bf002 |
ホスト処理系の long (unsigned long) はターゲット処理系のそれより範囲が狭くてはいけません。これは Standard C で規定されている条件でもあります。C99 では long long (unsigned long long) について同じことが言えます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
なお、ここで言うホストとターゲットというのは、クロスコンパイラのそれとは関係ありません。クロスコンパイルするのはコンパイラ本体の仕事で、プリプロセッサは原則としてそれには関知しません。mcpp を「クロスコンパイラに」移植する場合は、そのクロスコンパイラがここで言うターゲット処理系です。ホスト処理系としてはクロスコンパイラでないものを使うことになるはずです。mcpp を「クロスコンパイラで」コンパイルする場合は、そのクロスコンパイラがホスト処理系で、クロスコンパイラのターゲットがターゲット処理系となります。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp の過去のバージョンでサポートしていたもののその後、サポートをやめた処理系について述べておきます。
|
|
Packit Service |
8bf002 |
mcpp V.2.2 までは次の処理系をサポートしていましたが、V.2.4 で削除しました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
MS-DOS Turbo C V.2.0
|
|
Packit Service |
8bf002 |
OS-9/6x09 Microware C
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
V.2.5 では次の処理系に関するドキュメントを削除しました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
DJGPP V.1.12 GCC V.2.7.1
|
|
Packit Service |
8bf002 |
MS-DOS LSI C-86 V.3.3 試食版
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
V.2.6 では上の2つの処理系の設定をソースからも削除し、さらに次の処理系に関するドキュメントとソースを削除しました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
MS-DOS Borland C 4.0
|
|
Packit Service |
8bf002 |
Plan 9 pcc
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
V.2.6 ではまた、MS-DOS 上の処理系やメモリの小さいシステムのための設定をすべて削除し、pre-C90 の処理系のための設定も削除しました。
|
|
Packit Service |
8bf002 |
V.2.7.2 では次の処理系のサポートも削除しました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Win32 Borland C 4.0
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
いずれも古い処理系で、ユーザは少なくなっていると思われるものです。
|
|
Packit Service |
8bf002 |
もしそれらの処理系でコンパイルする場合は、compiler-specific-build では多くの設定が必要で簡単ではありませんが、compiler-independent-build なら、その処理系が C90 の仕様をほぼ実装していれば、次のようにして簡単にできます。
|
|
Packit Service |
8bf002 |
DJGPP については、noconfig.H で SYSTEM, HOST_SYSTEM を SYS_WIN32 とし、HAVE_INTMAX_T, HAVE_INTTYPES_H を FALSE とし、system.H で NBUFF をデフォルトの 1/4 くらいに押さえます。*1
|
|
Packit Service |
8bf002 |
MS-DOS 上の処理系については、noconfig.H で SYSTEM, HOST_SYSTEM を SYS_WIN32 とし、HAVE_LONG_LONG を FALSE とし、system.H で NBUFF をデフォルトの 1/16 くらいに、IDMAX をデフォルトの 1/4 くらいに押さえます。さらに directive.c で SBSIZE をデフォルトの 1/8 くらいにします。そして、large memory model でコンパイルします。
|
|
Packit Service |
8bf002 |
ただし、MS-DOS ではメモリの制約が厳しいので、この設定でコンパイルしておいても、長大なマクロ定義の多い場合などは out of memory となることがあります。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 DJGPP / GCC 4.1.0 ではこの設定で mcpp V.2.6.1 をコンパイルできたという報告がある。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp を処理系からは独立して単体で動く compiler-independent 版としてコンパイルすることもできます。これは多くの場合はコンパイルさえ通ればすむので簡単です。Compiler-independent 版は実行時オプションなどの仕様は一定で、処理系依存の部分はありません。OS による相違が少しあるだけです。include directory も UNIX 系で /usr/include, /usr/local/include が設定されるだけなので、あとは環境変数や -I オプションで指定する必要があります。*1, *2
|
|
Packit Service |
8bf002 |
configure が使えるシステムで GCC でコンパイルする場合は単に mcpp のルートディレクトリで
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
./configure; make; make install
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
とすればすみます。この場合は <samp>noconfig.H</samp> ではなく <samp>configed.H</samp> というヘッダファイルが使われます。configure の詳細については INSTALL-jp を参照してください。
|
|
Packit Service |
8bf002 |
configure の使えないシステムでも mcpp がすでに移植されている処理系では、noconfig ディレクトリにある所定の差分ファイルを使って <samp>noconfig.H</samp> を書き換えればすみます。それ以外の変更は必要ありません。makefile も noconfig ディレクトリにあるものをコピーして使います。インストールするディレクトリは makefile 中の BINDIR という変数に書きます。そして、src ディレクトリで make し、make install します。
|
|
Packit Service |
8bf002 |
mcpp がすでに移植されている処理系とバージョンが少し違うだけの場合は、まず近いバージョンの差分ファイルを適用して、それを編集します。
|
|
Packit Service |
8bf002 |
mcpp がまだ移植されていない処理系では、<samp>noconfig.H</samp> を編集して数個のマクロを書き換えたり書き加えたりしてください。まず、HOST_COMPILER を適宜定義します。そして、COMPILER を INDEPENDENT に定義し、SYSTEM をその OS に定義し、VERSION_MSG を適宜定義します。ターゲット処理系は存在しないので、PART 1 には設定することはありません。
|
|
Packit Service |
8bf002 |
PART 2 は mcpp をコンパイルするホスト処理系が Standard C の仕様をどれだけ実装しているか、必要な関数を持っているかによって、設定が違ってきます。最も違うのは long long という型の実装です。Visual C 2002, 2003, 2005 や Borland C 5.5 等では <samp>__int64</samp> という型になっていて、その値を printf() で表示する指定子が VC 2005 以外では j や ll ではなく I64 なので、LL_FORM というマクロを "I64" に定義します。MinGW では long long がありますが、printf() の指定子は I64 です。
|
|
Packit Service |
8bf002 |
Visual C 2008 では long long という型名も使えるようになりました。
|
|
Packit Service |
8bf002 |
stpcpy() という関数のない処理系では、HOST_HAVE_STPCPY を FALSE に定義します。
|
|
Packit Service |
8bf002 |
makefile は noconfig ディレクトリにあるものを参考にして書いてください(3.7 も参照のこと)。
|
|
Packit Service |
8bf002 |
Mac OS X には x86 と powerpc の双方のバイナリを片方のマシンで作れるように、ネイティブコンパイラとクロスコンパイラとが用意されています。
|
|
Packit Service |
8bf002 |
また、それを使って universal binary というものも作れるようになっています。
|
|
Packit Service |
8bf002 |
これは x86 と powerpc 用のバイナリを1本のファイルに束ねたものです。
|
|
Packit Service |
8bf002 |
これらの仕組みは少し複雑なので、3.1.4 に compiler-specific-build と compiler-independent-build の双方についてまとめて説明してあります。
|
|
Packit Service |
8bf002 |
なお、mcpp V.2.6.3 からは sourceforge のサイトで compiler-independent-build の何種類かのバイナリ・パッケージが提供されるようになりましたが、これはそれぞれのパッケージング方式に固有の方法でパッケージングされたものです。そのパッケージング仕様はそれぞれに対応するソース・パッケージ中にある設定ファイルに書かれています。FreeBSD, Linux, Mac OS X 用のものはすべてコンパイルには configure スクリプトを使っています。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 mcpp V.2.4, V.2.5 では compiler-independent 版の仕様は中途半端で、
|
|
Packit Service |
8bf002 |
処理系の仕様に対応した一般のコマンドとしてのプリプロセッサであった。V.2.6 からは処理系から独立した一定の仕様とした。
|
|
Packit Service |
8bf002 |
*2 コンパイルさえ通ればすむと言っても、MS-DOS 上の処理系ではメモリの制約が厳しいので、コンパイルはできても実行すると out of memory になることがある。MS-DOS では translation limits の設定を大幅に押さえてコンパイルしなければならない。3.10 を参照。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp を他の何らかのメインプログラムからサブルーチンとして呼び出すようにコンパイルすることもできます。これは独立したプリプロセッサと同じように、呼び出し元から実行時オプションを受取り、指定された入力ファイルをプリプロセスして出力ファイルに出力して、呼び出し元に戻るものです。必要なら複数のファイルについて繰り返し呼び出すこともできます。しかし、呼び出し元とトークン単位のやりとりをするものではありません。
|
|
Packit Service |
8bf002 |
サブルーチン版では、出力先としてファイルではなくメモリ上のバッファを使うこともできます。
|
|
Packit Service |
8bf002 |
mcpp のソースは、MCPP_LIB というマクロを non-0 に定義してコンパイルすると、サブルーチン版としてコンパイルされるようになっています。サブルーチンの入り口は stand-alone 版の main() が次のように mcpp_lib_main() という名前に変わるだけです。
|
|
Packit Service |
8bf002 |
int mcpp_lib_main( int argc, char ** argv);
|
|
Packit Service |
8bf002 |
GCC では COMPILER マクロは GNUC ではなく INDEPENDENT のままでコンパイルします。GNUC とすると、GCC の libexec ディレクトリにインストールされて GCC から呼び出されるものができてしまうからです。
|
|
Packit Service |
8bf002 |
他方で、Visual C, Borland C, LCC-Win32 等では COMPILER は INDEPENDENT でも MSC, BORLANDC, LCC 等のどちらでもかまいません。これらの処理系ではプリプロセッサが独立していないので、compiler-specific-build でも処理系から呼び出されることはないからです。compiler-specific-build では処理系固有の事前定義マクロやオプションやいくつかの処理系固有の仕様が定義されるので、それがつごうが良いか悪いかでコンパイルの仕方を選びます。
|
|
Packit Service |
8bf002 |
実際にコンパイルする時の手順を configure script を使う場合と noconfig/*.mak ファイルを使う場合とに分けて説明します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
GCC でコンパイルする場合は configure が使えます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
./configure --enable-mcpplib
|
|
Packit Service |
8bf002 |
make
|
|
Packit Service |
8bf002 |
sudo make install
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
とすると、Linux や FreeBSD では compiler-independent 版の libmcpp.a, libmcpp.so.$(SHLIB_VER) が生成されて、デフォルトでは /usr/local/lib にインストールされます。
|
|
Packit Service |
8bf002 |
そして、libmcpp.so および libmcpp.so.0 から libmcpp.so.$(SHLIB_VER) へのリンクが張られます。
|
|
Packit Service |
8bf002 |
*.a は static ライブラリ、*.so は shared ライブラリです。
|
|
Packit Service |
8bf002 |
libmcpp.la というファイルも生成されますが、これは libtool というツールが使うためのものです。
|
|
Packit Service |
8bf002 |
$(SHLIB_VER) は mcpp V.2.6.3 では 0.0.0、V.2.6.4 では 0.0.1、V.2.7 では 0.1.0、V.2.7.1 では 0.2.0、V.2.7.2 では 0.3.0 としています。
|
|
Packit Service |
8bf002 |
mcpp_lib.h, mcpp_out.h というヘッダファイルも /usr/local/include にインストールされます。
|
|
Packit Service |
8bf002 |
これは libmcpp を使うプログラムに必要なものです。
|
|
Packit Service |
8bf002 |
Mac OS X では *.so ではなく *.dylib という名前になります。
|
|
Packit Service |
8bf002 |
また、make で CFLAGS+='-arch i386 -arch ppc' 等と、-arch オプションでいくつかの CPU を指定すると、それらに対応する universal binary のライブラリができます。
|
|
Packit Service |
8bf002 |
さらに -isysroot と -mmacosx-version-min= というオプションを使って、使える Mac OS X のバージョンの範囲を広げることができます。
|
|
Packit Service |
8bf002 |
次の例は、Leopard 上で Tiger と互換の i386 と ppc 用の universal binary の shared ライブラリを作るコマンドです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
make CFLAGS+='-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -arch i386 -arch ppc'
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
CygWIN, MinGW では *.so ではなく *.dll という名前の DLL となります。
|
|
Packit Service |
8bf002 |
CygWIN では libmcpp.a, libmcpp.dll.a, libmcpp.la が /usr/local/lib に、cygmcpp-0.dll が /usr/local/bin にインストールされます。
|
|
Packit Service |
8bf002 |
MinGW もほとんど同じですが、cygmcpp-0.dll が libmcpp-0.dll という名前になります。
|
|
Packit Service |
8bf002 |
DLL を使うときは libmcpp.dll.a をリンクします。
|
|
Packit Service |
8bf002 |
これは import library というものです。
|
|
Packit Service |
8bf002 |
生成された libmcpp.so をリンクする main_libmcpp.c という簡単なソースもコンパイルされて、mcpp という名前で /use/local/bin にインストールされます。
|
|
Packit Service |
8bf002 |
このソースでわかるように、libmcpp を使うには mcpp_lib.h というヘッダファイルを include します。*1
|
|
Packit Service |
8bf002 |
最小限のドキュメントもインストールされます。
|
|
Packit Service |
8bf002 |
testmain.c をコンパイルしてライブラリとリンクすると、もう少し複雑なテストができます。
|
|
Packit Service |
8bf002 |
これは configure ではやらないので、次節の方法で行います。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 libmcpp を使わない stand-alone 版の compiler-independent-build の mcpp も同じ名前で同じディレクトリにインストールされるので、お互いに上書きし合うことになる。
|
|
Packit Service |
8bf002 |
ドキュメントは同じものが同じディレクトリにインストールされるので、これも上書きされる。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
noconfig.H と noconfig ディレクトリの makefile を使う場合は(noconfig.H にその処理系のバージョン用の patch を当てて、makefile の各ディレクトリの設定を自分のシステムに合わせて修正した上で)、次のようにします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
make MCPP_LIB=1 mcpplib
|
|
Packit Service |
8bf002 |
make MCPP_LIB=1 mcpplib_install
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
これは compiler-independent 版のコンパイルですが、GCC 以外では COMPILER=MSC 等として compiler-specific 版でコンパイルしてもかまいません。
|
|
Packit Service |
8bf002 |
Visual C では make ではなく nmake を使います。
|
|
Packit Service |
8bf002 |
LCC-Win32 の make は低機能で if 文による場合分けができないので、makefile を編集しながら make する必要があります。
|
|
Packit Service |
8bf002 |
Linux, FreeBSD, Mac OS X, CygWIN, MinGW では、libmcpp.la が生成されないのとドキュメントがインストールされない以外は、configure して make した場合と同様の結果になります。
|
|
Packit Service |
8bf002 |
Mac OS X では、mac_osx.mak の UFLAGS という変数定義をコメントアウトしている # を外すと、universal binary の設定になります。
|
|
Packit Service |
8bf002 |
Windows 上の処理系ではライブラリの名前は Linux 等とは違って、次のようになります。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
FreeBSD / GCCLinux / GCCMac OS X / GCCCygWIN / GCCMinGW / GCCVisual C, Borland C, LCC-Win32
|
|
Packit Service |
8bf002 |
static librarylibmcpp.alibmcpp.alibmcpp.alibmcpp.alibmcpp.amcpp.lib
|
|
Packit Service |
8bf002 |
shared library or DLLlibmcpp.so.$(SHL_VER)libmcpp.so.$(SHLIB_VER)libmcpp.$(SHLIB_VER).dylibcygmcpp-$(DLL_VER).dlllibmcpp-$(DLL_VER).dllmcpp$(DLL_VER).dll
|
|
Packit Service |
8bf002 |
import library of DLLlibmcpp-$(DLL_VER).dll.alibmcpp-$(DLL_VER).dll.amcpp$(DLL_VER).lib
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
$(SHL_VER) は mcpp V.2.6.3, V.2.6.4 では 0、V.2.7 では 1、V.2.7.1 では 2、V.2.7.2 では 3 です。
|
|
Packit Service |
8bf002 |
$(SHLIB_VER) は mcpp V.2.6.3 では 0.0.0、V.2.6.4 では 0.0.1、V.2.7 では 0.1.0、V.2.7.1 では 0.2.0、V.2.7.2 では 0.3.0 です。
|
|
Packit Service |
8bf002 |
$(DLL_VER) は mcpp V.2.6.3, V.2.6.4, V.2.7, V.2.7.1, V.2.7.2 ともに 0 です。
|
|
Packit Service |
8bf002 |
$(SHLIB_VER) の1ケタ目または $(DLL_VER) が同じ場合は、$(SHLIB_VER) の2ケタ目以降の高いバージョンは低いバージョンの上位互換の関係にあります。
|
|
Packit Service |
8bf002 |
Windows 上の処理系では import library というものも生成されますが、これは DLL を使うためのものです。
|
|
Packit Service |
8bf002 |
DLL を使うときはこの import library をリンクします。
|
|
Packit Service |
8bf002 |
Static library と import library は makefile 中で指定された $(LIBDIR) に、DLL 本体は $(BINDIR) にインストールされます。
|
|
Packit Service |
8bf002 |
DLL を $(BINDIR) にインストールするのは、Windows では DLL は実行プログラムの PATH の通ったディレクトリになければならないからです。
|
|
Packit Service |
8bf002 |
mcpp_lib.h, mcpp_out.h が $(INCDIR) にインストールされます。
|
|
Packit Service |
8bf002 |
ライブラリ版をリンクする main_mcpplib.c もコンパイルされて mcpp という名前で $(BINDIR) にインストールされます。
|
|
Packit Service |
8bf002 |
Windows 上の処理系ではさらに 'DLL_IMPORT=1' というオプションを指定すると、DLL 版の mcpp がリンクされます。
|
|
Packit Service |
8bf002 |
次のようにすると、testmain.c というサンプルをメインプログラムとしてライブラリ版の mcpp がリンクされます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
make testmain
|
|
Packit Service |
8bf002 |
make testmain_install
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
testmain.c にはメモリ上のバッファに出力する例も書いてあります。
|
|
Packit Service |
8bf002 |
メモリに出力するには、メインプログラム中で mcpp_lib.h というヘッダファイルを include して、そこで宣言されている関数を使います。
|
|
Packit Service |
8bf002 |
上記のコマンドに 'OUT2MEM=1' というオプションを付け加えると、testmain.c でこれが有効になります。
|
|
Packit Service |
8bf002 |
<samp>OUT2MEM</samp> というマクロは単に testmain.c のためのもので、mcpp のためにはこのマクロは必要ありません。
|
|
Packit Service |
8bf002 |
ライブラリ版を使うときは、testmain.c を参考に main プログラムを書き、noconfig/*.mak を参考に makefile を書いてください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ライブラリには static library と shared library(Windows 上では dynamically-linking library: DLL)とあります。
|
|
Packit Service |
8bf002 |
Static library は *.o (*.obj) ファイルを集めたもので、コンパイル時にリンクされます。
|
|
Packit Service |
8bf002 |
その変数や関数の global name はそのまま呼び出し側の global name となり、名前の衝突の危険もあります。
|
|
Packit Service |
8bf002 |
このことは、V.2.6.1 まではライブラリ化を予定せずに開発されてきた mcpp にとっては大きな問題となります。
|
|
Packit Service |
8bf002 |
これに対して shared library (DLL) は実行時にリンクされるもので、他のプログラムと共有されます。
|
|
Packit Service |
8bf002 |
Windows 上の DLL ではライブラリの global name は外からは見えず、明示的に export された名前だけが外から import 可能です。
|
|
Packit Service |
8bf002 |
mcpp の場合は mcpp_lib.h にある名前だけを import できます。
|
|
Packit Service |
8bf002 |
UNIX 上の shared library では、一般にはライブラリの global name は外から丸見えで、名前の衝突に神経を使わなければなりません。
|
|
Packit Service |
8bf002 |
しかし、GCC 4.0 以降で mcpp V.2.7 以降をコンパイルした場合は、mcpp_lib.h にある名前以外は外からは見えません。*1, *2
|
|
Packit Service |
8bf002 |
こういうことで、Windows 上では DLL を使い、UNIX 上では GCC 4.0 以降でコンパイルした shared library を使うのが、名前の衝突が起こらず安心です。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 mcpp V.2.7 以降では GCC V.4.0 で実装された #pragma GCC visibility * というディレクティブを使うようにしたためである。
|
|
Packit Service |
8bf002 |
*2 なお、GCC V.4.1 以降には -fstack-protector というオプションがあるが、これは #pragma GCC visibility hidden とは両立しないようである。
|
|
Packit Service |
8bf002 |
したがって、libmcpp のコンパイルでは使えない。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
これらのヘッダファイルに記述されていることの意味は、たいていは読めばわかると思います。コメントも多く書き込んであります。さらに念のために以下に注釈を書いておきます。
|
|
Packit Service |
8bf002 |
設定の PART 1, PART 2 は <samp>noconfig.H (configed.H)</samp> にあり、PART 3 は <samp>system.H</samp> にあります。
|
|
Packit Service |
8bf002 |
まず、ターゲットシステム(mcpp を移植するシステム)とホストシステム(mcpp をコンパイルするシステム)を指定します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>SYSTEM</samp>
|
|
Packit Service |
8bf002 |
ターゲット処理系が動くOSを指定します。OSの名前はこの直後に定義されています。名前が定義されていないOSは適宜定義してください。
|
|
Packit Service |
8bf002 |
<samp>COMPILER</samp>
|
|
Packit Service |
8bf002 |
ターゲット処理系を指定します。コンパイラの名前はこの直後に定義されています。名前が定義されていないコンパイラは適宜定義してください。COMPILER を INDEPENDENT に定義すると、ターゲット処理系の存在しない compiler-independent 版の mcpp が生成されます。この場合は PART 1 の多くの設定が無視されます。
|
|
Packit Service |
8bf002 |
<samp>VERSION_MSG</samp>
|
|
Packit Service |
8bf002 |
-v オプションや usage() 文で表示するためのホスト処理系のバージョン情報を文字列リテラルで書きます。
|
|
Packit Service |
8bf002 |
<samp>HOST_SYSTEM, HOST_COMPILER</samp>
|
|
Packit Service |
8bf002 |
ホストOS、ホスト処理系を指定します。ターゲットと同じ場合は、
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#define HOST_SYSTEM SYSTEM
|
|
Packit Service |
8bf002 |
#define HOST_COMPILER COMPILER
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
としておきます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
SYSTEM, COMPILER の命名には一定の規則がありますが、ソースを見たほうがわかりやすいでしょう。いささか仰々しい形になっていますが、SYSTEM はインクルードファイルのパスリストの形式やOS標準のインクルードディレクトリ等を知るためにしか使われていないので、あまり考える必要はありません。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>SYSTEM_OLD, SYSTEM_STD1, SYSTEM_STD2, SYSTEM_EXT, SYSTEM_EXT2, COMPILER_OLD, COMPILER_STD1, COMPILER_STD2, COMPILER_EXT, COMPILER_EXT2</samp>
|
|
Packit Service |
8bf002 |
mcpp で predefine する処理系固有のマクロの名前を文字列リテラルで指定します。不要なものは定義しないでおきます(0 個のトークンに定義してはいけない)。*_OLD で生成されるのは '_' (underline) で始まらない古い流儀のマクロで、これらは mcpp 実行時に -S <n> オプションで <n> に 1 以上を指定すると predefine されません(ただし、GCC-specific-build の STD モードでは、-ansi または -std=iso* オプションが指定されない限り、これらのマクロも定義される)。
|
|
Packit Service |
8bf002 |
*_STD?, *_EXT, *_EXT2 では必ず _ で始まるマクロ名を指定します。*_STD1 は <samp>__</samp> で始まるもので、*_STD2 は <samp>__</samp> で始まって <samp>__</samp> で終わるものです。SYSTEM_EXT, SYSTEM_EXT2, COMPILER_STD1, COMPILER_STD2, COMPILER_EXT, COMPILER_EXT2 ではそのマクロの値も SYSTEM_EXT_VAL, SYSTEM_EXT2_VAL, COMPILER_STD1_VAL, COMPILER_STD2_VAL, COMPILER_EXT_VAL, COMPILER_EXT2_VAL で指定します。これは整数を "" で囲んだ文字列リテラルで指定します。0 個のトークンに展開されるマクロは "" と定義します。指定されなければ、そのマクロの値は 1 になります。その他の predefined マクロ(SYSTEM_OLD, SYSTEM_STD1, SYSTEM_STD2, COMPILER_OLD で指定されるもの)はすべて 1 の値を持ちます。
|
|
Packit Service |
8bf002 |
<samp>SYSTEM_SP_OLD, SYSTEM_SP_STD</samp>
|
|
Packit Service |
8bf002 |
処理系固有の特殊な事前定義マクロの名前を文字列リテラルで書き、その値を SYSTEM_SP_OLD_VAL, SYSTEM_SP_STD_VAL で定義します。
|
|
Packit Service |
8bf002 |
<samp>COMPILER_SP1, COMPILER_SP2, COMPILER_SP3</samp>
|
|
Packit Service |
8bf002 |
処理系固有の特殊な事前定義マクロの名前を文字列リテラルで書き、その値を COMPILER_SP1_VAL, COMPILER_SP2_VAL, COMPILER_SP3_VAL で定義します。
|
|
Packit Service |
8bf002 |
<samp>COMPILER_CPLUS, COMPILER_CPLUS_VAL</samp>
|
|
Packit Service |
8bf002 |
-+ オプション(C++ プリプロセス)を指定した時に定義される処理系固有の事前定義マクロの名前とその値を上記と同じように文字列リラテルで指定します。COMPILER_CPLUS_VAL を指定しないと、そのマクロの値は 1 になります。名前は '_' で始まるものでなければなりません。必要がなければ COMPILER_CPLUS そのものを定義しないでおきます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
このほか、実行時オプションに応じて <samp>system.c</samp> で定義される事前定義マクロもあります。CPU-dependent なマクロなどです。GCC V.3.3 以降では大量の事前定義マクロがあるので、これらの設定とは別に <samp>mcpp_g*.h</samp> という名前の4本の専用のヘッダファイルが mcpp のインストール時に自動的に生成されます。
|
|
Packit Service |
8bf002 |
以上の設定で事前定義されたマクロはすべて実行時には -N オプションで無効となります。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>C_INCLUDE_DIR1, C_INCLUDE_DIR2, CPLUS_INCLUDE_DIR1, CPLUS_INCLUDE_DIR2, CPLUS_INCLUDE_DIR3</samp>
|
|
Packit Service |
8bf002 |
mcpp でサーチする標準ヘッダファイルの include directory を指定します。CPLUS_INCLUDE_DIR? は C++ の include directory がCのものと違っている場合に、設定します(mcpp を起動する時に -+ オプションを指定することで有効となる)。UNIX の /usr/include, /usr/local/include は <samp>system.c</samp> で設定されるので、C_INCLUDE_DIR? にはそれ以外の処理系固有のものを指定します。
|
|
Packit Service |
8bf002 |
<samp>ENV_C_INCLUDE_DIR, ENV_CPLUS_INCLUDE_DIR</samp>
|
|
Packit Service |
8bf002 |
mcpp でサーチする標準ヘッダファイルの include directory を実行時に環境変数で指定する場合のために、その環境変数の名前に定義します。ENV_CPLUS_INCLUDE_DIR は C++ の include directory を指定する環境変数の名前です。デフォルトではそれぞれ "INCLUDE", "CPLUS_INCLUDE" に定義されます。GCC-specific-build では "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH" がデフォルトです。
|
|
Packit Service |
8bf002 |
サーチパスはその外、<samp>system.c</samp> で設定されるもの、-I オプションで設定されるものがあります(それらの優先順位については mcpp-manual.html#4.2 を参照)。
|
|
Packit Service |
8bf002 |
<samp>ENV_SEP</samp>
|
|
Packit Service |
8bf002 |
この環境変数に複数のパスを書く時の separator を文字定数で書きます。
|
|
Packit Service |
8bf002 |
<samp>/usr/local/abc/include:/usr/local/xyz/include</samp> と書く時の ':' や
|
|
Packit Service |
8bf002 |
<samp>C:/BC55/INCLUDE;C:/BC55/LOCAL/INCLUDE</samp> と書く時の ';' がこれです。
|
|
Packit Service |
8bf002 |
<samp>SEARCH_INIT</samp>
|
|
Packit Service |
8bf002 |
ターゲット処理系が include ファイルをサーチする時のルールを書きます。#include "../dir/header.h" といったディレクティブを処理する時に、include ディレクトリをサーチする前にどのディレクトリをサーチするのかというルールです。カレントディレクトリからの相対パスをサーチする処理系では CURRENT とし、ソースファイル(include 元)のあるディレクトリからの相対パスをサーチする処理系では SOURCE とします。この両者の組合わせである場合は (CURRENT & SOURCE) とします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>LINE_PREFIX</samp>
|
|
Packit Service |
8bf002 |
mcpp から compiler-proper にファイル名と行番号情報を伝える形式を設定します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#line 123 "fname"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
というCのソースの形式がデフォルトとなっています。その他の形式を使う処理系では、この <samp>"#line "</samp> の部分を置き換える sequence を文字列リテラルで書いておきます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
# 123 "fname"
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
という形式なら <samp>"# "</samp> と定義し、どちらでもない独自の形式ならそれに合わせて定義します(場合によっては <samp>main.c</samp> の sharp() 等に書き足さなければならないかもしれない)。
|
|
Packit Service |
8bf002 |
Visual C++ .net や Borland C のような1パスコンパイラの前段に mcpp を使う場合は、組み込みプリプロセッサに出力を渡すことになるので、mcpp の出力はCのソースになっていなければなりません。したがって、行番号の受け渡しは1番目の形式でなければなりません。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>EMFILE</samp>
|
|
Packit Service |
8bf002 |
<samp><errno.h></samp> で too many open files (for the process) を意味する errno の値を表すマクロが EMFILE でない場合は、EMFILE をそのマクロ名に定義します(もちろん、<samp><errno.h></samp> 自体に書き加えてもかまわない)。
|
|
Packit Service |
8bf002 |
<samp>ONE_PASS</samp>
|
|
Packit Service |
8bf002 |
ターゲット処理系がプリプロセッサの分離されていないいわゆる「ワンパスコンパイラ」であればこれを TRUE に、そうでなければ FALSE に定義します。これを TRUE とすると、#pragma MCPP put_defines (#put_defines) では、処理系の事前定義マクロはすべてコメントで囲んで出力します。ワンパスコンパイラでは mcpp の出力をこれに与えると再度プリプロセスされることになるので、二重定義を避けるためです。
|
|
Packit Service |
8bf002 |
ただし、GCC V.3, V.4 はワンパスコンパイラとも言えますが、独立したプリプロセッサを使うこともできるので、このマクロは FALSE としておきます。
|
|
Packit Service |
8bf002 |
<samp>FNAME_FOLD</samp>
|
|
Packit Service |
8bf002 |
Windows のようにファイル名の大文字と小文字が区別されないOSではこれを TRUE と定義し、そうでなければ FALSE とします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>EXPAND_PRAGMA</samp>
|
|
Packit Service |
8bf002 |
#pragma 行の引数が STDC 以外であればマクロ展開の対象となる処理系では、これを TRUE に定義します。デフォルトでは FALSE としています。Visual C, Borland C では #pragma 行の引数は常にマクロ展開の対象となるので、これは TRUE とします。C99 では #pragma の引数がマクロ展開の対象となるかどうかは implementation-defined で、C90 ではマクロ展開されないのが規定なのですが、しかし、mcpp は Visual C, Borland C 用に限っては C99 でなくてもマクロ展開の対象とします(引数が STDC または MCPP で始まらない限り)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>HAVE_DIGRAPHS</samp>
|
|
Packit Service |
8bf002 |
Digraphs 処理が実装されている場合は TRUE、そうでなければ FALSE とします。
|
|
Packit Service |
8bf002 |
<samp>STDC</samp>
|
|
Packit Service |
8bf002 |
ターゲット処理系の事前定義マクロ <tt>__STDC__</tt> のデフォルト値に定義します。<tt>__STDC__</tt> が定義されていなければ 0 とします。
|
|
Packit Service |
8bf002 |
<samp>STDC_VERSION</samp>
|
|
Packit Service |
8bf002 |
ターゲット処理系の事前定義マクロ <tt>__STDC_VERSION__</tt> のデフォルト値に定義します。<tt>__STDC_VERSION__</tt> が定義されていなければ 0L とします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>CHARBIT, UCHARMAX, LONGMAX, ULONGMAX</samp>
|
|
Packit Service |
8bf002 |
ターゲット処理系の <samp><limits.h></samp> の <tt>CHAR_BIT, UCHAR_MAX, LONG_MAX, ULONG_MAX</tt> の値を書きます。
|
|
Packit Service |
8bf002 |
ただし、<samp>limits.h</samp> の <tt>UCHAR_MAX</tt> の定義は間違っている場合があるので、注意が必要です。255U, 0xffU 等と unsigned にしてはいけません。255, 0xff 等と signed int の値に定義します(cpp-test.html#5.1.3 参照)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
MBCHAR というマクロは multi-byte character の encoding を指定するものです。mcpp では下記の数種の encoding がすべて同時に実装されます。MBCHAR はデフォルトの encoding を指定するだけで、実行時に encoding を環境変数・オプション・#pragma で変更することができます(使い方については mcpp-manual.html#2.3, mcpp-manual#2.8, mcpp-manual.#3.4 を参照)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>MBCHAR</samp>
|
|
Packit Service |
8bf002 |
ターゲットの multi-byte character(日本語では漢字)の encoding の種類を定義します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
EUC_JP 日本の extended UNIX code (UJIS)
|
|
Packit Service |
8bf002 |
SJIS 日本の shift-JIS (MS-Kanji)
|
|
Packit Service |
8bf002 |
GB2312 中国の EUC-like な GB-2312(簡体字)
|
|
Packit Service |
8bf002 |
BIGFIVE 台湾の Big5(繁体字)
|
|
Packit Service |
8bf002 |
KSC5601 韓国の EUC-like な KSC-5601 (KSX 1001)
|
|
Packit Service |
8bf002 |
ISO2022_JPISO-2022-JP1 という国際規格の日本語
|
|
Packit Service |
8bf002 |
UTF8 unicode の encoding の1種である UTF-8
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
初めの5つはいずれも shift-states を持たない、1文字が2バイトを占める encoding です。なお、multi-byte character, wide character の encoding が2バイトであるにもかかわらず、wchar_t が4バイトの型になっている処理系もありますが、プリプロセッサは wchar_t の型には関知しません。ソース上では multi-byte character や wide character が2バイトを占めているので、それに従って処理をします。
|
|
Packit Service |
8bf002 |
ISO-2022-* は shift-states を持つ encoding です。UTF-8 は2バイトの unicode を1バイトないし3バイトで encode するものです。漢字は3バイトになります。
|
|
Packit Service |
8bf002 |
MBCHAR を 0 に定義した場合、multi-byte character の処理をしないのがデフォルトの仕様になるだけで、環境変数・オプション・#pragma で実行時に変更されます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>SJIS_IS_ESCAPE_FREE</samp>
|
|
Packit Service |
8bf002 |
コンパイラ本体が shift-JIS の処理をする場合は TRUE とし、しない場合は FALSE とします。
|
|
Packit Service |
8bf002 |
Shift-JIS では漢字の2バイト目が '\\' と同じ 0x5c の値になることがあります。コンパイラ本体が shift-JIS を認識しない場合は、これを escape sequence と解釈してしまい、tokenization でエラーになります。
|
|
Packit Service |
8bf002 |
SJIS_IS_ESCAPE_FREE を FALSE とすると、mcpp が処理を補います。すなわち、最終出力の時に、文字列リテラルまたは文字定数の中の shift-JIS 漢字第2バイトが 0x5c であった場合は、そこに 0x5c のバイトをもう1つ付加します。これによって、英語版のコンパイラを一応 shift-JIS に対応させることができます。
|
|
Packit Service |
8bf002 |
<samp>BIGFIVE_IS_ESCAPE_FREE</samp>
|
|
Packit Service |
8bf002 |
同様に、コンパイラ本体が Big 5 の処理をする場合はこれを TRUE とし、しない場合は FALSE とします。
|
|
Packit Service |
8bf002 |
<samp>IS02022_JP_IS_ESCAPE_FREE</samp>
|
|
Packit Service |
8bf002 |
同様に、コンパイラ本体が ISO-2022-JP の処理をする場合はこれを TRUE とし、しない場合は FALSE とします。IS0-2022-* では '\\' ばかりでなく、'\'' や '"' と一致するバイトも出現します。ISO2022_JP_IS_ESCAPE_FREE が FALSE の場合は mcpp は、'\\', '\'', '"' と一致するバイトの直前にすべて 0x5c のバイトを1つ挿入します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
なお、multi-byte character に関するコンパイラの動作は実行する時の環境によって変わる場合があります。自分の使う環境に合わせて設定してください。これについては、mcpp-manual.html#2.8 も参照してください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
次の2つは便宜上、PART 2 に書いてありますが、
|
|
Packit Service |
8bf002 |
ターゲット処理系とホスト処理系の双方が指定の型を持つ場合に TRUE とし、そうでない場合は FALSE とします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>HAVE_LONG_LONG</samp>
|
|
Packit Service |
8bf002 |
long long というデータ型を持つ処理系ではこれを TRUE とします。
|
|
Packit Service |
8bf002 |
Visual C の 2005 までや Borland C 5.* のように、long long はないが __int64 という同じサイズの型があり printf() で表示するための length modifier も用意されている場合は、これは TRUE とします。
|
|
Packit Service |
8bf002 |
Visual C 2008 では long long が使えます。
|
|
Packit Service |
8bf002 |
<samp>HAVE_INTMAX_T</samp>
|
|
Packit Service |
8bf002 |
intmax_t というデータ型が定義されていればこれを TRUE とします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>LL_FORM</samp>
|
|
Packit Service |
8bf002 |
双方の処理系が long long を持っている場合は、ホスト処理系の最大の整数型の値を printf() で表示するための length modifier を文字列リテラルで定義します。C99 では "j" です。また、C99 では long long の length modifier は "ll" (ell-ell) です。Visual C の 2003 までと Borland C 5.* では __int64 の値を表示する "I64" を使います。MinGW でも "I64" です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>noconfig.H, configed.H</samp> ではターゲット処理系とホスト処理系とが同一であると仮定していますが、異なる場合は PART 2 を書き直す必要があります。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
HOST_HAVE_STPCPY</samp>
|
|
Packit Service |
8bf002 |
ホスト処理系のライブラリに stpcpy() があれば TRUE に、なければ FALSE に定義します。FALSE であれば stpcpy() には <samp>system.c</samp> のものが使われます。
|
|
Packit Service |
8bf002 |
<samp>PATHMAX</samp>
|
|
Packit Service |
8bf002 |
ホスト処理系の <samp><limits.h</samp>> の <tt>PATH_MAX</tt> の値です。
|
|
Packit Service |
8bf002 |
これは POSIX で規定されているマクロですが、これがない処理系では <samp><stdio.h</samp>> の <tt>FILENAME_MAX</tt> の値を使います。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
PART 1 にもホストとターゲットが同一と仮定している部分があるので、必要ならそれを書き換えます。例えば次のようにホスト処理系の事前定義マクロを使っている行です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#if _MSC_VER >= 1200
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>system.H</samp> では mcpp の動作仕様を指定するマクロが定義されています。
|
|
Packit Service |
8bf002 |
mcpp には mcpp_mode という変数があり、これがマクロの展開方法、使えるディレクティブ、使える predefined マクロ等、プリプロセッサの根幹となる動作の仕様を決めています。mcpp_mode の値には OLD_PREP, KR, STD, POST_STD の4種があります。
|
|
Packit Service |
8bf002 |
mcpp の動作モードは実行時オプションで指定されます。mcpp をコンパイルする時には、これらの4つのマクロについては何も設定することはありません。しかし、各種の設定を正しく行うためには4つの動作仕様の違いを理解することが必要です。
|
|
Packit Service |
8bf002 |
このほかに COMPAT モードもありますが、これは STD の変種です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>OLD_PREP</samp>
|
|
Packit Service |
8bf002 |
いわゆる "Reiser" model cpp の動作仕様です。
|
|
Packit Service |
8bf002 |
<samp>KR</samp>
|
|
Packit Service |
8bf002 |
C90 以前の K&R 1st. のプリプロセス仕様です。
|
|
Packit Service |
8bf002 |
<samp>STD</samp>
|
|
Packit Service |
8bf002 |
規格 (C90, C99, C++98) 準拠のプリプロセス仕様です。
|
|
Packit Service |
8bf002 |
<samp>POST_STD</samp>
|
|
Packit Service |
8bf002 |
筆者が勝手に作ったプリプロセス仕様で、規格の首尾一貫しない規定を整理して単純化したものです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ここでは KR と OLD_PREP を合わせて pre-Standard モード、STD と POST_STD を合わせて Standard モードと呼ぶことにします。各モードの仕様の詳細については mcpp-manual.html#2.1 を参照してください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>CPLUS</samp>
|
|
Packit Service |
8bf002 |
-+ オプションで C++ のプリプロセッサとして動作させた時に、標準組み込みマクロ <tt>__cplusplus</tt> がこの値に事前定義されます。C++98 では 199711L です。-V オプションによって実行時に変更できます。
|
|
Packit Service |
8bf002 |
<samp>TRIGRAPHS_INIT</samp>
|
|
Packit Service |
8bf002 |
STD モードでの trigraph 処理の初期状態を指定します。-3 オプションはその状態を反転させます。これを TRUE にすると、default で trigraph が認識され、-3 オプションで起動すると認識しません。FALSE の場合は逆に default で認識せず、-3 オプションで認識するようになります。
|
|
Packit Service |
8bf002 |
<samp>DIGRAPHS_INIT</samp>
|
|
Packit Service |
8bf002 |
Standard モードでの digraph 処理の初期状態を指定します。-2 オプションはその状態を反転させます。これを TRUE にすると、default で digraph が認識され、-2 オプションで起動すると認識しません。FALSE の場合は逆に default で認識せず、-2 オプションで認識するようになります。
|
|
Packit Service |
8bf002 |
HAVE_DIGRAPHS == FALSE の処理系の場合、digraphs は mcpp が通常のトークンに変換します。
|
|
Packit Service |
8bf002 |
<samp>OK_UCN</samp>
|
|
Packit Service |
8bf002 |
STD モード で -V199901L または -+ オプションを指定した時に UCN (universal-character-name) を有効にするには、これを TRUE に定義します。デフォルトでは TRUE としています。*1
|
|
Packit Service |
8bf002 |
<samp>OK_MBIDENT</samp>
|
|
Packit Service |
8bf002 |
STD モード で -V199901L オプションを指定したときに identifier 中に multi-byte character を使えるようにするには、これを TRUE に定義します。デフォルトでは FALSE としています。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>expr_t, uexpr_t</samp>
|
|
Packit Service |
8bf002 |
最も大きい整数の型に typedef で定義します。intmax_t, uintmax_t という型があればそれに、そうでなくて long long, unsigned long long を持つ処理系ではそれに、そうでなくて __int64, unsigned __int64 を持つ処理系ではそれに、そうでなければ long, unsigned long に定義します。
|
|
Packit Service |
8bf002 |
<samp>EXPR_MAX</samp>
|
|
Packit Service |
8bf002 |
uexpr_t の最大値に定義します。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 UCN は C++, C99 の仕様で、Unicode の文字の値を \u または \U で始まる16進 escape sequence で表記するものである(mcpp-manual.html#3.7, cpp-test.html#2.8, cpp-test.html#4.6 参照)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>RESCAN_LIMIT</samp>
|
|
Packit Service |
8bf002 |
Standard モードでのマクロ展開時の再走査回数の限度を定義します。
|
|
Packit Service |
8bf002 |
Standard モード では再走査回数は少ないので、あまり大きな値を設定する必要はありません。
|
|
Packit Service |
8bf002 |
<samp>PRESTD_RESCAN_LIMIT</samp>
|
|
Packit Service |
8bf002 |
pre-Standard モードでのマクロ展開時の再走査回数の限度を定義します。pre-Standard モード では再帰的なマクロ展開によって無限ループが発生しえますが、それがこのリミットにひっかかります。
|
|
Packit Service |
8bf002 |
<samp>NBUFF</samp>
|
|
Packit Service |
8bf002 |
論理行(ソースの物理行の行末の \ を取って接続した行)の最大長 +1 を定義します。コメントを a space に変換した後の行(コメントによって複数の論理行にまたがることもありうる)もこの長さにおさまっていなければなりません。
|
|
Packit Service |
8bf002 |
<samp>NMACWORK</samp>
|
|
Packit Service |
8bf002 |
マクロ展開の内部的なバッファのサイズを定義します。すなわち、1つの論理行中のマクロを展開した結果(マクロ呼び出しが複数行にまたがる場合は、それを展開した結果)はこのサイズにおさまっていなければなりません。これはまた、1つのマクロ定義の置換リストを内部的に記憶する際の最大長としても使われます。これは NBUFF*2 以上で NWORK*2 以上でなければなりません。
|
|
Packit Service |
8bf002 |
<samp>NWORK</samp>
|
|
Packit Service |
8bf002 |
mcpp の出力する最大行長を定義します。これは compiler-proper の受け取れる最大行長+1 を越えてはいけません。また、NBUFF の値を越えてもいけません。マクロ展開後の行長がこれを越えた時は、mcpp がこれ以下の行長に分割して出力します。文字列リテラルの長さは NWORK-2 の範囲に収まっていなければなりません(文字列リテラルの長さというのは、char 配列の要素数のことではなく、ソース上での文字列リテラルというトークンの長さである。両端の " を含み、\n 等は2バイトと数える。ワイド文字列リテラルでは先頭の L も含む)。
|
|
Packit Service |
8bf002 |
ただし、GCC 版および Visual C 版では出力の最大行長としては NWORK ではなく NMACWORK を使います。
|
|
Packit Service |
8bf002 |
これらの処理系ではコンパイラがかなり長い行を受け取ることができるので、分割して出力する必要がないからです。
|
|
Packit Service |
8bf002 |
<samp>IDMAX</samp>
|
|
Packit Service |
8bf002 |
識別子の最大長を定義します。これより長い名前もエラーにはなりませんが、この長さに切り詰められます。
|
|
Packit Service |
8bf002 |
<samp>NMACPARS</samp>
|
|
Packit Service |
8bf002 |
関数様マクロの引数の最大数を定義します。これは UCHARMAX よりも大きくはできません。
|
|
Packit Service |
8bf002 |
<samp>NEXP</samp>
|
|
Packit Service |
8bf002 |
#if 行の式のカッコでくくられるネストレベルの限度を定義します(本当はネストレベルがこれで直接決まるわけではない。正確には、式中の定数トークンの数がこの2倍、演算子トークンの数がこの3倍まで使える。かっこは一対で2つと数える)。
|
|
Packit Service |
8bf002 |
<samp>BLK_NEST</samp>
|
|
Packit Service |
8bf002 |
#if (#ifdef, #ifndef) section のネストレベルの限度(#if, etc. が何段階にネストできるか)を定義します。
|
|
Packit Service |
8bf002 |
<samp>INCLUDE_NEST</samp>
|
|
Packit Service |
8bf002 |
#include のネストレベルの限度を定義します。#include の無限再帰をチェックするためのものです。同時にオープンできるファイルの数に関する OS の制限を超えていてもかまいません。
|
|
Packit Service |
8bf002 |
<samp>SBSIZE</samp>
|
|
Packit Service |
8bf002 |
マクロを内部的に hash で分類して記憶する際の hash table の要素数を定義します。必ず2のベキ乗でなければなりません。マクロの数より小さくても動作は正常にしますが、大きいほうが処理はやや速くなります。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
それぞれ大きい値にするほど仕様は上等になりますが、NWORK, NBUFF, NMACWORK, SBSIZE は大きいとそれだけ大きなメモリを食います。実際のメモリ消費はマクロ定義の量によってさらに増えてゆきます(それぞれのマクロ定義の長さによって必要メモリが決まる。マクロ定義の内部的な形式は <samp>internal.H</samp> の struct defbuf に書いてある)。
|
|
Packit Service |
8bf002 |
NMACWORK, NEXP, RESCAN_LIMIT はスタックを消費します。
|
|
Packit Service |
8bf002 |
他のものはメモリはさほど必要としませんが、<samp>system.H</samp> のデフォルトの値以上にしても実用上の意味はほとんどないでしょう。
|
|
Packit Service |
8bf002 |
C90, C99 の要求する translation limits の最低限度は <samp>system.H</samp> の最後のほうに書いてあります。C++98 の translation limits も書いてありますが、これはCと異なり、要求仕様ではありません。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
主としてターゲット処理系に関するいくつかの設定を実装しています。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>PATH_DELIM</samp>
|
|
Packit Service |
8bf002 |
OSの path-delimiter を定義しています。PATH_DELIM は \ としてはいけません(プログラムのつごうで)。Windows では / としています。ユーザプログラムではもちろん \ も使えますが、それを内部的には / に変換します。
|
|
Packit Service |
8bf002 |
<samp>OBJEXT</samp>
|
|
Packit Service |
8bf002 |
処理系の生成するいわゆるオブジェクトファイルの接尾子を文字列リテラルで定義します。UNIX 上の処理系の "o"、Windows 上の処理系の "obj" 等です。これは -M* オプションを指定した時の makefile 用依存関係行の出力に使われるものです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>do_options()</samp>
|
|
Packit Service |
8bf002 |
mcpp を起動する時のオプションを実装しています。まだ移植されていない処理系に移植する時には、その処理系付属のコンパイラドライバに合わせて、ここに何行か書き足すことが必要でしょう。do_options() に追加した時は、それに対応して次の set_opt_list(), usage() にも書き足します。
|
|
Packit Service |
8bf002 |
do_options() は mcpp_getopt() を呼び出します。mcpp_getopt() は POSIX の getopt() と同じ仕様です。
|
|
Packit Service |
8bf002 |
そのため、1つのオプション文字は引数なしか引数ありのどちらかに決めなければなりません。-P と -P- といったオプションの使い方は原則としてできません(しかし、処理系付属のプリプロセッサとの互換性のために必要な場合は、無理やりできなくもない。-M オプションの実装を参照)。また、-trigraphs といった長いオプションは t をオプション文字として rigraphs を引数とすることで実装するしかありません。
|
|
Packit Service |
8bf002 |
<samp>set_opt_list()</samp>
|
|
Packit Service |
8bf002 |
do_options() で使うオプション文字を設定します。
|
|
Packit Service |
8bf002 |
<samp>usage()</samp>
|
|
Packit Service |
8bf002 |
Usage 文が書かれています。
|
|
Packit Service |
8bf002 |
モードごとのオプションがアルファベット順に並べられています。
|
|
Packit Service |
8bf002 |
<samp>set_sys_dirs()</samp>
|
|
Packit Service |
8bf002 |
Include directory を設定しています。<samp>noconfig.H (configed.H)</samp> のマクロ C_INCLUDE_DIR?, CPLUS_INCLUDE_DIR? で指定された処理系固有のディレクトリのほか、UNIX 系OSでの /usr/include, /usr/local/include もここで設定しています(<samp>noconfig.H, configed.H</samp> のマクロ ENV_C_INCLUDE_DIR, ENV_CPLUS_INCLUDE_DIR で定義された名前の環境変数による include directory 指定は set_env_dirs() で設定される)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>do_pragma()</samp>
|
|
Packit Service |
8bf002 |
#pragma の処理を実装しています。mcpp 自身が処理しない #pragma sub-directive はそのまま出力して compiler-proper に渡します。mcpp 自身が処理する #pragma MCPP debug 等はここから呼び出す関数で処理します。mcpp 自身が処理する #pragma sub-directive は原則として MCPP という名前で始まるようにしています。MCPP で始まる #pragma 行そのものは出力しません。また #pragma once も出力しません。しかし、#pragma __setlocale 行は出力します。規格では処理系固有の拡張 directive は #pragma sub-directive として実装することになっています。
|
|
Packit Service |
8bf002 |
<samp>do_old()</samp>
|
|
Packit Service |
8bf002 |
規格に合致しない preprocessing directive (#pragma sub-directive でない #assert, #asm, #endasm, #include_next, #warning, #put_defines, #debug 等)が必要な場合は、その処理をする関数を書き足したうえで、ここからそれを呼び出すようにします(ただし、GCC 用では #include_next, #warning は STD モード でも使えるようにしてある)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
Standard C にはないライブラリ関数のうち、getopt() と stpcpy() のソースがここに書いてあります。
|
|
Packit Service |
8bf002 |
getopt() はリンクのトラブルを防ぐため、mcpp_getopt() と名前を変えてあります。
|
|
Packit Service |
8bf002 |
stpcpy() は HOST_HAVE_STPCPY が FALSE の時に使われます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
「kmmalloc -- デバッグ機能を持つ malloc()」というのは、私がCで書いた malloc(), free(), realloc(), calloc() の portable なソースです。これはメモリ効率を改善するとともに、デバッグのつごうを考えて書いてあります。デバッグ用のルーチンも添付してあります。これをリンクしておくと、思わぬバグがひっかかってくることがあります。*1, *2
|
|
Packit Service |
8bf002 |
noconfig/*.mak で -DKMMALLOC -D_MEM_DEBUG -DXMALLOC というオプションを与えているのは、この私の malloc() 等とデバッグルーチンをリンクするためのものです。これをリンクした mcpp がEFREEP, EFREEBLK, EALLOCBLK, EFREEWRT, ETRAILWRT というエラー番号で途中で exit することがあれば、それは mcpp のバグを意味します。
|
|
Packit Service |
8bf002 |
BSD_MALLOC, DB_MALLOC, MALLOC_DBG というマクロのどれかを 1 に定義して mcpp をコンパイルすると、私の malloc() とは別のそれぞれデバッグ機能を持った malloc() が使われます。いずれにしても、処理系付属のものではない malloc() を使うには、コンパイルする前にライブラリを作っておかなければなりません。これについては kmmalloc のドキュメントを見てください。
|
|
Packit Service |
8bf002 |
注:
|
|
Packit Service |
8bf002 |
*1 kmmalloc は次のところにある。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
http://download.vector.co.jp/pack/dos/prog/se026997.html
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
*2 CygWIN ではライブラリの組み立てが他の malloc() を使えないようになっているので、私の malloc() は使っていない。
|
|
Packit Service |
8bf002 |
Visual C 2005, 2008 でも同様である。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
プリプロセスの Standard C 適合性を検証するための Validation Suite を mcpp といっしょに公開しています。Standard C のプリプロセスのすべての規定を検証できるものにしたつもりです。もちろん、mcpp はこれを使ってチェックしてあります。それも、上記のすべての処理系でコンパイルしてチェックしてあります。したがって、バグや誤仕様はほとんどないと思いますが、しかし、まだいくつか残っている恐れもあります。まだ移植されていない処理系に新しく移植した場合は、処理系のバグにひっかかる可能性もあります。
|
|
Packit Service |
8bf002 |
もし、不可解な動作が発見されたら、ぜひご報告ください。その際には、次の点のチェックをお願いします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
STD モードの場合、自分の Standard C 解釈を確かめるため、まず Validation Suite を使ってみる。GCC / testsuite の使えるシステムでは、オプションを付けて configure して make check で自動テストができる。
|
|
Packit Service |
8bf002 |
自分の mcpp の移植に間違いはないかどうか、ドキュメントを確かめる。
|
|
Packit Service |
8bf002 |
バグを再現するサンプルソースを抽出する。
|
|
Packit Service |
8bf002 |
バグを引き出す部分を
|
|
Packit Service |
8bf002 |
#pragma MCPP debug <args> と #pragma MCPP end_debug ではさんで mcpp の動作をトレースしてみる。この <args> をさらに増やしてより詳細にトレースしてみる。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
もし、"Bug: ..." という診断メッセージが出たら、それは間違いなく mcpp または処理系の(たぶん mcpp の)バグです。また、たとえむちゃくちゃな「ソース」でも、それを食わせることで mcpp が暴走するなら、それもバグです。
|
|
Packit Service |
8bf002 |
もちろん、Standard C モード以外のモードの mcpp は Validation Suite では「間違い」だらけの動作をしますが、それは仕様です(それでも暴走はしないはず)。どういう仕様かは 4.1.3 を見てください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
私が書いた kmmalloc という malloc() 等のライブラリがあります(4.extra 参照)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
もし、私のこの malloc() 等をリンクした mcpp で 120 から 124(処理系によっては 2120 から 2124)のエラー番号で途中で exit することがあれば、それは間違いなく mcpp または処理系の(たぶんライブラリ関数の)バグです。
|
|
Packit Service |
8bf002 |
また、テストに使うサンプルソースのどこかに
|
|
Packit Service |
8bf002 |
#pragma MCPP debug memory
|
|
Packit Service |
8bf002 |
と書いておくと、その個所および終了時にヒープメモリに関する情報が出力されますが、ここで Heap error: ... というメッセージが出ることがあれば、それも間違いなく mcpp または処理系のバグです。
|
|
Packit Service |
8bf002 |
これらのバグが発見されたら、サンプルソースの各部分を #if 0 と #endif ではさんでテストを繰り返し、バグを発生する部分を絞り込んでみてください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
バグ報告には次のようなデータを付けてくださるようお願いします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp を移植した処理系。
|
|
Packit Service |
8bf002 |
移植した方法(<samp>noconfig.H</samp> 等の設定)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
バグと思われるものを再現できるサンプルソース。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
その処理結果。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp はほとんどの処理系に比較的簡単に移植できるように書いてあるつもりです。
|
|
Packit Service |
8bf002 |
しかし、私が持っている処理系は少数です。他の処理系への移植ではソースの書き足しが必要なはずです。それらの処理系への移植の報告をお待ちしています。それをソースにフィードバックしていきたいと思います。
|
|
Packit Service |
8bf002 |
移植の報告は次のような形でお願いします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
処理系。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
<samp>noconfig.H (configed.H), system.H, system.c</samp> の設定。
|
|
Packit Service |
8bf002 |
なるべくオリジナルとの差分ファイルが良いが、簡単なものならメモでも可。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
正しく移植できたかどうかを確かめるには、compiler-specific-build では、まずプリプロセッサを入れ替えて、ヘッダファイルの "pre-preprocess" の機能を使って自分自身をリコンパイルしてみるのが手っ取り早いでしょう。
|
|
Packit Service |
8bf002 |
さらに Validation Suite で STD モードのチェックをします。ただ、これはファイルの数が多いので、デバッグを繰り返す時には手間がかかりすぎます。デバッグ中はまず、n_std.c をコンパイルして、正常にコンパイル・実行されるかどうかを見ます。処理系付属のコンパイラドライバでは mcpp に渡す方法のないオプションもありますが、それについては mcpp-manual.html#2.2 を見てください。先に mcpp を通してからコンパイルする手もあります。
|
|
Packit Service |
8bf002 |
もしこれがうまくいかない場合は、 n_std.t というサンプルを使って、どこが悪いのか、目でチェックします。これがうまくいったら、e_std.t, m_*.t, unspcs.t, warns.t, misc.t もチェックします。"post-Standard" モードでは n_post.t, e_post.t を使います。
|
|
Packit Service |
8bf002 |
これらを mcpp -QCz23 というオプションを付けて処理します(post-Standard モードでは -3 は不可)。STDC == 0 でコンパイルしてあれば -S1 -V199409L オプションも付けます。-C オプションでコメントも出力されるので、処理結果が期待通りかどうかがすぐわかります。
|
|
Packit Service |
8bf002 |
-Q オプションで診断メッセージは mcpp.err というファイルに出力されるので、それをページャー等で読みます。
|
|
Packit Service |
8bf002 |
-z オプションで、ヘッダファイルの出力は省略されます。
|
|
Packit Service |
8bf002 |
-2 -3 で digraph と trigraph が有効になります。-S1 -V199409L で <tt>__STDC__</tt> が 1 に <tt>__STDC_VERSION__</tt> が 199409L になります。
|
|
Packit Service |
8bf002 |
C99 対応のテストをするためには、-V199901L オプションを付けて n_std99.t, e_std99.t のチェックをします。
|
|
Packit Service |
8bf002 |
Validation Suite の <samp>cpp_test.c</samp> というプログラムを使うと、n_*.c, i_*.c のサンプルのテストを自動的に行うことができます(ただし、これは○×をつけるだけで、詳細はわからない。また、e_*.?, u_*.?, unspcs.?, warns.? 等のテストは含まれない。mcpp 自身のテストをするためには、n_std.c をコンパイルするほうが早い)。
|
|
Packit Service |
8bf002 |
なお、Validation Suite は GCC の testsuite に対応しています。したがって、mcpp を GCC のどれかのバージョンに移植した場合は、GCC / testsuite がインストールされていれば、GCC のプリプロセッサを mcpp に置き換えると、mcpp の自動テストができます。これについては cpp-test.html#3.2.3, mcpp-manual.html#3.9.7 を見てください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
mcpp は UNIX 系システムでは configure スクリプトが使えます。
|
|
Packit Service |
8bf002 |
しかし、UNIX 系システムでの GCC 以外の処理系については私はまったく知らないので、compiler-specific-build の configure ではいくつかのオプションを指定してもらわなければなりません。
|
|
Packit Service |
8bf002 |
これらのオプションで指定する内容については、その処理系を使っている人は知っているか、または調べることができるはずです。おわかりの方はぜひ教えてください。Configure に取り込んでゆきたいと思います。
|
|
Packit Service |
8bf002 |
Configure については INSTALL をご覧ください。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
移植がうまくいかない場合は、そのようすをお知らせください。
|
|
Packit Service |
8bf002 |
次のデータを付けてくれれば、移植したソースをお返しできるかもしれません。Configure の使える環境では、これらのデータのうちのかなりの部分を configure によって知ることができます。
|
|
Packit Service |
8bf002 |
なお、C90 (ANSI C) に対応していない処理系は、mcpp V.2.6 からは移植の対象から外しました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
OSとそのパスリストの形式(私は UNIX 系, DOS/Windows 系, OS-9 しか知らない)。
|
|
Packit Service |
8bf002 |
処理系の名前とバージョン。
|
|
Packit Service |
8bf002 |
基本文字セットは ASCII か。
|
|
Packit Service |
8bf002 |
そうでなければどういう文字セットか。Multi-byte character(漢字)の encoding はシフト JIS か EUC-JP か、それとも何か。Shift-JIS のように <backslash> と同じコードが multi-byte character に含まれる encoding の場合、コンパイラ本体はそれを認識するか。
|
|
Packit Service |
8bf002 |
Shell(コマンドプロセッサ)は大文字と小文字を区別するか。
|
|
Packit Service |
8bf002 |
ファイル名の大文字と小文字は区別されるか。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
実装したい実行時オプション。コンパイラドライバから渡されるオプション。
|
|
Packit Service |
8bf002 |
プリプロセッサ単体で動かす時のオプション(getopt() で実装できないものは不可)。
|
|
Packit Service |
8bf002 |
プリプロセッサが分離されている処理系か、それともいわゆるワンパスコンパイラか。
|
|
Packit Service |
8bf002 |
その処理系の事前定義マクロとその値。C++ の時はどうなるか(コンパイラドライバから -D オプション等でプリプロセッサに渡されるマクロと、プリプロセッサ自身が事前定義するマクロとを区別すること)。
|
|
Packit Service |
8bf002 |
long long 型はあるか。long long がある場合、printf() での long long の length modifier は何か。long long がなくても同じサイズの型があるか。
|
|
Packit Service |
8bf002 |
#pragma 行の引数はマクロ展開の対象となるか。
|
|
Packit Service |
8bf002 |
Include directory を指定する環境変数にはどういう名前を使うか。環境変数で複数のパスを記述する時の separator には何を使うか。
|
|
Packit Service |
8bf002 |
通常使う include directory。#include でヘッダファイルをサーチする時の規則。
|
|
Packit Service |
8bf002 |
必要な関数で、ライブラリに無いものがあるか。
|
|
Packit Service |
8bf002 |
コンパイラ本体は digraph を認識するか。
|
|
Packit Service |
8bf002 |
識別子に $ を使うか。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#asm, #endasm はあるか。
|
|
Packit Service |
8bf002 |
これではさまれたブロックのコンパイラ本体への受け渡し形式はどうか。その他の規格外 directive にはどんなものがあるか。
|
|
Packit Service |
8bf002 |
プリプロセッサで処理すべき #pragma sub-directive には何があるか。
|
|
Packit Service |
8bf002 |
コンパイラ本体が受け取れる行長はどのくらいまでか(Validation Suite にある <samp>test-l/l_37_8.c</samp> をコンパイルするとわかる)。
|
|
Packit Service |
8bf002 |
コンパイラ本体では、識別子は何バイトまで識別されるか。
|
|
Packit Service |
8bf002 |
コンパイル後、リンク前の「オブジェクトファイル」の接尾子は何か(UNIX 上の処理系の .o や Windows 上の処理系の .obj に相当するもの)。
|
|
Packit Service |
8bf002 |
次の <samp>t_line.c</samp> というサンプルをプリプロセッサだけに通した結果(単体プリプロセッサを使うか、またはオプションでプリプロセス後の出力を指定する)。これは行番号とファイル名の情報をコンパイラ本体に渡す方法を見るためのものである。<samp><stdio.h></samp> の内容は長すぎるので、途中をカットして最初の10〜20行と最後の10〜20行があれば十分である。
|
|
Packit Service |
8bf002 |
さらに、#line 1000 が処理された結果が #line 1000 "t_line.c" とならず #1000 "t_line.c" とかその他の形式になる処理系では、その部分を #line 1000 "t_line.c" と書き替えてコンパイラ本体に渡して、これを認識できるかどうかを見る(#line 1000 "t_line.c" でエラーにならなければ error line; の行でエラーメッセージが出るはずであるが、その時に行番号がどう出るか)。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
/* t_line.c */
|
|
Packit Service |
8bf002 |
#include <stdio.h>
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
#line 1000
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
error line;
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
main( void)
|
|
Packit Service |
8bf002 |
{
|
|
Packit Service |
8bf002 |
return 0;
|
|
Packit Service |
8bf002 |
}
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ホスト処理系とターゲット処理系が違う場合はその双方について上記のデータがあれば、何とかなるでしょう。
|
|
Packit Service |
8bf002 |
こうして並べてみると、チェックすべきことがずいぶんたくさんありますね。しかし、多くの処理系では移植ずみの処理系と共通の特性が多いでしょうから、一応動作するだけの移植であればさほどの手間ではないはずです。比較的手間のかかるのは実行時オプションと #pragma、さらに規格外仕様の実装です。これは一応動作するようになってから、徐々にやってゆくこともできます。唯一面倒なのは、処理系のバグにひっかかった場合です。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
私が持っている処理系のプリプロセッサを私の検証セットでテストした結果は、cpp-test.html#6 にまとめてあります。
|
|
Packit Service |
8bf002 |
その他の処理系についてテストした結果をお知らせください。項目が多いのでかなりの手間ですが。
|
|
Packit Service |
8bf002 |
<samp>cpp_test.c</samp> によるテストであれば手間はかからないので、これだけでもお願いします。GCC の場合は、検証セットによる自動テストができます。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
バグ報告のほかにも、mcpp の使い勝手、診断メッセージ、mcpp のソース、Validation Suite、私の Standard C 解釈、ドキュメントの書き方、などについてご意見をお寄せください。
|
|
Packit Service |
8bf002 |
趣味で作ったプリプロセッサですが、V.2.0 までだけでも6年半もかけて凝りに凝った労作です。凝りついでにできるだけ良いものにしたいと思っています。Cプリプロセッサについては、私の持っていない処理系への移植とテスト以外は、やって意味のあることはほとんどすべてやったつもりです。多少とも問題が残っていれば、手を入れたいと思います。
|
|
Packit Service |
8bf002 |
Martin Minow のソースはとてもきれいな、クセのない、わかりやすいもので、これを読むだけでも私にとってはずいぶん勉強になりました。
|
|
Packit Service |
8bf002 |
こういうものに興味を持つ人はかなり限られていると思いますが、多くのコメントと情報をお待ちしています。
|
|
Packit Service |
8bf002 |
ご意見と情報は
|
|
Packit Service |
8bf002 |
http://mcpp.sourceforge.net/
|
|
Packit Service |
8bf002 |
の "Open Discussion Forum" またはメールでお願いします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
1992/01 に DECUS cpp をいじりだした時には、
|
|
Packit Service |
8bf002 |
こんな長丁場になるとは夢にも思いませんでした。正月休みにちょこっとバージョンアップしてみようと思っただけだったのです。
|
|
Packit Service |
8bf002 |
やり始めて、ソースをちゃんと読まないとダメだとわかり、2か月くらいかけて読みました。読みがいのあるソースだったからでもあります。次にいくつかの仕様を C90 対応にバージョンアップしました。ここまでは当初の目的の通りでした。
|
|
Packit Service |
8bf002 |
しかし、ここで私は自分が C90 のプリプロセス仕様を正確には知っていないことに気付きました。P. J. Plauger & Jim Brodie "Standard C" (1989) を読んだところ、function-like マクロの展開方法は、私の先入見をひっくり返すものでした(ある邦訳書はここを誤訳していたが)。そこで規格書を買って、プリプロセスに関する難解な文章をくり返し読みました。その結果、C90 のプリプロセスは伝統的なものとは多くの点で異なっていることがわかりました。#, ## 演算子が追加されたことは、そのほんの一部分にすぎなかったのです。
|
|
Packit Service |
8bf002 |
ことに function-like マクロの展開ルーチンにはかなり頭を悩ましました。E. Ream の cpp のソースを参考に2〜3週間考えて、C90 用マクロ展開ルーチンを新しく書きました。私がプログラムのアルゴリズムでこんなに一生懸命考えたのは、後にも先にもないことです。1992/04 のことでした。
|
|
Packit Service |
8bf002 |
さて、これで峠を越して、今度こそ cpp いじりはおしまいだと思ったのですが、ところがそれからさらに6年あまりたってしまいました。といっても、この間にはさほど頭を悩ます問題はなかったのです。にもかかわらず、時間はずいぶんかかりました。考えるだけ考えたら飽きてきて、cpp いじりに集中しなくなったせいもあります。しかし、それだけではありません。この間にやったのは次のようなことです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
仕様をさらに明確にする。Standard モードでは規格に完全に対応させる。
|
|
Packit Service |
8bf002 |
Standard C のモードを中心にプログラム構造・データ構造を再構成する。
|
|
Packit Service |
8bf002 |
Portability を上げるため、ソースのスタイルを変える。
|
|
Packit Service |
8bf002 |
デバッグをする。
|
|
Packit Service |
8bf002 |
処理系のバグや不備に対処する。
|
|
Packit Service |
8bf002 |
テストプログラムすなわち Validation
|
|
Packit Service |
8bf002 |
Suite を作る。
|
|
Packit Service |
8bf002 |
他の処理系のテストをする。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
ドキュメントを書く。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
1997/07 には新しいパソコンを買ったため、初めて使う WindowsNT/95,X Window System とそのソフトのインストールと習得に追われた。そうしているうちに C99-1997/11 draft が出て、これへの対応が必要となった。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
中でも時間のかかったのはドキュメントでした。ことに後半の4年くらいはソースをいじった時間はほんの少しで、ドキュメント書きが作業の大半を占めていました。おかげで大変な分量になってしまいましたが、しかし、時間がかかったのは量が多いせいばかりではありません。ドキュメントを書いていると、仕様の不明確なところが次々と出てくるのです。そのたびに規格書を読み返し、ソースを少しずついじりました。ソースをいじった時間は少なくても、回数は少なくありません。規格書もプリプロセス規定だけではなく、全体を ANSI C の Rationale も含めてよく読んでみました。私はプリプロセッサを作ることを通して C90 の勉強をしたようなものです。さらにはこれを通して、C90 の規定の問題点も明確に把握することができました。
|
|
Packit Service |
8bf002 |
テストプログラムは初めは簡単なサンプルを何本か書いただけでした。ところが、書いて cpp をテストするたびに意外なバグが見つかるのです。そこで、C90 プリプロセスの全規定をテストする Validation Suite を書くことにしました。そして、Valadation Suite を書くことを通して、C90 の問題点がさらに明らかになってきました。C90 の不規則な部分に対応するのは、自分にとってはわずらわしいばかりであまり意味のないことでしたが、それよりも意味のある部分のほうがはるかに多かったことは確かです。
|
|
Packit Service |
8bf002 |
この作業を通して私が学んだのは、次のようなことです。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
プログラムの仕様は、詳細なドキュメントを書き終えるまで確定しない。
|
|
Packit Service |
8bf002 |
プログラムのデバッグは、全仕様をテストするサンプルが完成するまで終わらない。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
この考え方は完全主義的なものです。
|
|
Packit Service |
8bf002 |
世の中のことは完全主義ではうまくゆかないものが多く、プログラムも例外ではありませんが、中には完全主義が重要な意味を持つ分野もあります。言語処理系はその一つでしょう。
|
|
Packit Service |
8bf002 |
趣味だから何年もかけて徹底的にやることができたとも言えます。それにしても6年半は長すぎました。こんなに時間をかけて完全なプログラムを作って、いったいだれが使うのだろうという疑問がずっと続いていました。趣味で作るプログラムとしては、このくらいが規模の限度なのでしょう。
|
|
Packit Service |
8bf002 |
しかし、mcpp はもう作ってしまったので、今後もメンテナンスをしていくつもりです。せっかくですから皆さん、コメント、報告、移植をお願いします。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
V.2.0 を公開した後、さらに V.2.1, V.2.2, V.2.3 と update を繰り返しました。C99 や正式に承認された ISO / C++ に対応させたり、対応処理系を増やしたり、バグをとったりというのがその内容です。
|
|
Packit Service |
8bf002 |
V.2.2 までは簡単に update できていました。V.2.2 は V.2.0 から3か月しかたっていません。ところが、V.2.3 は V.2.2 から4年あまりもたってしまいました。私の身辺が多忙になり、時間がとれなくなったのが主な原因です。2000/07 に 60 歳になって、仕事を週4日に減らしてから、いくらか時間がとれるようになり、cpp いじりに復帰しました。
|
|
Packit Service |
8bf002 |
V.2.3 は時間だけでなく、手間も比較的かかっています。GCC V.2.9x に実装してみたところ、GCC / cpp との互換性確保のためにかなり手を加えなければならないことがわかったからです。多くのオプションを追加し、拡張仕様を実装しました。また、一部のエラーをウォーニングに格下げしたり、頻発するウォーニングをデフォルトのウォーニングクラスからはずしたりして、規格による制限を緩和しています。
|
|
Packit Service |
8bf002 |
こうした変更の多くは後向きのものであり、楽しいものではありませんでした。ことに C90 以前の "traditional" な仕様の一部を C99 の仕様と両立させなければならないというのは、はなはだ不本意なことでした。しかし、これが現在のオープンソース界の実情であれば、それにある程度合わせるのはやむをえません。
|
|
Packit Service |
8bf002 |
規格による制約を緩和したことで、他の処理系用の版も、処理系付属のプリプロセッサと置き換えて使うためには使いやすくなったと思います。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
V.2.3 への update の途中で、mcpp および Validation Suite は情報処理振興事業協会 (IPA) の平成14年度「未踏ソフトウェア創造事業」というものに採択されました。たまたまこの事業のことを知ったので応募してみたところ、新部 裕・プロジェクトマネージャが採択してくれたのです。こうして 2002/07 から 2003/02 までは IPA の資金援助と新部PMの助言のもとに、開発が進められることになりました。ドキュメントの英訳も、ハイウェルが引き受けてくれることになりました
|
|
Packit Service |
8bf002 |
比較的小さいソフトウェアながらも、これだけ時間をかけ、私のライフワークのようになってしまったものです。その完成度には自信がありましたが、世に出る機会がなく、残念な思いをしてきました。その機会がついに与えられたのです。私はこのプロジェクトを遂行するため、仕事を週3日に減らしました。
|
|
Packit Service |
8bf002 |
私がこのプロジェクトでやることとして考えたのは、次のようなことでした。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
英語版のドキュメントを作成する。それを使って、mcpp と検証セットを国際的な評価の場に出してゆく。C処理系の大半が外国製となっている現状では、英語版ドキュメントの存在は評価と普及のために必須だからである。
|
|
Packit Service |
8bf002 |
移植の対象を広げる。これまで対応してきた処理系の新しいバージョンに対応させるほか、市販の主要な処理系への移植を進める。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
さらに新部 PM から次の提案がありました。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
GCC 3.x にも移植し、さらにその testsuite で私の検証セットが利用できるようにする。
|
|
Packit Service |
8bf002 |
開発をオープンな形で進めてゆく。
|
|
Packit Service |
8bf002 |
開発とその成果を共有しやすいように、標準的なやり方を採用する。
|
|
Packit Service |
8bf002 |
|
|
Packit Service |
8bf002 |
私自身もこれらはぜひやりたいことであるので、喜んで計画に追加しました。
|
|
Packit Service |
8bf002 |
ところが、私の計画は遅延に遅延を重ねました。
|
|
Packit Service |
8bf002 |
まず、ディスククラッシュに見舞われました。また、何か新しいことをするたびに使ったことのないソフトウェアを使って、そのたびに時間がかかりました。GCC をソースからコンパイルしたのも初めてですが、これはいくつかのトラブルに見舞われました。大量のドキュメントの更新と大量の英訳のチェックと修正にも、かなりの時間がかかりました。その上、母の入院という事態まで発生しました。プロジェクトは市販の処理系への対応等、計画の一部を断念する結果となりました。
|
|
Packit Service |
8bf002 |
私はこれまで一つの穴を深く掘ってゆくようなことしかしてこなかったので、穴を少し広げようとするとひどく手間がかかってしまうのです。アマチュアプログラマが何かを掘り下げるには、こういうやり方をしなければできることではありません。しかし、その成果を世に出すためには、穴をいくらか広げなければならないのでした。
|
|
Packit Service |
8bf002 |
穴を広げる過程で、私は新部 PM の助言と励ましを得て、いくつかの未経験のソフトウェアを習得し、開発の前線というものに触れることができました。自分の文章がこなれた英文に翻訳されて戻ってくるのも、大変うれしいことでした。時間に追われるのは苦しいことですが、内容はどれも新鮮で楽しいことでした。
|
|
Packit Service |
8bf002 |
「未踏ソフトウェア創造事業」はこれでおしまいではありませんでした。平成15年度にも、伊知地 宏・プロジェクトマネージャが mcpp を継続プロジェクトとして採択してくれたのです。こうして、前年度の積み残しの課題を初めとして、私にとっては未経験の領域のいくつかの課題に取り組むこととなりました。
|
|
Packit Service |
8bf002 |
今回も私の6年前のパソコンにトラブルが発生し、ハードウェアと OS を upgrade する過程でさらにいくつかのトラブルに見舞われました。未経験のソフトウェアの習得にも時間を要し、開発はやはり遅れ気味でした。いったん退院して比較的元気になっていた母の容態が、プロジェクトが大詰めに近づくのと並行して以前にも増して悪くなってきたことも、心配の種でした(母は 2004 年 2 月に死去した)。しかし、伊知地PMが目標を無理のないところに設定してくれたおかげで、あわてずにじっくりと課題に取り組むことができました。
|
|
Packit Service |
8bf002 |
Visual C++ への移植、configure スクリプトの作成、多様な multi-byte character encoding への対応等の課題を達成することができました。また、ソースコードの整理という目立たないながらも作者としてはこだわりのある課題にも取り組みました。日本語版と英語版のドキュメントの更新という手間のかかる作業も、ハイウェルの協力を得て達成することができました。
|
|
Packit Service |
8bf002 |
この成果によって、私は伊知地PMから何と「スーパークリエータ」という評価を受けることができました。私の実力にとっては過分の評価ですが、長年にわたる mcpp の積み重ねを認めていただいたものと思い、大変喜んでいます。
|
|
Packit Service |
8bf002 |
2年近くにわたる「未踏ソフトウェア」のプロジェクトによって、mcpp は世界一高品質な C/C++ プリプロセッサに仕上がったつもりです。熟年のアマチュアプログラマとして非力ながらもよくやったと自分では納得しています。
|
|
Packit Service |
8bf002 |
未踏ソフトウェアのプロジェクトが終わってからも、mcpp の改良作業は続けられています。まだいくつかの課題が残っています。これらの課題を達成し、mcpp を普及させるために、今後も着実に取り組みを続けてゆくつもりです。
|
|
Packit Service |
8bf002 |
</body>
|
|
Packit Service |
8bf002 |
</html>
|