Moai+Easter 上級マニュアル

トップページ   初級マニュアル   上級マニュアル   アナウンスメント   FAQ  

ご案内   Moaiエンジン   CustomBoyエンジン   HowToコンパイル   Moai CGI Developers  

C言語でCGIその1   C言語でCGIその2   mkfgenリファレンス  

はじめに

mkfgen は一つの設定ファイル mkfgen.myf から、さまざまなコンパイル環境向けの複数のMakefileを一括して自動生成するためのツールです.
ここではその使い方とmkfgen.myfの記述方法についてmkfgenツールの作者が解説します.
この記事はまた、現在のznk_projectのファイル+ディレクトリ構造全体がどのようになっているかを解説するものでもあります.

出来るだけ平易な説明を心がけたつもりですが、それでもかなり専門的な内容であることに変わりはなく、
おそらくこれは上級マニュアルの中でも最も難しい内容のものでしょう.
マルチプラットフォームの静的ライブラリ、動的ライブラリ、そしてツールの開発に相当に慣れたプログラマの方を対象に
この種のビルドシステムの一形態としてznk_projectが提供する抽象化モデルをご紹介します.


目次



mkfgenが扱うプロジェクトモデル


ディレクトリモデル
あなたが開発を進めているツール my_tool では、hello.c と utils.c があるとものとします.
hello.c 内には main関数があり、その他のCファイル( この例では utils.c しかありませんが )は、 hello.c から使うサブルーチンなどが格納された補助的なCファイル群とします.

次に、以下のようなディレクトリ構造のモデルを考えましょう.
そしてあなたの my_tool ディレクトリはこのモデルの配下に内包されていると考えます.

  • my_project ディレクトリ

    これはあなた専用のプログラム開発用ディレクトリであり、同時にすべてのものの最上層となるトップディレクトリです.
    即ちこの配下には、あなたが使うライブラリやツール群(極めて標準的なライブラリやコンパイラは除いて)一式が すべてが格納されているものとします.
    Moaiではznk_projectというディレクトリに相当するものと考えていいでしょう.

  • my_project/mkfsys ディレクトリ

    このディレクトリ内には mkfgen ツールの本体やそれに関係するその他のビルド支援系ファイルが存在します(詳しくは後述).

  • my_project/src ディレクトリ

    このディレクトリにあなたのソースファイルがすべて格納されているものとします.
    つまりあなたがこれまで開発を行ってきた(あるいはこれからも行うであろう)ライブラリやツールのソースファイルです.

    mkfgenが生成するMakefileでは、ビルド時にout_dir/$(ABINAME)というサブディレクトリをその場に作成します.
    特にライブラリの場合、そのソースディレクトリ配下のout_dirにビルドされたライブラリの実体が格納されるわけです.
    即ちこのsrc ディレクトリは生成されたライブラリ群が格納される場をも兼ねています.
    znk_projectのすべてのツールとライブラリでは、後述するconfigセクションの my_libs_root において src ディレクトリをこの意味で指定しています.

    このようにするメリットは、わざわざ生成したライブラリやヘッダ群を別のインストールディレクトリへ ずらずらとコピーする処理をMakefile内で記述するの省略できるということです.
    その分、ビルドサイクルにおけるトータルな時間も短縮されます.

    しかし勿論、そのようなコピーを行うようにした方がよい場合もあります.
    例えば、mkfgenが提供するプロジェクトモデルの範疇の外にあるツールから、そのライブラリを利用したい場合があります.
    mkfgenが生成するMakefileでは、特に汎用性の高い静的ライブラリと動的ライブラリについては、 それぞれslibとdlibというディレクトリ配下へ、一応コピーする処理を行います.
    一方、インポートライブラリとヘッダについてはそのようなコピーを行いません.

  • my_project/my_tool-vX.Y-platform

    このディレクトリはあなたが開発を行ったツール(my_tool)のインストール先です.
    実行バイナリやランタイムライブラリ、必要な設定データなど一式が格納されているものとします.
    ここで my_tool や X, Y, platform の部分はツールやそのバージョン、プラットフォームなどによって変わる文字列です.

  • my_project/my_profile

    このディレクトリでは、my_projectにおけるツールが共通して使うプロファイルデータが格納されているものとします.
    Moaiで言えば moai_profileディレクトリがこれにあたります.
    FirefoxなどにもProfileがありますが、イメージとしてはあれを意識したものです.
    これはツールの種類やバージョンを超えて共通して参照される場合もあり得るものとします.

  • my_project/src/my_tool ディレクトリ

    このディレクトリはsrc配下にあり、あなたが開発を行っているツールmy_toolのソースディレクトリです.
    この中に上記のCファイルに加え、mkfgen.myf が存在するものとします.
複雑ですか?

