.gprがそこそこ便利?な件について
Ada専用makefileみたいなやつです。
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gnat_ugn_unw/GNAT-Project-Manager.html
gprmakeという専用コマンドがあるものの、こちらは.gprのファイル名を指定するオプション-Pのあとにスペースを入れられないのでgprmake -Pxxx.gprとなってしまいシェルのファイル名補完機能を使えないので、gnatmake -P xxx.gprのほうが良い。というかgprmakeはgnatmakeを呼んでいるだけにしか思えないので何が違うのか不明。またgnatmakeだと、i386-pc-freebsd4-gnatmakeを使うときちんとクロスコンパイルしてくれる。i386-pc-freebsd4-gprmakeではいまいち上手くいかないので本当にgprmakeの存在意義は不明。
さて.gprですが、withだけで他の.gprが持つソースを参照パスに含めたりリンクしてくれたりします。.gprを探すのは環境変数ADA_PROJECT_PATHを見てくれ、他のパス関係のオプションは.gprからの相対で上手いことやってくれますので、ディレクトリ構成で考えることが一気に減る優れものです。
一方、makefile本来の機能であるソースファイル間の依存関係を記述する方法が無さそうです。まあまともなモジュール機構持ってる言語では、コンパイラがソースの記述を見て依存関係を勝手に把握してくれるのが正しい在り方ですので、いいっちゃあいいのですが……gnatprepやらパーサジェネレーター他が割り込む隙が無かったり、そもそも.gprの対応言語はAdaとCなんですがこれだとCでは事実上用を為さんだろと思ったりしますので、結局makefileとの併用は必須になります。
そもそもGPSというIDEのプロジェクトファイルも兼ねていたりしますので、Delphiで言う.dprからbegin以降を抜いたものみたいな扱いなのかもしれません。
なお必要も無いのに半ば無理やりAda風の文法になっているため記述はかなりめんどくさいです。そもそも詰め込めばgnatmakeのコマンドラインオプションとして一行で書けてしまいそうなところもマイナスです。条件わけや、ファイル単位で細かくオプションを使い分けるのは.gprでしかできませんが……。
自分でも誉めているのか貶しているのか良く分からんですが、とりあえずコマンドラインオプションで指定するとひたすら長くなりがちなディレクトリ関係の解決を勝手にやってくれるのは便利です。ディレクトリ関係以外では意味無さげです。
with "Ase"; with "dyayaml"; project vampire is type Target_Type is ("i686-pc-mingw32", "i386-pc-freebsd4"); Target : Target_Type := External ("TARGET", "i686-pc-mingw32"); type Build_Type is ("release", "debug"); Build : Build_Type := External ("BUILD", "debug"); for Source_Dirs use ("."); for Exec_Dir use "."; for Object_Dir use "./" & Target; for Main use ("vampire.adb"); package Builder is case Target is when "i686-pc-mingw32" => null; when "i386-pc-freebsd4" => for Executable_Suffix use ".cgi"; end case; end Builder; package Compiler is case Build is when "release" => for Default_Switches ("Ada") use ("-gnat05", "-O2", "-gnata", "-gnatwI", "-ffunction-sections", "-fdata-sections", "-fomit-frame-pointer"); when "debug" => for Default_Switches ("Ada") use ("-gnat05", "-Os", "-g", "-gnata", "-gnatwbcIjpruF"); end case; end Compiler; package Binder is case Build is when "release" => null; when "debug" => for Default_Switches ("Ada") use ("-E"); end case; end Binder; package Linker is case Build is when "release" => for Default_Switches ("Ada") use ("-s", "--gc-sections"); when "debug" => null; end case; end Linker; end vampire;