第 2 章 Build Tools

简介:

2.1. Apache Ant

http://ant.apache.org/

2.1.1. 安装 ant

2.1.1.1. 1.8

cd /usr/local/src
wget http://mirror.bjtu.edu.cn/apache//ant/binaries/apache-ant-1.8.1-bin.tar.gz
tar zxvf apache-ant-1.8.1-bin.tar.gz
mv apache-ant-1.8.1 /usr/local/
cd ..
ln -s apache-ant-1.8.1 apache-ant
			
ANT_HOME=/usr/local/apache-ant
export CLASSPATH=$CLASSPATH:$ANT_HOME/lib
			

2.1.1.2. 1.10.1

Netkiller OSCM 一键安装

curl -s https://raw.githubusercontent.com/oscm/shell/master/lang/java/ant/apache-ant-1.10.1.sh | bash
			

2.1.2. ANT

2.1.2.1. ant.project.name

ant.project.name 一般式定义在

			
<project name="www.netkiller.cn" default="compile" basedir="." xmlns:if="ant:if">
<echo>${ant.project.name}</echo>
			
			

我们希望从命令行传递这个值

			
<project default="compile" basedir="." xmlns:if="ant:if">
<echo>${ant.project.name}</echo>
			
			

你需要将 project 中的定义去掉才能从命令行传递

			
ant -Dant.project.name=www.netkiller.cn -f build.xml
			
			

你也可以从 build.properties 文件定义 ant.project.name

			
MacBook-Pro:deployment neo$ cat build.properties 
ant.project.name=www.netkiller.cn			
			
			
			
ant -f build.xml -propertyfile build.properties	
			
			

2.1.2.2. 定义

			
			
			

2.1.3. Project

		
<description>project Name</description>
		
		

2.1.3.1. property

在 build.xml 中定义 property

			
<property name="src" value="src"/>
<property name="dest" value="classes"/>
<property name="hello" value="hello.jar"/>		
			
			

引用 properties 文件

			
<property file="build.properties" />
<propety resource="build.properties"/>
			
			

设置系统的环境变量为前缀

			
<property environment="env"/> 
<property name="tomcat.home" value="${env.CATALINA_HOME}"/> 
			
			

命令行传值,使用-D参数是会覆盖build.xml中的先前定义的变量

			
$ ant --help | grep property
  -D<property>=<value>   use value for given property
  -propertyfile <name>   load all properties from file with -D
  

	 		
			

2.1.3.2. ant

Project name

			
${ant.project.name}
			
			

2.1.3.3. environment

			
<property environment="env"/>
<echo message="JAVA_HOME is set to = ${env.JAVA_HOME}" />			
			
			

2.1.4. path

定义

		
	<path id="classpath">  
        <fileset dir="${env.JAVA_HOME}/lib">  
            <include name="*.jar" />  
        </fileset>  
        <fileset dir="${env.CATALINA_HOME}/lib">  
            <include name="*.jar" />  
        </fileset>  
        <fileset dir="WebRoot/WEB-INF/lib" includes="*.jar"/>
    </path>    
		
		

引用

		
	<javac srcdir="${src.dir}" destdir="${classes.dir}" source="1.5" target="1.5">  
		<classpath refid="classpath" />  
	</javac>		
		
		

		
    <classpath>
		<path refid="classpath"/>
    </classpath>		
		
		

2.1.5. copy

复制目录

		
	<copy todir="${basedir}/WebContent"> 
		<fileset dir="${basedir}/WebRoot" includes="**/*"/>
	</copy>	    
		
		

复制指定扩展名文件

		
	<copy todir="${dest}">  
		<fileset dir="${src}">  
			<include name="**/*.xml" />  
			<include name="**/*.properties" />  
		</fileset>
	</copy> 	
		
		

2.1.6. javac

		
	<path id="classpath">
		<fileset dir="${env.JAVA_HOME}/lib">
			<include name="*.jar" />
		</fileset>
		<fileset dir="${env.CATALINA_HOME}/lib">
			<include name="*.jar" />
		</fileset>
		<fileset dir="${project.dir}/WebRoot/WEB-INF/lib" includes="*.jar" />
	</path>

	<javac srcdir="${project.src}" destdir="${project.build}/WEB-INF/classes" debug="true" listfiles="true">
			<classpath refid="classpath" />
			<include name="**/*.java"/>
			<exclude name="**/*.xml"/>
			<exclude name="**/*.properties"/>
	</javac>
		
		

listfiles 显示编译文件列表

debug 显示调试信息,编译错误信息