しかし競合するその他の同様のツールと比べればはるかに単純ともいえます.
必要なツールはすべてmy_project/mkfsysディレクトリ一つに比較的小さなサイズで収まっており、 従ってこの辺りが必要にして十分な考えられ得る最小モデルではないでしょうか?

mkfgenツールによって生成されるMakefileは、この例では windows用(vc、mingw、msys)、linux用(gcc)、cygwin用(gcc)、android用(ndk)の6つであり、 my_project/src/my_tool ディレクトリ内にそのすべてが瞬時に生成されることでしょう.
(例えば、vc用の場合、Makefile_vc.mak といった名前のMakefileになります).


mkfgen.myfの例
まずは最も簡単な mkfgen.myf の例を示しましょう.

@def_quote [' ']

@@V config
my_libs_root = ['..']
template_dir = ['../../mkfsys/template']
install_dir = ['../../bin']
@@.

@@L include_paths_common
@@.

@@L dependency_libs_common
@@.

@@V info_vc
@@.

@@V info_mingw
@@.

@@V info_msys
@@.

@@V info_linux
@@.

@@V info_cygwin
@@.

@@L mkid_list
vc
mingw
msys
linux
cygwin
android
@@.

@@L product_list
exec hello hello.c
@@.

@@L rc_list
@@.

@@L sublibs_list
@@.

@@L install_data_list
@@.

@@L ignore_list
@@.

@@L src_suffix_list
c
@@.

長いですか?

しかし6つのMakefileを書く手間を考えれば、これ一つで済むのですからはるかに短いともいえます.
また、上の例ではほとんど空のセクションを列記しているだけであるため、見かけほど記載されている情報量は多くはありません.
つまり実際には上記をコピペし、必要な情報だけを修正+追記するだけで大抵は事足りるでしょう.

hello.cを除くその他のCファイル( この例では utils.c だけですが )の指定がどこにも見当たらないと思われるかもしれません.
実は mkfgenツールは、それが実行されたディレクトリ配下を再帰的にスキャンし、拡張子からC/C++ファイルを自動的に認識するため、 mkfgen.myfにおいては基本的にCファイルの指定は不要なのです.

一方、main関数を含むCファイルだけは明示的に指定する必要があります.
これは product_listにexecキーワードに続けて、生成される実行バイナリ名( この例では hello )、 ソースコード名( この例ではhello.c )の順でスペース区切りで指定する形となります.

この指定が必要な理由は、一つのプロジェクト内において複数の実行バイナリをビルドさせたい割とよくある需要に応じるためです.
つまりmain関数を持つCファイルが複数あるようなケースです.
Cファイルを完全スキャンすれば main関数が含まれるかどうかまで自動認識はできますが、 実のところそれは本当はビルド対象には含めて欲しくはないCファイルであるかもしれません.
( 例えばlibpngに含まれる example.c は、main関数を含むものですが、実のところこれは擬似的な Cコードであり、 コンパイル対象に含めて欲しくないCファイルです ).
このようなケースでも取捨選択してビルドさせるため、mkfgenツールではこの指定が必要な仕様になっています.

今思えば、ignore_listの指定によってもこのような除外ができますので、mkfgenの将来のバージョンではこの仕様を変更するかもしれません.


mkfgenの修正が必要なタイミング
mkfgenツールにおける Cファイルの再帰的自動認識機能はCファイルの多い大規模なプロジェクトで大きな効果を発揮します.
下請けのCファイル群が増えた場合、mkfgenツールを実行するだけでMakefile内のCファイルの情報を自動的に更新できますし、 その際に mkfgen.myf 自体を我々が修正するなどの作業も一切発生しないからです.

それでは逆に、どのような場合に我々がmkfgen.myfを直接修正しなければならないかと言えば、 例えば開発しているプロジェクトが使う依存ライブラリが新しく増えたような場合です.
この場合、include_paths_commonやdependency_libs_commonに新しいライブラリに関するパス情報などを手動で追記した上、 mkfgenツールを実行してMakefileを更新しなければなりません.

Moai CGI上でわかりやすいUIを表示しつつ、その指定によってmkfgen.myfを自動生成し、 それをダウンロードできるようなツールを作ると便利かもしれません.
Moaiの将来のバージョンではそのようなツールを提供するかもしれません.


目次に戻る

configセクション (Section Type: @@V 変数リスト)


