eclipseの独自ant taskを触ってみる
自メモ)
eclipseはformatterだけ分離できれば…
@grimrose あーーーそういうの欲しいですね。Goみたいに言語として持ってるのも出てきてるくらいだし、今より一般的になるとちょっと楽かも。
@toru_inoue 会社で共通のformatter使ってると、それだけのために古いeclipse立ち上げるのが面倒で…
2013-12-11 00:49:09 via YoruFukurou to @toru_inoue
@grimrose わぁ
@toru_inoue antで出来ないかいろいろ探して見ましたが、どうやら根深そうなので断念しました…
2013-12-11 00:51:06 via YoruFukurou to @toru_inoue
@grimrose eclipseをコマンドライン実行してフォーマッター実行とかは難しいんですかね? 自分もeclipseの eclipse.refreshLocal antタスクとか遣りたいけどUI上から実行なネタ情報しか出てこなくて結構面倒臭いなと思ってたり<汗
2013-12-11 00:54:15 via YoruFukurou to @grimrose
@kimukou2628 似たような感じですね。コマンドラインからやる方法らしきものはあったと思いますが、結局eclipse無いとダメなので諦めました…
eclipseで用意されてるAntTask)
task名 | task class path | task効果 |
---|---|---|
eclipse.refreshLocal | org.eclipse.core.resources.ant.RefreshLocalTask | 指定プロジェクトの更新 |
eclipse.incrementalBuild | org.eclipse.core.resources.ant.IncrementalBuild | プロジェクトをビルド(incremental, full, clean ) |
eclipse.convertPath | org.eclipse.core.resources.ant.ConvertPath | 相対パスをリアルパスに変換 |
- eclipse.refreshLocalの記述例
- プロジェクト project1 をリフレッシュ(F5)する。
<eclipse.refreshLocal resource="../project1" depth="infinite" />
<eclipse.incrementalBuild kind="full" />
-
- プロジェクト project1 をクリーンする。
<eclipse.incrementalBuild project="project1" kind="clean" />
- eclipse.convertPathの記述例
eclipse-taskを含んだ build.xmlを実行する標準的な方法)
以前
な方法をググッて見つけてはいたんだけど、やっぱり重いので
antでどうにか出来ないか見てみる。
PS)
因みに上記は情報古すぎて動かないのが多いので
- eclipse and me: Headless Build for Beginners - part I
- eclipse and me: Headless Build for Beginners - part II
- eclipse and me: Headless Build for Beginners - part III
- eclipse and me: Headless Build for Beginners - part IV
- eclipse and me: Headless Build for Beginners - part V
辺になるかも。。。(汗。でもコレでも古い。。。
自分がなんでコレ遣りたいか調べてたかというと
- library-projetを含めたapkを生成するためにant-build
- 本体プロジェクト側library-projetをXXXX.jarという形で本体が参照してる
- これがant-buildのタイミングで消えるのでプロジェクトが真っ赤になる
これをant-buildだけでなんとかしたい。
という形
ではantパスを通す方針で動かしてみます
android update project -p ./
と最新のADTで実行するとプロジェクト直下に
が作成されます。
カスタムのタスクを追加するのは custom_rules.xml 追記が
がお作法になっているようなので下記のように記述します
- custom_rules.xml
<?xml version="1.0" encoding="UTF-8"?> <project name="custom_rules"> <loadproperties srcFile="local.properties" /> <property name="out.final.file.change" location="${out.dir}/../${release.app.name}_${release.app.version}.apk" /> <target name="aftert-copy"> <copy file="${out.final.file}" tofile="${out.final.file.change}"/> <copy file="${out.dir}/proguard.txt" tofile="${out.dir}/../proguard.txt"/> </target> <target name="aftert-copy-install" depends="uninstall"> <exec executable="${adb}" failonerror="true"> <arg line="${adb.device.arg}" /> <arg value="install" /> <arg value="-r" /> <arg path="${out.final.file.change}" /> </exec> </target> <property name="launch-package" value="com.irof.irof_history" /> <property name="launch-activity" value=".IrofActivity" /> <target name="apk-launch"> <echo message=" ==== apk-launch start ===="/> <exec executable="${adb}" failonerror="true"> <arg line="${adb.device.arg}" /> <arg line="shell am start -a android.intent.action.MAIN" /> <arg value="-n" /> <arg line="${launch-package}/${launch-activity}" /> </exec> <echo message=" ==== apk-launch end ===="/> </target> <!--eclipse4.4ベースで追加--> <property name="eclipse.home" value="/Users/XXXX/eclipse44" /> <path id="classpath_eclipse_task"> <pathelement location="factory/resources-ant.jar" /> <fileset dir="${eclipse.home}/plugins"> <include name="org.eclipse.equinox.common_*.jar" /> <include name="org.eclipse.core.resources_*.jar" /> <include name="org.eclipse.core.jobs_*.jar" /> <include name="org.eclipse.core.runtime_*.jar" /> <include name="org.eclipse.osgi_*.jar" /> </fileset> </path> <target name="refresh"> <fail unless="eclipse.running" message="[refresh]need running on Eclipse"/> <echo message=" ==== refresh start ===="/> <taskdef name="eclipse.refreshLocal" classname="org.eclipse.core.resources.ant.RefreshLocalTask"> <classpath refid="classpath_eclipse_task" /> </taskdef> <eclipse.refreshLocal resource="${android.library.reference.1}" depth="infinite" /> <eclipse.refreshLocal resource="${android.library.reference.2}" depth="infinite" /> <eclipse.refreshLocal resource="${ant.project.name}" depth="infinite" /> <echo message=" ==== refresh end ===="/> </target> </project>
- local.properties
sdk.dir=/Users/XXXX/android-sdks release.app.name=irof_history release.app.version=v01g
- project.propertie
target=android-19 android.library.reference.1=../QuickActionLib android.library.reference.2=../NakamapSDK
eclipseのカスタムタスク自体は
ECLIPSE_HOME/plugin の中に格納されていて
- org.eclipse.core.resources_3.9.0.v20130917-1718.jar
- ant_tasks
- resources-ant.jar
- ant_tasks
という形で格納されています。ただjarの内部のjarの指定が分からないので
とりあえず解凍して
プロジェクト直下の factoryフォルダに突っ込みます。
で実行していってエラーになるものの関連jarを芋づるで引っ張ってきた形が
上記のbuild.xmlとなります。
でここまで対応して実行すると
<groovy.util.AntBuilder@109ce4a3 log=java.util.logging.Logger@3152bdc7 project=org.apache.tools.ant.Project@48baa31b antXmlContext=org.apache.tools.ant.helper.AntXMLContext@552a66ea antElementHandler=org.apache.tools.ant.helper.ProjectHelper2$ElementHandler@52cab854 antTargetHandler=org.apache.tools.ant.helper.ProjectHelper2$TargetHandler@7b0bbd42 collectorTarget=null implicitTarget= lastCompletedNode=null insideTask=false saveStreams=true current=null nameMappingClosure=null proxyBuilder=groovy.util.AntBuilder@109ce4a3> Caught: /Users/XXXX/Documents/workspace/irof_history/custom_rules.xml:47: java.lang.IllegalStateException: Workspace is closed. /Users/XXXX/Documents/workspace/irof_history/custom_rules.xml:47: java.lang.IllegalStateException: Workspace is closed. at org.apache.tools.ant.IntrospectionHelper.extractBuildException(IntrospectionHelper.java:813) at org.apache.tools.ant.IntrospectionHelper.setAttribute(IntrospectionHelper.java:410) at org.apache.tools.ant.RuntimeConfigurable.maybeConfigure(RuntimeConfigurable.java:403) at org.apache.tools.ant.RuntimeConfigurable.maybeConfigure(RuntimeConfigurable.java:346) at org.apache.tools.ant.Task.maybeConfigure(Task.java:202) at org.apache.tools.ant.UnknownElement.configure(UnknownElement.java:196) at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:163) at org.apache.tools.ant.Task.perform(Task.java:347) at org.apache.tools.ant.Target.execute(Target.java:392) at org.apache.tools.ant.Target.performTasks(Target.java:413) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399) at org.apache.tools.ant.Project.executeTarget(Project.java:1368) at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41) at org.apache.tools.ant.Project.executeTargets(Project.java:1251) at _apkinstall_builder.run(_apkinstall_builder.groovy:38) Caused by: java.lang.IllegalStateException: Workspace is closed. at org.eclipse.core.resources.ResourcesPlugin.getWorkspace(ResourcesPlugin.java:407) at org.eclipse.core.resources.ant.RefreshLocalTask.setResource(RefreshLocalTask.java:106) at org.apache.tools.ant.IntrospectionHelper$AttributeSetter.setObject(IntrospectionHelper.java:1498) at org.apache.tools.ant.IntrospectionHelper.setAttribute(IntrospectionHelper.java:405) ... 13 more
で メモリ上のworkspace情報を参照しようとしてコケる形のようです。
eclipseコマンドラインで なまじ -data でworkspaceを指定してるわけではありません(汗
備考)
resources-ant.jar の指定に関してはググると
の話が出てきますが*1、
これは plugin taskの中の antTaskという属性がある なので使えません><
らへんの 話。
<!--OK case --> <pathelement location="factory/resources-ant.jar" /> <!--NG case --> <pathelement location="jar:${eclipse.home}/plugins/org.eclipse.core.resources_*.jar!/ant_tasks/resources-ant.jar" />
もダメポでしたorz
ここらへんのClassLoader的仕組みはjavaで書かないと面倒な話が書いてたりします
libraryタグも多分同じようなことしてるんだろうな。。。
で、コンセプトを変えてeclipseを antでコマンドラインタスクで実行で遣る方法を
考えてみます。
ただeclipse自体をコマンドライン実行した場合、
eclipseのGUIをたちあげた状態だとworkspace-locがかかります。
eclipseのexecLancherがどうも防いでいるようなので
lancher.jarの方を操作する方向が良さそうです
で調べてみると
辺りの antRunner のmacrodefを上手く流用すれば出来そうです
- custom_rules.xml (追記)
<path id="equinox.launcher.path"> <fileset dir="${eclipse.home}/plugins"> <include name="org.eclipse.equinox.launcher_*.jar" /> </fileset> </path> <macrodef name="antRunner"> <!-- Ant script location --> <attribute name="antFile" default="build.xml"/> <!-- the arguments for the script that is executed --> <attribute name="args" default=""/> <sequential> <available file="${eclipse.home}" property="eclipse.running" /> <java fork="true" output="result_@{args}.txt" outputproperty="cmdOut_@{args}" classname="org.eclipse.equinox.launcher.Main" failonerror="true"> <arg line="-verbose" /> <arg line="-data ../" /> <arg line="-application org.eclipse.ant.core.antRunner" /> <arg line="-f @{antFile}" /> <arg line="@{args}"/> <classpath refid="equinox.launcher.path" /> </java> <echo message="[@{args}] ${cmdOut_@{args}}"/> </sequential> </macrodef> <target name="refresh_exec"> <antRunner args="refresh" /> </target>
で、[clean,debug,refresh_exec]
とタスク設定を実行すると eclipse上からの外部実行でも
task自体の実行は問題なくOKでした。
PS)
<java fork="true"
としていると eclipse上だとコンソールには処理結果がでない形です。
で
外すとコンソールにはでますが
outputproperty あたりの出力は出力されない感じ*2
なんか痛し痒しですね。。。
ただ、refreshかけるだけで本リビルドまではかからないようです。
だったので 外部実行経由がコケてる? という話だけではないようです。
ここらへんは実は eclipse.incrementalBuild の方が正しいのかもしれない。
で下記に追加してみる
- custom_rules.xml (追記)
<property name="android.library.reference.project.1" value="/NakamapSDK" /> <property name="android.library.reference.project.2" value="/QuickActionLib" /> <target name="incremental"> <fail unless="eclipse.running" message="[incremental]need running on Eclipse"/> <echo message=" ==== incremental start ===="/> <!-- <antTask library="ant_tasks/resources-ant.jar" name="eclipse.incrementalBuild" classname="org.eclipse.core.resources.ant.IncrementalBuild" loaderref="hmant"> <classpath refid="classpath_eclipse_task" /> </antTask> --> <taskdef name="eclipse.incrementalBuild" classname="org.eclipse.core.resources.ant.IncrementalBuild" loaderref="hmant"> <classpath refid="classpath_eclipse_task" /> </taskdef> <eclipse.incrementalBuild project="${android.library.reference.project.1}" kind="clean" /> <eclipse.incrementalBuild project="${android.library.reference.project.2}" kind="clean" /> <eclipse.incrementalBuild project="${ant.project.name}" kind="clean" /> <echo message=" ==== incremental end ===="/> </target>
なタスクを追加してみましたが
な感じでした。UI依存部分がなんか引っかかってしまっているのかも。。(汗
Ant書くのに参考にした資料)
- Ant「antcallタスク」メモ(Hishidama's ant-antcall Memo)
- Ant「execタスク」メモ(Hishidama's ant-exec Memo)
- Ant「javaタスク」メモ(Hishidama's ant-java Memo)
なんか世の中は gradleマンセーになってるけど
antもマダマダ奥が深いな〜とか思ってたりもしてます*3
gradle前提のASって
あれ「初心者向け開発ツール」ってやたら喧伝されてるけど
大丈夫なんだろうか?って思っちゃったりもしますね(苦笑