2.1.7. condition

		
<?xml version="1.0"?>
<project name="test" default="doFoo" basedir=".">
  <property name="directory" value="/www/directory"/>

  <target name="doFoo" depends="dir.check" if="dir.exists">
    <echo>${directory} exists</echo>
  </target>

  <target name="doBar" depends="dir.check" unless="dir.exists">
    <echo>${directory} missing"</echo>
  </target>

  <target name="dir.check">
    <condition property="dir.exists">
      <available file="${directory}" type="dir"/>
    </condition>
  </target>
</project>		
		
		

2.1.8. exec

		
<project name="{{ name }}" default="help" basedir=".">
  
  <property name="username" value="{{ username }}"/>
  <property name="host" value="{{ host }}"/>
  <property name="dir" value="/srv/{{ path }}/"/>

  <tstamp>
    <format property="TODAY_UK" pattern="yyyyMMddhhmmss" locale="en,UK"/>
  </tstamp>

  <target name="help" description="show available commands" >
    <exec executable="ant" dir="." failonerror="true">
      <arg value="-p"/>
    </exec>
  </target>
  
  <target name="deploy-to" description="show where we are deploying to" >
    <echo>${username}@${host}:${dir}</echo>
  </target>

  <target name="deploy" description="deploy usng rsync" >
    <exec executable="rsync" dir="." failonerror="true">
      <arg value="-r"/>
      <arg value="."/>
      <arg value="${username}@${host}:${dir}"/>
      <arg value="--exclude-from=rsync.excludes"/>
      <arg value="-v"/>
    </exec>
  </target>

  <target name="deploy-test" description="test deploy usng rsync with the dry run flag set" >
    <exec executable="rsync" dir="." failonerror="true">
      <arg value="-r"/>
      <arg value="."/>
      <arg value="${username}@${host}:${dir}"/>
      <arg value="--exclude-from=rsync.excludes"/>
      <arg value="--dry-run"/>
      <arg value="-v"/>
    </exec>
  </target>

  <target name="backup" description="backup site" >
    <exec executable="scp" dir="." failonerror="true">
      <arg value="-r"/>
      <arg value="${username}@${host}:${dir}"/>
      <arg value="backups/${TODAY_UK}"/>
    </exec>
  </target>

</project>		
		
		

2.1.8.1. sshexec

			
<sshexec host="${remove}" keyfile="~/.ssh/id_rsa" command="/srv/apache-tomcat/bin/catalina.sh stop -force" />			
			
			

2.1.9. if

		
		
<if>
  <available file="my_directory" type="dir" />
  <then>
    <echo message="Directory exists" />
  </then>
  <else>
    <echo message="Directory does not exist" />
  </else>
</if>		
		
		
		

Ant 1.9.x 新增 xmlns:if="ant:if"

		
<project name="tryit"
 xmlns:if="ant:if"
 xmlns:unless="ant:unless"
>
 <exec executable="java">
   <arg line="-X" if:true="${showextendedparams}"/>
   <arg line="-version" unless:true="${showextendedparams}"/>
 </exec>
 <condition property="onmac">
   <os family="mac"/>
 </condition>
 <echo if:set="onmac">running on MacOS</echo>
 <echo unless:set="onmac">not running on MacOS</echo>
</project>


<!DOCTYPE project>
<project xmlns:if="ant:if" xmlns:unless="ant:unless">
  <property unless:set="property" name="property.is.set" value="false"/>
  <property if:set="property" name="property.is.set" value="true"/>
  <echo>${property.is.set}</echo>
</project>
		
		

2.1.10. macrodef

arg value 与 arg line

arg line 可以处理参数的空格, 而arg value则不能. arg line 可以处理空参数, arg value传递空参数会报错.

		
<exec executable = "sh" dir = "@{dir}">
	<arg line = "ls -l /var/log" />
</exec>


<exec executable = "ls" dir = "@{dir}">
	<arg value = "-l" />
	<arg value = "/var/log" />
</exec>
		
		
		
        <macrodef name="mvn">
                <attribute name="options" default="" />
                <attribute name="goal" default="" />
                <attribute name="phase" default=" " />
                <attribute name="dir" default="" />
                <element name="args" optional="false" />
                <sequential>
                        <exec executable="mvn" dir="@{dir}" >
                                <arg value="@{options}" />
                                <arg value="@{goal}" />
                                <arg value="@{phase}" />
                        </exec>
                </sequential>
        </macrodef>

<!-- 执行下面宏将会出错,你必须传递options,phase参数 -->
<mvn goal="package" dir="${project.dir}"/>
<!-- 将vale改为line后正常 -->
		<exec executable="mvn" dir="@{dir}" >
                                <arg line="@{options}" />
                                <arg line="@{goal}" />
                                <arg line="@{phase}" />
        </exec>
		
		
		