mkfgenの全般的な設定
このセクションでは基本的なパスの指定など、この mkfgen.myf全体に関わる設定を行います.
ディレクトリ区切り文字(以降これをDSPと呼びます)は、Windowsにおいても / を使用して構いません.
  • my_libs_root(String型)
    すべてのライブラリのルートとなるディレクトリを指定します.
    (znk_projectではsrcディレクトリがこれに該当します)

  • template_dir(String型)
    templateファイルが格納されているディレクトリを指定します.

  • lib_dlver(String型)
    DLib(Dynamic Link Library)のファイル名に付するバージョン番号文字列を指定します.

  • install_dir(String型)
    デフォルトのinstall先ディレクトリを指定します.

  • install_data_dir(String型)
    データファイルのinstall先ディレクトリを指定します.
    この指定を省略した場合、替わりにinstall_dirの値が使われます.

  • install_exec_dir(String型)
    Exec(実行バイナリ)のinstall先ディレクトリを指定します.
    この指定を省略した場合、替わりにinstall_dirの値が使われます.

  • install_dlib_dir(String型)
    DLib(Dynamic Link Library)のinstall先ディレクトリを指定します.
    この指定を省略した場合、替わりにinstall_dirの値が使われます.

  • install_slib_dir(String型)
    SLib(Static Link Library)のinstall先ディレクトリを指定します.
    この指定を省略した場合、替わりにinstall_dirの値が使われます.

  • special_exe_sfx(String型)
    生成物(product)が実行バイナリの場合で、かつその拡張子を特別に変更したい場合 その拡張子を指定します.
    例えば拡張子をcgiにしたい場合などの用途が考えられます.

  • special_lib_pfx(String型)
    生成物(product)がライブラリの場合で、かつそのlibプレフィックスを特別に変更したい場合 そのプレフィックスを指定します.
    例えばlibプレフィックスを付けないようにしたい場合は、これに明示的に空値を指定します.
    あるいはlibプレフィックスを必ず付けるようにしたい場合は、これに明示的にlibを指定します.

  • resfile_additional(String型)
    resource file(拡張子res)としてこれを特別に追加します.

  • runtime_install(bool型)
    これをtrueに設定すると、このproductが依存するランタイムライブラリもいっしょにインストールされます.
    falseに設定すると、このランタイムライブラリがインストールされません.
    デフォルトではtrueであり、runtime_installを特に指定しない場合もtrueとみなされます.

  • include_makefile_version(bool型)
    これをtrueに設定すると、Makefile_version.makをincludeする処理が行われるようになります.
    Makefile_version.makでは DL_VER や REL_VER の値が定義されます.
    DL_VERはDLibに付加するバージョン番号であり、デフォルトではlibZnkのものが参照されます.
    REL_VERはツールに付加するバージョン番号であり、デフォルトではmoaiのものが参照されます.

  • is_android_ndk_build_support(bool型)
    このbool値は mkid_list 内に android の指定を含む場合のみ意味を持ちます.
    ここでは mkid_list 内に android が指定されているものとします.

    mkfgenシステムでの android版バイナリのビルドは、Makefile_android.makを使って ( mkidがandroid のもの以外と同様の様式によって) makeコマンドを実行することで行うことができます.
    しかしながら、Android Developerの公式ドキュメントでは ndk_build スクリプトの実行によってビルドする方法が示されています.
    mkfgenシステムでも、この ndk_build によるビルドは可能ですが、ただしその場合 その実行に必要な特別なMakefile、すなわち Application.mk と Android.mk を生成する必要があります.

    このbool値を true に設定すると、mkf_androidフォルダを生成して、その配下にこの Application.mk と Android.mk を生成します.
    このときカレントディレクトリを mkf_android へ移動し、Android NDK が提供する ndk_build スクリプトを実行しますと. この Application.mk と Android.mk に記述されたルールに従ってビルドが行われるといった形になります.
    この値を false に設定すると、mkf_androidフォルダは生成されず、Makefile_android.mak のみが生成されます.
    ( Makefile_android.mak は、この値の真偽に関わらず生成されます ).


  • makefile_version_landmark(String型)
    ソースディレクトリ内にMakefile_version.makがまだ存在していない場合、 その内容をどうするかに関してこの値がヒントとなります.
    mkfgenはそのソースディレクトリから親ディレクトリへと順に辿り、この値と同じ名前のディレクトリがあれば その中にMakefile_version.makがあるかを調べます.
    そしてもしそこにMakefile_version.makが存在するならば、 それをincludeするような新しいMakefile_version.makをソースディレクトリ内に生成します.

  • gslconv(String型)
    我々が提唱するディレクトリモデルでは、Makefileの他にも gsl.myf という特別なファイルを導入しています.
    このファイルは、DLib(Windowsの場合はDLL : Dynamic Link Library)のソースディレクトリの中でのみ生成されます.
    gsl.myf はそのDLibにおいてExportされるべきグローバルシンボル(要はグローバル関数)のリストを列挙したものです.

    ソースコードでグローバル関数が追加/削除されると同時に、このgsl.myfも修正しなければなりませんが、 我々プログラマがそれを毎回手動でやっていては大変ですので、通常はそれをツールによって自動更新させます.

    gslconv(Global Simbol List CONVerter)はそのためのツールであり、mkfgenとセットで私が開発したものですが、 mkfgenが生成するDLib用のMakefileではこのツールが必須となります
    (ちなみに gslconv 自体のソースコードはlibZnkに含まれており、libZnkとこのツールは同時にビルドされます).

    前置きが長くなりましたが、ここではgslconvの実行バイナリのパスを指定します.
    gslconvについての補足
    gslconvについての補足

    gslconvツールは予め生成しておいたSLib(Static Library)を分析して、それに含まれるグローバルシンボルを自動的に抽出し、 gsl.myfを生成/更新するためのものとなります.
    ただしSLibはCOFF形式である必要があります(OMF形式には対応しておりません)

    この gsl.myf の使い道をもう少し詳しくお話しましょう.
    例えばこの gsl.myf ファイルから各コンパイラ用の def ファイルへの変換は、SLibを直接分析する処理と比べればはるかに容易いのです.
    def ファイルとはDLLを作る際にコンパイラ(厳密にはリンカ)に直接指定できる形式のシンボル定義ファイルです.
    ただしコンパイラによって defファイルの記法が微妙に異なることがあるのです.
    gsl.myfとはdefファイルをコンパイラに依存しない形で抽象化したようなものです.


    gslconvを開発した経緯
    gslconvを開発した経緯

    ところで、GNU binutils に nm コマンドというものがあります.
    実のところ、このコマンドでもgslconvと同じようにSLibからグローバルシンボルを抽出できます.
    実際、mkfgenツールを開発するにあたって初期のプロトタイプでは nm を使っていました.
    しかし nm コマンドでは次の問題があるため、結局不採用としました.
    • 64bit版ライブラリのシンボルを得るためには64bit版 nm を使わなければならない.
      つまり32bit版と64bit版の両方の nm がシステムにおいて使えるようにインストールされていなければならず、 しかもMakefile内ではどちらの版を使うかを適切に切り分けなければならない.

    • WindowsのVC環境では標準で用意されていない.
      (dumpbin.exeで可能では?と思われるかもしれませんが、これは静的ライブラリには使えません).
      MinGWやCygwinなどをインストールすると使うことができるが、 VCを使っているのに nm コマンドのためだけにMinGWをインストールするという理不尽な状況が生じる.

    • 標準で用意されていないなら開発プロジェクトに常時同梱しておけばよいと思われるかもしれないが、 nm コマンド(binutils)のライセンスはGPLである.
      知らない方のために一言で言うと、このライセンスはとても不自由かつ伝染するので、 このような同梱がし辛い.
    このような要請から、上記の問題すべてを解決する代替のツールとして、今回gslconvを開発するに至ったわけです.
    gslconvであれば、32bit/64bitライブラリ双方をこれ一つで認識します.
    またライセンスは mkfgen と同じくNYSLであり、使用や同梱するにあたっての制限は何もありません.



