Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Introduction to Gradle
Search
Gasol Wu
September 15, 2012
Programming
2
270
Introduction to Gradle
Gasol Wu
September 15, 2012
Tweet
Share
More Decks by Gasol Wu
See All by Gasol Wu
Behat - BDD for PHP
gasol
3
1.1k
Buffering Requirement for Lossless Vertical handoffs in Wireless Overlay Networks
gasol
0
32
Other Decks in Programming
See All in Programming
おやつのお供はお決まりですか?@WWDC25 Recap -Japan-\(region).swift
shingangan
0
140
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
660
レベル1の開発生産性向上に取り組む − 日々の作業の効率化・自動化を通じた改善活動
kesoji
0
260
効率的な開発手段として VRTを活用する
ishkawa
0
150
20250704_教育事業におけるアジャイルなデータ基盤構築
hanon52_
5
880
技術同人誌をMCP Serverにしてみた
74th
1
680
GPUを計算資源として使おう!
primenumber
1
190
Webの外へ飛び出せ NativePHPが切り拓くPHPの未来
takuyakatsusa
2
570
フロントエンドのパフォーマンスチューニング
koukimiura
4
1.5k
すべてのコンテキストを、 ユーザー価値に変える
applism118
4
1.4k
High-Level Programming Languages in AI Era -Human Thought and Mind-
hayat01sh1da
PRO
0
830
MCPを使ってイベントソーシングのAIコーディングを効率化する / Streamlining Event Sourcing AI Coding with MCP
tomohisa
0
150
Featured
See All Featured
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
740
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.7k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Speed Design
sergeychernyshev
32
1k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
The Pragmatic Product Professional
lauravandoore
35
6.7k
Visualization
eitanlees
146
16k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
107
19k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
4 Signs Your Business is Dying
shpigford
184
22k
Transcript
Introduction to Gradle Gasol Wu 2012/9/15
Who am I • Work at KKBOX • http://github.com/Gasol •
Twitter @gasolwu
Build System History 3 2 +
The Problem is ... <XML/>!
<?xml version="1.0"?> <project name="simple" default="dist" basedir="."> <property name="src" location="src/main/java"/> <property
name="srcTest" location="src/test/java"/> <property name="build" location="build"/> <property name="dist" location="${build}/lib"/> <property name="version" value="1.0-SNAPSHOT" /> <path id="classpath.compile"> <pathelement location="libs/commons-lang-2.5.jar"/> </path> <path id="classpath.test"> <pathelement location="libs/junit-4.8.2.jar"/> <pathelement location="libs/commons-lang-2.5.jar"/> <pathelement location="${srcTest}"/> <pathelement location="${build}/classes"/> <pathelement location="${build}/test-classes"/> </path> <target name="init"> <mkdir dir="${build}/classes"/> <mkdir dir="${build}/test-classes"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}/classes"> <classpath refid="classpath.compile"/> </javac> </target> <target name="testCompile" depends="compile"> <javac srcdir="${srcTest}" destdir="${build}/test-classes"> <classpath refid="classpath.test"/> </javac> </target> <target name="test" depends="testCompile"> <junit fork="yes" haltonfailure="yes"> <batchtest fork="yes"> <fileset dir="${srcTest}"> <include name="**/*Test.java"/> </fileset> </batchtest> <classpath refid="classpath.test"/> <formatter type="plain"/> </junit> </target> <target name="dist" depends="test"> <mkdir dir="${dist}"/> <jar jarfile="${dist}/coc-comparison-${version}.jar" basedir="$ {build}/classes"/> </target> <target name="clean"> <delete dir="${build}"/> </target> </project> <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>grId</groupId> <artifactId>coc-comparison</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> </dependencies> <properties> <maven.compiler.target>1.6</maven.compiler.target> <maven.compiler.source>1.6</maven.compiler.source> </properties> </project> apply plugin: 'java' version="1.0-SNAPSHOT" group="grId" archivesBaseName="coc-comparison" repositories { mavenCentral() } dependencies { compile 'commons-lang:commons-lang:2.5' testCompile 'junit:junit:4.8.1' } 2 http://kaczanowscy.pl/tomek/2010-11/build-script-length-maven3-polyglot-maven-gradle-ant
Size Comparison Size Comparison Size Comparison chars lines Ant 1733
102 Maven 2 904 31 Gradle 224 17
• Quite verbose • Expressiveness of XML is limited •
It’s hard to trace
So, What We Really Want?
• Easy to customize and extend • Abstraction and structuring
A Better Way To Build!
Gradle • Ease of migration • Declarative builds and build-by-convention
• Rich DSL based on Groovy • Leverage both Ant and Maven • Gradle Wrapper
Gradle is Groovy Groovy is Java
// build.gradle System.out.println(“Java Way”); 4.times { print it }
> gradle Java Way 0 1 2 3 :help Welcome
to Gradle 1.2. To run a build, run gradle <task> ... To see a list of available tasks, run gradle tasks To see a list of command-line options, run gradle --help BUILD SUCCESSFUL Total time: 2.454 secs
Task task myTask task myTask { configure closure } task
myType << { task action } task myTask(type: SomeType) task myTask(type: SomeType) { configure closure}
Hello World // build.gradle task hello { doLast { println
‘Hello World!’ } } > gradle -q hello Hello World!
A shortcut task definition task hello << { println ‘Hello
World!’ }
Build scripts are code task upper << { String someString
= ‘mY_nAmE’ println “Original: $someString“ println “Upper: “ + someString.toUpperCase() } > gradle -q upper Original: mY_nAmE Upper: MY_NAME
Groovy in Gradle’s tasks task count << { 4.times {
print “$it “ } } > gradle -q count 0 1 2 3
Task dependencies task hello << { println ‘Hello World’ }
task intro(dependsOn: hello) << { println “I’m Gradle” } > gradle -q intro Hello World! I’m Gradle
Lazy dependsOn task X(dependsOn: ‘Y’) << { println ‘X’ }
task Y << { println ‘Y’ } > gradle -q X Y X
Dynamic tasks 4.times { counter -> task “task$counter” << {
println “I’m task number $counter” } } > gradle -q task1 I’m task number 1
Default tasks defaultTasks ‘clean’, ‘run’ task clean << { println
‘Default Cleaning!’ } task run << { println ‘Default Running!’ } task other << { println “I’m not a default task!” } > gradle -q Default Cleaning! Default Running!
Configure by DAG task distribution << { println "We build
the zip with version=$version" } task release(dependsOn: 'distribution') << { println 'We release now' } gradle.taskGraph.whenReady { if (it.hasTask(release)) { version = '1.0' } else { version = '1.0-SNAPSHOT' } }
Build Phases • Initialization • Configuration • The build scripts
of all projects which are part of the build are executed. • Execution
Build phases (cont.) // settings.gradle println ‘initialization phase’ // build.gradle
println ‘configuration phase’ task configured { println ‘configuration phase’ } task test << { println ‘execution phase’ }
Build phases (output) > gradle test initialization phase initialization phase
execution phase :test BUILD SUCCESSFUL Total time: 1 secs
Ant are first class citizens // build.xml <project> <property name=”gradleName”
value=”Gradle”/> <target name=”helloFromAnt”> <echo message=”Hello Ant!”/> </target> </project> // build.gradle ant.importBuild ‘build.xml’ task hello(dependsOn: helloFromAnt) << { println ‘Hello ‘ + ant.gradleName }
Ant are first class citizens (cont.) > gradle tasks --all
/* skip */ Other tasks ---------- hello helloFromAnt > gradle hello :helloFromAnt [ant:echo] Hello Ant! :hello Hello Gradle BUILD SUCCESSFUL Total time: 2.015 secs
A basic Java project apply plugin: ‘java’
Directory Structure By Default . ├── build.gradle └── src ├──
main │ ├── java │ └── resources └── test ├── java └── resources sourceSets { main { java { srcDir ‘src/main/java’ } resources { srcDir ‘src/main/resources’ } } test { java { srcDir ‘src/test/java’ } resources { srcDir ‘src/test/resources’ } } }
> gradle build :compileJava :processResources :classes :jar :assemble :compileTestJava :processTestResources
:testClasses :test :check :build BUILD SUCCESSFUL Total time: 1 secs
External Dependencies repositories { mavenCetral() } dependencies { compile group:
‘common-collections’, name: ‘common- collections’, version: ‘3.2’ testCompile ‘junit:junit:4.+’ }
More dependencies dependencies { compile project(':shared') compile files('libs/a.jar', 'libs/b.jar') runtime
fileTree(dir: 'libs', include: '*.jar') compile gradleApi() groovy localGroovy() }
More repositories repositories { mavenCentral() mavenLocal() maven { url "http://repo.mycompany.com/maven2"
} ivy { url "http://repo.mycompany.com/maven2" layout "maven" credentials { username 'user' password 'password' } } }
Customising Project apply plugin: 'java' apply plugin: 'maven' apply plugin:
'eclipse' sourceCompatibility = 1.5 version = '1.0' jar { manifest { attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version } } repositories { mavenCentral() } dependencies { compile 'commons-collections:commons-collections:3.2' testCompile 'junit:junit:4.+' } uploadArchives { repositories.mavenDeployer { repository(url: 'file://localhost/tmp/repo') } }
> tree -C /tmp/repo/ /tmp/repo/ └── quickstart └── quickstart ├──
1.0 │ ├── quickstart-1.0.jar │ ├── quickstart-1.0.jar.md5 │ ├── quickstart-1.0.jar.sha1 │ ├── quickstart-1.0.pom │ ├── quickstart-1.0.pom.md5 │ └── quickstart-1.0.pom.sha1 ├── maven-metadata.xml ├── maven-metadata.xml.md5 └── maven-metadata.xml.sha1 3 directories, 9 files
Standard Gradle Plugins • java, groovy, scala, antlr, cpp*, cpp-exe*,
cpp-lib* • announce, application, ear, jetty, maven, osgi, war, maven2Gradle • checkstyle, codearc, eclipse, ecilpse-wtp, findbugs, idea, jdepend, pmd, project-report, signing, sonar
Multi-Project? http://gradle.org/docs/current/userguide/ multi_project_builds.html
Demo • gradle-android-plugin • Writing my own plugin • git://github.com/Gasol/intro-to-gradle.git
Links • http://gradle.org/docs/current/userguide/ userguide.html • https://speakerdeck.com/u/bmuschko/p/ next-generation-builds-with-gradle-1
http://gradleware.com/registered/books/building-and-testing/
Thanks :)
Question?