运行方式sequential为顺序执行, parallel为并行执行。

2.1.10.1. Git

			
<macrodef name = "git">
    <attribute name = "command" />
    <attribute name = "dir" default = "" />
    <element name = "args" optional = "true" />
    <sequential>
        <echo message = "git @{command}" />
        <exec executable = "git" dir = "@{dir}">
            <arg value = "@{command}" />
            <args/>
        </exec>
    </sequential>
</macrodef>
<macrodef name = "git-clone-pull">
    <attribute name = "repository" />
    <attribute name = "dest" />
    <sequential>
        <git command = "clone">
            <args>
                <arg value = "@{repository}" />
                <arg value = "@{dest}" />
            </args>
        </git>
        <git command = "pull" dir = "@{dest}" />
    </sequential>
</macrodef>
			
			
			
<git command = "clone">
    <args>
        <arg value = "git://github.com/280north/ojunit.git" />
        <arg value = "ojunit" />
    </args>
</git>

<git command = "pull" dir = "repository_path" />		

<git-clone-pull repository="git://github.com/280north/ojunit.git" dest="ojunit" />	
			
			

2.1.10.2. Rsync

			
			
	<macrodef name="rsync">
		<attribute name="option" default="auzv" />
		<attribute name="src" default="" />
		<attribute name="dest" default="" />
		<element name="args" optional="true" />
		<sequential>
			<exec executable="rsync">
				<arg value="@{option}" />
				<arg value="@{src}" />
				<arg value="@{dest}" />
				<args />
			</exec>
		</sequential>
	</macrodef>			
			
			
			
			
	<target name="deploy" depends="compile">
		<rsync option="-auzv" src="${project.dest}" dest="${remote}:${destination}">
			<args>
				<arg value="-P" />
			</args>
		</rsync>
	</target>			
			
			

2.1.10.3. SSH

			
	<macrodef name="ssh">
		<attribute name="host" />
		<attribute name="command" />
		<attribute name="keyfile" default="~/.ssh/id_rsa" />
		<element name="args" optional="true" />
		<sequential>
			<exec executable="ssh">
				<arg value="@{host}" />
				<!-- arg value="-i @{keyfile}" / -->
				<args />
				<arg value="@{command}" />
			</exec>
		</sequential>
	</macrodef>
			
			
			
	<target name="stop" depends="">
		<!-- ssh host="${remote}" command="/srv/apache-tomcat/bin/catalina.sh stop -force" keyfile="~/.ssh/id_rsa" / -->
		<ssh host="${remote}" command="/srv/apache-tomcat/bin/shutdown.sh" />
	</target>
	<target name="start" depends="">
		<ssh host="${remote}" command="/srv/apache-tomcat/bin/startup.sh" keyfile="~/.ssh/id_rsa" />
	</target>		
			
			

2.1.10.4. maven

			
        <macrodef name="mvn">
                <attribute name="options" default="" />
                <attribute name="goal" default="" />
                <attribute name="phase" default=" " />
                <attribute name="dir" default="" />
                <element name="args" optional="false" />
                <sequential>
                        <exec executable="mvn" dir="@{dir}" >
                                <arg line="@{options}" />
                                <arg value="@{goal}" />
                                <arg line="@{phase}" />
                        </exec>
                </sequential>
        </macrodef>			
			
			

2.1.11. Javascript

		

$ cat build.xml 
<project name="Attachments" default="print">
    <property name="numAttachments" value="20" />
    <target name="generate">
        <script language="javascript"><![CDATA[
            var list = '1';
            var limit = project.getProperty( "numAttachments" );
            for (var i=2;i<limit;i++)
            { 
                list = list + ',' + i;
            }
            project.setNewProperty("list", list);            
		print(list);
        ]] >
        </script>    
    </target>
</project>

		
		
		
$ ant generate
Buildfile: /www/testing/build.xml

generate:
   [script] 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19

BUILD SUCCESSFUL
Total time: 0 seconds
		
		

2.1.12. mail

https://ant.apache.org/manual/Tasks/mail.html

		
cp ~/.m2/repository/com/sun/mail/javax.mail/1.5.6/javax.mail-1.5.6.jar /srv/apache-ant-1.9.6/lib
cp /www/.m2/repository/com/sun/mail/javax.mail/1.5.6/javax.mail-1.5.6.jar /srv/apache-ant-1.10.1/lib/
		
		

Examples

		
<mail from="me"
      tolist="you"
      subject="Results of nightly build"
      files="build.log"/>
Sends an email from me to you with a subject of Results of nightly build and includes the contents of the file build.log in the body of the message.