目次に戻る

include_paths_commonセクション (Section Type: @@L ラインリスト)


インクルードパスの設定
ここではヘッダをインクルードするためのパス群を一行につき一つずつ指定します.
この指定では、シンタクスシュガーとして以下のような@記法を使うことができます.
@{X}

これはコンパイルオプション上では INCLUDE_FLAG として次のように展開されます.
-I$(MY_LIBS_ROOT)/X

ここで $(MY_LIBS_ROOT) は configセクションのmy_libs_rootにおいて指定したパスに展開されます.

この@記法では都合の悪い場合は、これを使わずに直接記述することもできます.
例えば以下のようになります.
../include

この場合、INCLUDE_FLAG としては次のように展開されます.
-I../include


目次に戻る

dependency_libs_commonセクション (Section Type: @@L ラインリスト)


依存ライブラリの設定
ここでは依存ライブラリのリストを一行につき一つずつ指定します.
この指定では、シンタクスシュガーとして以下のような@記法を使うことができます.
rlib: @{X} Y $(DL_VER)

この記法により my_libs_rootからの相対位置 X にある libY-$(DL_VER) というライブラリを指定することができます.
ここで$(DL_VER)はライブラリのバージョン番号を示す文字列に展開されます.

リンクする際には、これはコンパイラ環境に応じて次のように展開されます.
VC:
$(MY_LIBS_ROOT)/X/out_dir/$(ABINAME)/Y-$(DL_VER).imp.lib
MinGW:
$(MY_LIBS_ROOT)/X/out_dir/$(ABINAME)/libY-$(DL_VER).dll.a
Linux(gcc):
$(MY_LIBS_ROOT)/X/out_dir/$(ABINAME)/libY-$(DL_VER).so
Cygwin(gcc):
$(MY_LIBS_ROOT)/X/out_dir/$(ABINAME)/cygY-$(DL_VER).dll

