スポンサーリンク

繰り返し実行可能なコンパイルバッチ


プログラムのソースコードをコンパイルする場合,

  • (1)もしコンパイル成功したら → そこでプログラムを実際に動かしてみる。

という流れが一般的だろう。


しかし,もしコマンドラインからコンパイルや実行を実行する場合,いちいち「コンパイルバッチ」と「実行バッチ」を別々に探して動かすのは面倒だ。


(1)と(2)の操作が,スムーズにつながったら便利では。

下記ではそういうWindowsバッチを書いてみる。

例として,コンパイル対象のコードはJavaとする。

(1)実行バッチ

起動引数(OPT)付きで,JARから実行する。(JARの作り方は後述)

もし起動引数が与えられなかった場合は,デフォルトの値(DEFAULT_OPT)を使う。


下記の内容を exec_jar.bat で保存。

@echo off
set DEFAULT_OPT=10
set JARPATH=..\jar\jarname.jar
set OPT=%1
if "%1" == "" set OPT=%DEFAULT_OPT%
cls
java -jar %JARPATH% %OPT%
@pause

概説:

  • JARに引数を渡したいような場合,%1,%2 等でbatの実行時引数を取得
  • cls で画面の文字列を消去

(2)コンパイル用のAntスクリプト

Javaで,もしソースファイルが大量に存在する場合は,それらのソースを幾つかのフォルダに分けて設置することになる。


フォルダに分散させるとはつまり,クラスを幾つかのパッケージに分けるという事だ。

そして,JDKの javac コマンドには「ディレクトリ以下の全てのパッケージを再帰的にコンパイルする」という機能はない。


だから,全パッケージをまとめて一度にコンパイルしたい場合は,Apache Antなどのビルドツールを利用する必要がある。


※参考:

Antメモ
http://muimi.com/j/jakarta/ant/#WhatIs


Ant徹底活用
http://www.stackasterisk.jp/tech/java/ant01_01.jsp


DL
http://ant.apache.org/bindownload.cgi


Antのインストールや,Path,ANT_HOMEの設定が終わった段階で,下記の内容を build.xml で保存。

<project name="helloant" default="compile">
	<property name="build_dir"   value=".."/>
	<property name="src_dir"     value="${build_dir}/src"/>
	<property name="classes_dir" value="${build_dir}/classes"/>
	<property name="jar_dir"     value="${build_dir}/../jar"/>
	<property name="jar_file"    value="${jar_dir}/jarname.jar"/>
	<property name="mf_file"     value="${src_dir}/conf/MANIFEST.MF"/>
	<property name="doc_dir"     value="${build_dir}/../doc/javadoc"/>
	<property name="pack_name"   value="jp.co.〜パッケージ名〜.*"/>
	
	<target name="compile">
		<javac 
			fork="true" 
			srcdir="${src_dir}" 
			destdir="${classes_dir}"/>
	</target>
	
	<target name="jar" depends="compile">
		<jar 
			basedir="${classes_dir}" 
			destfile="${jar_file}"
			manifest="${mf_file}"/>
	</target>
	
	<target name="javadoc">
		<javadoc 
			destdir="${doc_dir}"
			packagenames="${pack_name}"
			sourcepath="${src_dir}/java"
			>
		</javadoc>
	</target>
</project>

ここでのディレクトリ構成:

build
   bin
     build.xml

   src (ソースディレクトリ)
     java
        jp
           co
              ..(以下パッケージ構成が続く)
     conf
        MANIFEST.MF

   classes  (クラス格納用ディレクトリ)

jar
   jarname.jar (完成品)

doc
   javadoc


概説:

  • ディレクトリ・ファイル名を変数として宣言したのち,targetごとにタスクを列挙。
  • Antでjavacタスクを実行する際には,fork=true を付けないとエラーになる。
  • JARに固める際には,マニフェストファイルが必要。中身は,Main-Class: でJAR実行時の起動クラスを書く。
  • javadocタスクでは,パッケージ名を指定する際に最後を * で終わらせる。そのパッケージ名のルートディレクトリを sourcepath に指定する。


ここで作ったビルド設定に基づいてビルドを行なうためには,コマンドプロンプトから

ant -buildfile build.xml compile jar

とする。buildfileオプションでXMLを読み込み,そのあとに実行したいタスク名を並べる。

(3)コンパイルバッチ

前項までの内容は,どこにでも書いてある基礎であって,ここが今回のキモになる。

build.xmlと同じフォルダに,下記の内容を compile.bat で保存。

@echo off

:start
cls

rem ----- コンパイル実行 -----

call ant -buildfile build.xml compile jar
rem call を付けないで直接呼び出すと,antの実行終了時にこのバッチも終了してしまう


rem ----- キー入力で分岐 -----

echo.
set userkey=
set /p userkey=終了する (Enter) / 再度コンパイル (o + Enter) / 成果物を実行 (p + Enter) ?
rem oはoptimize, pはplayの略のつもり。Enterから近いキーがよい。
if not '%userkey%'=='' set userkey=%userkey:~0,1%
if '%userkey%'=='o' goto start
if '%userkey%'=='p' goto exec
goto quit


:exec

rem ----- コンパイル結果を実行 -----

call exec_jar.bat

:quit

rem ----- 終了 -----

概説:

  • コンパイル実行の部分では(2)のビルドを,また最後の実行の部分では(1)のバッチを呼び出している。
  • set /p で,ユーザ入力の文字列を受け付けて,環境変数(ここではuserkeyという変数)に格納できる。
  • :~0,1 を使って,環境変数の0文字目から1文字分を切り出している。


これを実行すると,コンパイルが実行された後で,

  • 終了するか?(エンターキー)
  • 続けて再度コンパイルするか?(oを押せ)
  • コンパイル結果を実行するか?(pを押せ)

の分岐になる。


もしコンパイル時にコンパイルエラー箇所がたくさん表示されたら,ソースコードを修正してから o を押下すればよい。

もしコンパイルエラーが表示されなかったならば,すぐ p を押下すればよい。


それぞれ,開発中に何度も何度も実行するはずの操作なので,こうして連結させる事で少し快適になるはず。
(ダブルクリックの回数が減る。)

補足

上記の機能はEclipseやVisual Studioがあれば不問だけども,「重たくてIDE立ち上げたくない」という時には結構役立つ。


例えば,与えられた開発用マシンがVistaで,マシンパワー上の問題があるときなど…。*1

 

*1:IMEで,一単語の変換に数秒,Eclipseの立ち上げに数分,Excelでテーブル定義書をオープンするのに10分かかり,テスト実行時にはタイムアウトエラーが起こる。というような環境。あれは悪夢だった。