<mail mailhost="smtp.myisp.com" mailport="1025" subject="Test build">
  <from address="config@myisp.com"/>
  <replyto address="me@myisp.com"/>
  <to address="all@xyz.com"/>
  <message>The ${buildname} nightly build has completed</message>
  <attachments>
    <fileset dir="dist">
      <include name="**/*.zip"/>
    </fileset>
  </attachments>
</mail>
		
		

2.1.13. basename

		
<basename property="jar.filename" file="${lib.jarfile}"/>
will set jar.filename to myjar.jar, if lib.jarfile is defined as either a full-path filename (eg., /usr/local/lib/myjar.jar), a relative-path filename (eg., lib/myjar.jar), or a simple filename (eg., myjar.jar).
<basename property="cmdname" file="D:/usr/local/foo.exe"
          suffix=".exe"/>
will set cmdname to foo.
<property environment="env"/>
<basename property="temp.dirname" file="${env.TEMP}"/>
			
		
		

2.1.14. FAQ

2.1.14.1. warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds

includeantruntime="false"

			
<target name="compile" depends="init">
   <javac includeantruntime="false" srcdir="${src}" destdir="${dest}"/>
</target>
			
			

or

			
<property name="build.sysclasspath" value="last"/>
			
			

2.1.14.2. 调试 exec

将 executable="echo" 设置成 echo 是一种不错的调试手段

			
        <macrodef name="gulp">
                <attribute name="stage" default=""/>
                <attribute name="src" default=""/>
                <attribute name="dir" default="" />
                <sequential>
                        <exec vmlauncher="false" executable="echo" dir="@{dir}" osfamily="unix">
                                <arg line="--stage @{stage} --src @{src}"/>
                                <!-- arg value="stage @{stage}" / -->
                        </exec>
                </sequential>
        </macrodef>

        <target name="gulp">
                <gulp stage="${git.branch}" src="cn" dir="."/>
        </target>
			
			




原文出处:Netkiller 系列 手札
本文作者:陈景峯
转载请与作者联系,同时请务必标明文章原始出处和作者信息及本声明。

目录
相关文章
|
Android开发
【错误记录】Android Studio 编译报错 ( Installed Build Tools revision 31.0.0 is corrupted )
【错误记录】Android Studio 编译报错 ( Installed Build Tools revision 31.0.0 is corrupted )
667 0
【错误记录】Android Studio 编译报错 ( Installed Build Tools revision 31.0.0 is corrupted )
|
Android开发 开发工具 IDE
Android gradle问题解决: This app has been built with an incorrect configuration. Please configure your build for VectorDrawableCompat
1. 问题描述: Android Studio在运行模拟器某些机型或者真机某些机型的时候发生闪退。 错误如下: Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.
2279 0
|
Java iOS开发
Mac编译OpenJDK8:configure: error: Xcode 4 is required to build JDK 8, the version found was 10.1config
Mac编译OpenJDK8:configure: error: Xcode 4 is required to build JDK 8, the version found was 10.1config
93 0
|
Android开发
Migrate Project to Gradle? This project does not use the Gradle build system
Migrate Project to Gradle? This project does not use the Gradle build system
78 0
|
开发工具
Dex Loader] Failed to load D:\adt-bundle-windows-x86_64-20190307\sdk\build-tools\28.0.3\lib\dx.jar
Dex Loader] Failed to load D:\adt-bundle-windows-x86_64-20190307\sdk\build-tools\28.0.3\lib\dx.jar
83 0
|
Java API Kotlin
Gradle Writing Build Scripts
The Gradle build language Gradle 构建语言 Gradle 提供了一种领域特定语言(DSL)来描述构建,这种构建语言在 Groovy 和 Kotlin 都可以使用。 Groovy 构建脚本可以包含任何 Groovy 语言元素。 Kotlin 构建脚本可以包含任何 Kotlin 语言元素。 Gradle 假设每个构建脚本都使用 UTF-8进行编码。
106 0
|
API 开发工具 Android开发
Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager.
Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager.
792 0
Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager.
dpkg-checkbuilddeps: error: Unmet build dependencies: build-essential:native
dpkg-checkbuilddeps: error: Unmet build dependencies: build-essential:native
648 0
|
JavaScript Java
|
Java Android开发 Maven
Android Studio 中无法下载com.android.tools.build:gradle:3.0.1
异常 异常.png Android Studio中无法依赖com.android.tools.build:gradle:3.0.1 解决办法 进入Maven仓库, 并进入指定版本号的Gradle页面,下载pom与jar文件,进入\studio\gradle\m2repository\com\android\tools\build\gradle\文件夹下,创建对应的版本,并将下载好的pom与jar复制进此文件夹。
4967 0