また、実行バイナリを構築する場合にはさらに動的リンクライブラリをランタイムライブラリとして、 インストール時にこれをインストール先にコピーします.
このインストール先は、コンパイラ環境に応じて次のように展開されます.
Windows:
$(MY_LIBS_ROOT)/$(DLIBS_DIR)/Y-$(DL_VER).dll
Linux:
$(MY_LIBS_ROOT)/$(DLIBS_DIR)/libY-$(DL_VER).so
Cygwin:
$(MY_LIBS_ROOT)/$(DLIBS_DIR)/cygY-$(DL_VER).so

いかがでしょうか?
この@記法1行だけでこれほどまでに多様な指定を自動生成することができます.
(さらに必要ならば各Makefile毎に用意されたtemplateファイルを編集することにより、 この生成のされ方を変更することもできます)


使用例
では実際の使用例も見てみましょう.


rlib: @{libZnk} Znk $(DL_VER)

説明
libRanoのmkfgen.myf より抜粋したものです.
この例では my_libs_root/libZnk という動的ライブラリを指定したことになります.
(libRanoはlibZnkに依存するということです)


rlib: @{libZnk} Znk $(DL_VER)
rlib: @{libRano} Rano $(DL_VER)

説明
moaiのmkfgen.myf より抜粋したものです.
この例では my_libs_root/libZnk および my_libs_root/libRano の二つの動的ライブラリを指定したことになります.
(moaiはlibRanoとlibZnkに依存するということです)


slib: @{libZnk} Znk $(DL_VER)

説明
auto_triggerのmkfgen.myf より抜粋したものです.
今回は最初が rlib: ではなく slib: となっています.
rlib: は動的なランタイムライブラリであることを示すのに対し、slibは静的ライブラリであることを示します.
この例では my_libs_root/libZnk という静的ライブラリを指定したことになります.
(auto_triggerはlibZnkを静的にリンクするということです)


slib: $(MY_LIBS_ROOT)/$(SLIBS_DIR) crypto $(DL_VER)

説明
@記法を使わない例も挙げておきます.
この例では $(MY_LIBS_ROOT)/$(SLIBS_DIR)/libcrypto という静的ライブラリを指定したことになります.


目次に戻る

runtime_additionalセクション (Section Type: @@L ラインリスト)


ビルド済みライブラリを追加する
ここでは、動的にロードしたい依存ライブラリのリストをdependency_libs_commonと同様の形式で追加指定します.
dependency_libs_commonと違い、ここに指定されたものはこのMakefileでのコンパイルおよびリンクでの直接の対象とはなりません.
(つまり仮にここに指定したものが存在しなくとも、とりあえずそれらの処理に直接支障は及ばないないということです).

ここに指定されたものはMakefileでのinstallにおいてのみ意味を持ちます.
つまりこれらは単にインストールディレクトリへのコピーだけが行われるということです.
また仮にこれらが存在しない場合はエラーとはならず単に無視されます.

例えば、既にビルド済みのサードパーティ製の動的ライブラリなどをここに指定するとよいでしょう.
これらを実行時(ランタイム)に動的にロードしたいケース等に対応できます.
(この実行時動的ロードを行うためには、WindowsならばLoadLibrary関数、Linuxならばdlopen関数を使います.)

その他、孫受け的な動的ライブラリもここで指定します.
これはこのMakefileがビルドするソースコードからは直接は必要ない(ヘッダのincludeやインポートライブラリのリンクの必要がない)が、 下請けの動的ライブラリからはそれが必要となる、つまり「下請けの下請け」の動的ライブラリを意味します.
動的ロードの依存性をすべて解決するには、これらも最終的なインストールディレクトリ内に存在する必要があるわけです.


記法
rlib: @{X} Y V
この記法において、libY-V というライブラリを指定することができます.
(Ver2.1より Linux系でもsoファイル名にこのVが付加される仕様に変更されました.)
runtime_additionalセクションでは、Xの部分はダミー指定となり特に効果を持ちません.

インストールにおけるこのランタイムライブラリのコピー元は、コンパイラ環境に応じて次のように展開されます.
Windows:
$(MY_LIBS_ROOT)/$(DLIBS_DIR)/Y-V.dll
Linux:
$(MY_LIBS_ROOT)/$(DLIBS_DIR)/libY-V.so
Cygwin:
$(MY_LIBS_ROOT)/$(DLIBS_DIR)/cygY-V.so


使用例
では実際の使用例も見てみましょう.

rlib: @{libressl/tls} tls 17

説明
moaiのmkfgen.myf より抜粋したものです.
この例では libressl/tlsはダミー指定です.

Windowsでは $(MY_LIBS_ROOT)/$(DLIBS_DIR)/tls-17.dllを指定したことになります.
(Moaiの実際の例では、さらにlibtls-17.dllとなるようinfo_vc、info_mingw、info_msysセクション等で、 特殊な指定が加えられています).
Linuxでは $(MY_LIBS_ROOT)/$(DLIBS_DIR)/libtls-17.soとなります.


目次に戻る

info_{COMPILER}セクション (Section Type: @@V 変数リスト)

{COMPILER}にはmkid_listで列挙したコンパイル環境を示すidを指定します.
このセクションにはコンパイル環境ごとにそれぞれ以下を指定できます.


コンパイラに関する指定
  • compiler_option_special(String型)
    このコンパイラ環境において特別に指定するコンパイラオプションを指定.

    ['/wd4127 /wd4996 /wd4267']
    説明
    libZnkのmkfgen.myf内info_vc より抜粋したものです.
    この例では、VCにおいて警告を抑制するオプションを指定しています.


    ['-D_POSIX -D_WIN32_WINNT=0x0500 \ -DWIN32_LEAN_AND_MEAN \ -D_REENTRANT']
    説明
    -Dはdefineすべきマクロ変数をコンパイラに指定するためのオプションです.
    この例では、4つの変数を定義しています.
    また、Makefileでは途中で改行する場合は改行の直前に \ でエスケープする必要があります.


リンカに関する指定
  • linker_option_special(String型)
    このコンパイラ環境において特別に指定するリンカオプションを指定.

    ['/SUBSYSTEM:console']
    説明
    この例では、VCにおいてLINKコマンドオプションである/SUBSYSTEM(コンソールウィンドウが付くか否か等)を指定しています.
    (もっとも現在のVCでは、/SUBSYSTEMを明示的に指定しなくても、ソースコードでmainかWinMainのどちらが使われているかによって、 適切なものが自動的に設定されるようです)


    ['-Wl,-dn,-lstdc++']
    説明
    この例では、gccにおいてC++のコンパイルに関するリンカオプションを指定しています.

  • linking_libs_special(String型)
    このコンパイラ環境において特別にリンクするライブラリのリストを指定.

    ['ws2_32']
    説明
    libZnkのmkfgen.myf内info_vc より抜粋したものです.
    この例では、VCにおいて ws2_32.lib ライブラリのリンクを指定しています.


    ['pthread dl stdc++']
    説明
    moaiのmkfgen.myf内info_linux より抜粋したものです.
    この例では、linux(gcc)において -lpthread -ldl -lstdc++ に該当する指定を行っています.

  • dependency_libs_special(String型)
    ほとんどの場合、この指定を使う替わりに linker_option_special や linking_libs_special を使うべきです.
    ここで指定した文字列はリンカのオプション指定としては最後方に置かれます.
    そのため、オプションの指定順が重要な環境で特殊な指定を行う場合のみ、この指定が必要となることがあります.

    ['../my_static_libs/util.a']
    説明
    この例では、linux(gcc)におけるイレギュラーな静的ライブラリをパスで直接指定を行っています.


ライブラリの命名規則を修正する指定
  • template_lib_file_special(String型)
    このコンパイラ環境において生成されるライブラリ名の構造を特別に指定.

    ['cyg$[lib_name]$.$[lib_sfx]$']
    説明
    plugin_5ch のmkfgen.myf内 info_cygwinより抜粋したものです.
    この例では、生成される動的リンクライブラリをplugin用に強制的に名前変更しています.

  • slib_pfx_special(String型)
    このコンパイラ環境で用いられる slib_pfx の値を特別に上書き指定する.


    ['crypto:lib ssl:lib']
    説明
    この例では、lib_nameがcryptoの場合はそれに付け加えるslib_pfxをlibに強制的に置き換えます.
    また、lib_nameがsslの場合も同様にslib_pfxをlibに置き換えます.

    例えばVCの場合、デフォルトではslib_pfxは空となっています.
    このままでは crypto.lib などといったファイル名になってしまいますが、
    これを特別に libcrypto.lib に変更するなどといったことが出来ます.

  • rlib_pfx_special(String型)
    このコンパイラ環境で用いられる ilib_pfx と dlib_pfx の値を特別に上書き指定する.

    ['crypto:lib ssl:lib']
    説明
    この例では、lib_nameがcryptoの場合はそれに付け加えるilib_pfxとdlib_pfxをlibに強制的に置き換えます.
    また、lib_nameがsslの場合も同様にilib_pfxとdlib_pfxをlibに置き換えます.

    例えばVCの場合、デフォルトではilib_pfxやdlib_pfxは空となっています.
    このままでは crypto-17.dll などといったファイル名になってしまいますが、
    これを特別に libcrypto-17.dll に変更するなどといったことが出来ます.


その他の指定
  • shell(String型)
    このコンパイラ環境におけるMakefileで使用するシェルのタイプ.
    dos または sh を指定.


目次に戻る

mkid_listセクション (Section Type: @@L ラインリスト)


サポートするコンパイラ環境の指定
このセクションにはMakefileを生成したいコンパイル環境を示すidを列挙します.
( 現在サポートするidは vc mingw msys cygwin linux android です ).
mkfgen ではこのセクションで列挙されたidについてのみ、Makefileが作成されます.
(逆に言えばここで列挙されなかったidについては作成されません)
例えば、linux専用のツールの場合などでは vc mingw などWindows系専用のMakefileを生成しても明らかにムダです.
そのような場合にここで linux のみを指定しておけば余計なMakefileを生成せずに済みます.


目次に戻る

product_listセクション (Section Type: @@L ラインリスト)


最終生成ファイルの指定
このセクションにはこのmkfgenによって生成するプロダクトとその種類を列挙します.
複数指定可能であり、以下のような記法になります.
product_type product_name product_mainsrc
product_type の指定は生成したいファイルの種類によって変わります.
後述の指定例を参照してください.

product_name の指定では拡張子を指定してはいけません.
コンパイル環境に応じて適切な拡張子が自動的に付加されます.

product_mainsrc の指定ではファイルのパスを指定してください.
こちらは拡張子まですべて記述する必要があります.


指定例
実行ファイルを生成したい場合、product_type として exec を指定します.

exec player main.cpp
説明
playerという実行ファイルを作ります(例えばWindowsではplayer.exeなど適切な拡張子が自動的に付加されます).
また3番目の指定では、そのmain関数の存在するソースファイルはmain.cppであることを指定しています.

動的ライブラリを生成したい場合、product_type として dlib を指定します.

dlib Znk dll_main.c
説明
Znkというdlibファイルを作ります(例えばVCではZnk-2.2.dllなど適切なバージョン番号と拡張子が自動的に付加されます).
また3番目の指定では、WindowsのDLLの場合DllMain関数の存在するソースファイルを指定します.
Linuxのsoファイルの場合はこの項目は意味を持ちませんが、Windowsと指定の互換性を持たせるため、 やはりDllMain関数の存在するソースファイルを指定するとよいでしょう.

静的ライブラリを生成したい場合、product_type として slib を指定します.

slib zlib zutil.c
説明
zlibというslibファイルを作ります(例えばVCではzlib.libなど適切な拡張子が自動的に付加されます).
また3番目の指定では、その代表となるソースファイルを何でもよいので一つ指定します.


目次に戻る

rc_listセクション (Section Type: @@L ラインリスト)


Windowsリソースファイルの指定
このセクションではこのmkfgenによって扱うrcファイル(Windowsのリソースファイル)の名前を明示的に列挙できます.
しかしこれが空でもmkfgenは自動的にrcファイルを認識して、この情報を生成されるMakefileに補充します.
万一この自動認識がうまくいかないケースが発生した場合はこのセクションで明示的に指定してください.

特にproduct_list においてexec指定された実行ファイル名とrc名が一致する場合、これらは自動的に関連付けられます.
例えば product_list において exec player main.cpp と指定された場合、rcファイルの名前が player.rc の場合は 特に何も指定せずとも player.rc は playerに自動的にリンクされるということです.


目次に戻る

sublibs_listセクション (Section Type: @@L ラインリスト)


サブディレクトリのサブライブラリ
このセクションはサブディレクトリにサブライブラリがある場合にのみ使用します.
(このサブライブラリとは、例えばlibZnkが内包するzlibのようなものです).

サブディレクトリおよびサブライブラリの名前を指定することでそれらのビルドとリンクをすることができます.
以下の記法になります.

submkf_dir sublib_name

左側はサブディレクトリの名前です.
右側はサブディレクトリ内に生成されるサブライブラリの名前です.

参考
参考

親となるMakefileからサブディレクトリのMakefileへ実行の制御を移すとき、 この実行のトリガーとなるtarget名を親となるMakefile内で指定しておかなければなりません.
mkfgenでは、このtarget名を submkf_{X} という形式でMakefile内に作り出すルールとなっています.
このXに相当する部分としてsubmkf_dirが使われます.



目次に戻る

install_data_listセクション (Section Type: @@L ラインリスト)


インストール時にコピーするファイル群
単にコピーしてインストールするデータファイル群を指定できます.
次のようにインストール元としてワイルドカードを指定することもできます.
template/*.mak

このときインストール先として、install_dir配下にtemplateディレクトリが自動的に生成され、 拡張子がmakの全ファイルがそこへコピーインストールされます.
インストール元の指定ではディレクトリに対してワイルドカードを使用してはいけません.
上記の例では template の部分でワイルドカードは使用できません.
ワイルドカードが使用できるのはファイルに対してのみとなります.
ワイルドカードの使用は上記のように拡張子を指定する単純な用途にしておくことを強くお勧めします.
特にWindows(DOS)環境において、複雑な指定は問題が生じることがあります.

以下のようにスペース区切りでインストール先のディレクトリを明示的に与えることもできます.
template/*.mak share

このときinstall_dir配下に(templateディレクトリではなく)shareディレクトリが自動的に生成され、 拡張子がmakの全ファイルがそこへコピーインストールされます.
インストール先の指定ではワイルドカードを使用してはいけません.

DOSにおける3文字拡張子とワイルドカードの問題について
DOSにおける3文字拡張子とワイルドカードの問題について

LinuxなどのShellと比べると信じられないことですが、 DOSでは例えば *.xls は 拡張子 xls だけでなく xlsx や xlsxx という拡張子にもマッチします.
この現象は拡張子が3文字の場合のみに起きます. 一方拡張子が3文字以外の場合ではこの現象は起きません.
例えば *.rb の場合は *.rbx や *.rbxx にマッチするようなことは起きません.
さらには *.xls ではなく *xls と指定しても同様のことが起きます.


test_xl test_xls test_xlsx test_xlsxx
test.xl test.xls test.xlsx test.xlsxx
というファイルがあるとする.

dir /b にワイルドカードを指定すると展開結果は以下のようになる.
dir /b test_* : test_xl test_xls test_xlsx test_xlsxx
dir /b *_xl : test_xl
dir /b *_xls : test_xls
dir /b *_xlsx : test_xlsx
dir /b *_xl* : test_xl test_xls test_xlsx test_xlsxx
dir /b *_xls* : test_xls test_xlsx test_xlsxx

dir /b test.* : test.xl test.xls test.xlsx test.xlsxx
dir /b *.xl : test.xl
dir /b *.xls : test.xls test.xlsx test.xlsxx (problem1!)
dir /b *.xlsx : test.xlsx
dir /b *.xl* : test.xl test.xls test.xlsx test.xlsxx
dir /b *.xls* : test.xls test.xlsx test.xlsxx

dir /b *xl : test_xl test.xl
dir /b *xls : test_xls test.xls test.xlsx test.xlsxx (problem2!)

このように3文字の拡張子に絡む場合のみ奇妙な動作を起こします.
(8-3短縮ファイル名時代の名残のようです).

mkfgen では、一応この問題を救済してあります.
この問題が起こり得るケースにおいて生成されるMakefileは for /f in と dir /b と findstrを駆使したDOSのコードを生成するようにしています.



目次に戻る

ignore_listセクション (Section Type: @@L ラインリスト)


mkfgenに無視して欲しいディレクトリやファイル群
自動認識において無視するディレクトリまたはファイルを指定します.
例えば名前が example.c というファイル、および ignores ディレクトリとobsoleteディレクトリ内に含まれるソースファイルを無視したい場合は、 次のように指定します.
example.c
ignores
obsolete

これにより、たとえignoresディレクトリやobsoleteディレクトリ内に拡張子が c のファイルがあったとしても、 それはコンパイル対象として無視されます.


目次に戻る

only_list_{COMPILER}セクション (Section Type: @@L ラインリスト)


環境依存ファイルの指定
特定のコンパイラにおいてのみ使用するソースファイルまたはディレクトリを指定します.

例えば名前が example_win.c と thread_win.c というソースファイルについてはvcとmingwにおいてのみ、 名前が example_unix.c と thread_pthread.c というソースファイルについてはlinuxとcygwinにおいてのみとして それぞれ使用したい場合は次のように指定します.
@@L only_list_vc
example_win.c
thread_win.c
@@.

@@L only_list_mingw
example_win.c
thread_win.c
@@.

@@L only_list_linux
example_unix.c
thread_pthread.c
@@.

@@L only_list_cygwin
example_unix.c
thread_pthread.c
@@.


環境依存ディレクトリの指定
ディレクトリの指定の例も示しましょう.
例えば名前が audio/dsound ディレクトリについてはvcとmingwにおいてのみ、 audio/alsa ディレクトリについては linuxとcygwinにおいてのみ、 audio/android ディレクトリについては androidにおいてのみとして それぞれ使用(すなわち配下のソースファイルをコンパイル対象に含めるという意味ですが)したい場合は次のように指定します.
@@L only_list_vc
audio/dsound
@@.

@@L only_list_mingw
audio/dsound
@@.

@@L only_list_linux
audio/alsa
@@.

@@L only_list_cygwin
audio/alsa
@@.

@@L only_list_android
audio/android
@@.
このようにプラットフォーム依存のファイルやディレクトリの指定などでこのセクションを使いますが、 特に指定するファイルやディレクトリがない場合はこのセクションは省略することが可能です.
またファイルとディレクトリを混在させて指定してもかまいません.
mkfgenは only_list で指定されたパスがファイルであるのか、あるいはディレクトリであるのかを自動認識します.



目次に戻る

src_suffix_listセクション (Section Type: @@L ラインリスト)

srcファイルとして使われる拡張子を列挙しておきます.
例えば、c と cpp が混在している環境なら次のように指定します.

c
cpp

目次に戻る

This article was written by:
none image

Zenkaku

@znk project