Android Gradle Pluginのソースコードの位置とちょっとだけコードを追ってみたメモ

Instant Runのコードとかちょっと気になりませんか？

コードがどこにあるのかなど後で忘れそうなので、自分用メモとして残しておきます。

# ソースコードの場所の特定

https://sites.google.com/a/android.com/tools/build
https://sites.google.com/a/android.com/tools/build/gradleplugin
ここらへんをみて、
repo syncなどを行ってソースコードを取ってきました。

toolsディレクトリでプロジェクト一覧を取得するために`./gradlew projects`すると以下のように出てきました。


```
Root project 'tools'
+--- Project ':base'
|    +--- Project ':base:annotations'
省略
|    +--- Project ':base:draw9patch'
|    +--- Project ':base:dvlib'
|    +--- Project ':base:google-services'
|    +--- Project ':base:gradle'
|    +--- Project ':base:gradle-core'
|    +--- Project ':base:gradle-experimental'
|    +--- Project ':base:gradle-import'
|    +--- Project ':base:gradle-model'
|    +--- Project ':base:integration-test'
|    +--- Project ':base:jack'
|    |    +--- Project ':base:jack:jack-api'
|    |    \--- Project ':base:jack:jill-api'
|    +--- Project ':base:jobb'
|    +--- Project ':base:layoutlib-api'
|    +--- Project ':base:lint'
省略
```
https://gist.github.com/takahirom/605b24175e11e04110a4


Gradleに関係ありそうなのは
`:base:gradle` みたいです。

`./gradlew base:gradle dependencies`
で依存関係を洗ってみます。
:base:gradle-coreなどに依存しているようです。

```
compile - Compile classpath for source set 'main'.
\--- project :base:gradle-core
     +--- project :base:builder
     |    +--- project :base:builder-model
     |    |    \--- project :base:annotations
     |    +--- project :base:builder-test-api
     |    |    \--- project :base:ddmlib
     |    |         +--- project :base:common
     |    |         |    +--- project :base:annotations
     |    |         |    \--- com.google.guava:guava:17.0
     |    |         \--- net.sf.kxml:kxml2:2.3.0
     |    +--- project :base:sdklib
     |    |    +--- project :base:layoutlib-api
     |    |    |    +--- project :base:common (*)
     |    |    |    +--- net.sf.kxml:kxml2:2.3.0
     |    |    |    +--- project :base:annotations
     |    |    |    \--- com.intellij:annotations:12.0
     |    |    +--- project :base:dvlib
     |    |    |    \--- project :base:common (*)
     |    |    +--- com.google.code.gson:gson:2.2.4
     |    |    +--- org.apache.commons:commons-compress:1.8.1
     |    |    +--- org.apache.httpcomponents:httpclient:4.1.1
     |    |    |    +--- org.apache.httpcomponents:httpcore:4.1
     |    |    |    +--- commons-logging:commons-logging:1.1.1
     |    |    |    \--- commons-codec:commons-codec:1.4
     |    |    \--- org.apache.httpcomponents:httpmime:4.1
     |    |         +--- org.apache.httpcomponents:httpcore:4.1
     |    |         \--- commons-logging:commons-logging:1.1.1
     |    +--- project :base:sdk-common
     |    |    +--- project :base:sdklib (*)
     |    |    +--- project :base:builder-test-api (*)
     |    |    \--- project :base:builder-model (*)
     |    +--- project :base:common (*)
     |    +--- project :base:manifest-merger
     |    |    +--- project :base:common (*)
     |    |    +--- project :base:sdklib (*)
     |    |    +--- project :base:sdk-common (*)
     |    |    +--- net.sf.kxml:kxml2:2.3.0
     |    |    \--- com.google.code.gson:gson:2.2.4
     |    +--- project :base:ddmlib (*)
     |    +--- project :base:jack:jack-api
     |    +--- project :base:jack:jill-api
     |    +--- com.squareup:javawriter:2.5.0
     |    +--- org.bouncycastle:bcpkix-jdk15on:1.48
     |    |    \--- org.bouncycastle:bcprov-jdk15on:1.48
     |    +--- org.bouncycastle:bcprov-jdk15on:1.48
     |    +--- org.ow2.asm:asm:5.0.3
     |    \--- org.ow2.asm:asm-tree:5.0.3
     |         \--- org.ow2.asm:asm:5.0.3
     +--- project :base:lint
     |    +--- project :base:lint-checks
     |    |    +--- project :base:lint-api
     |    |    |    +--- project :base:sdk-common (*)
     |    |    |    +--- project :base:builder-model (*)
     |    |    |    +--- com.android.tools.external.lombok:lombok-ast:0.2.3
     |    |    |    |    \--- com.google.guava:guava:17.0
     |    |    |    +--- org.ow2.asm:asm:5.0.3
     |    |    |    \--- org.ow2.asm:asm-tree:5.0.3 (*)
     |    |    \--- org.ow2.asm:asm-analysis:5.0.3
     |    |         \--- org.ow2.asm:asm-tree:5.0.3 (*)
     |    \--- org.eclipse.jdt.core.compiler:ecj:4.4.2
     \--- net.sf.proguard:proguard-gradle:5.2.1
          \--- net.sf.proguard:proguard-base:5.2.1

```
https://gist.github.com/takahirom/00a0d2d7b60fc47edc19


`gradle :base:gradle:properties`
で
`projectDir: /Users/xxxxx/tools/base/build-system/gradle`
になっているので
この辺りにあるみたい
https://android.googlesource.com/platform/tools/base/+/master/build-system

そもそもGradle Pluginは
`src/main/resources/META-INF/gradle-plugins/org.samples.greeting.properties`
みたいなところに

```
implementation-class=org.gradle.GreetingPlugin
```
のような記述をして、そのファイルクラスをPluginとして読みに行くらしい
https://docs.gradle.org/current/userguide/custom_plugins.html

grepして `./gradle/src/main/resources/META-INF/gradle-plugins/com.android.application.properties`を発見

https://android.googlesource.com/platform/tools/base/+/master/build-system/gradle/src/main/resources/META-INF/gradle-plugins/com.android.application.properties

# ソースコードをちょっとだけ読む

これを参考に読む
https://docs.gradle.org/current/userguide/custom_plugins.html

https://android.googlesource.com/platform/tools/base/+/master/build-system/gradle/src/main/resources/META-INF/gradle-plugins/com.android.application.properties に記載されているので、プラグインの実態はこれみたい
`android.build.gradle.AppPlugin`

https://android.googlesource.com/platform/tools/base/+/gradle-dev/build-system/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy
BasePluginを継承していてこっちがたくさん実装されている
https://android.googlesource.com/platform/tools/base/+/cb896f5/build-system/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy#302

## Androidエクステンション `android{...}`の内容はどこに保管されている？

ここで"android{"から始まるextenstionを設定しているみたい
BasePlugin.groovy

```groovy
        extension = project.getExtensions().create("android", getExtensionClass(),
                project, instantiator, androidBuilder, sdkHandler,
                buildTypeContainer, productFlavorContainer, signingConfigContainer,
                extraModelInfo, isLibrary());
```

AppPlugin.groovy

```groovy
    @Override
    protected Class<? extends BaseExtension> getExtensionClass() {
        return AppExtension.class
    }
```

AppExtensionはgradle-coreモジュールにある模様
AppExtension
https://android.googlesource.com/platform/tools/base/+/cb896f5/build-system/gradle-core/src/main/groovy/com/android/build/gradle/AppExtension.groovy
BaseExtensionを継承している
https://android.googlesource.com/platform/tools/base/+/cb896f5/build-system/gradle-core/src/main/groovy/com/android/build/gradle/BaseExtension.groovy

ここに実際に、メンバ変数として色んなオブジェクトがあるみたい

```groovy
public abstract class BaseExtension {
    private String target
    private FullRevision buildToolsRevision
    /** Default config, shared by all flavors. */
    final ProductFlavor defaultConfig
    /** Options for aapt, tool for packaging resources. */
    final AaptOptions aaptOptions
    /** Lint options. */
    final LintOptions lintOptions
    /** Dex options. */
    final DexOptions dexOptions

```


## タスクはどこで作られている？
AppPlugin
https://android.googlesource.com/platform/tools/base/+/cb896f5/build-system/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy#57
ここでApplicationTaskManagerクラスのインスタンスを作って返している

```groovy
    @Override
    protected TaskManager createTaskManager(
            Project project,
            TaskContainer tasks,
            AndroidBuilder androidBuilder,
            BaseExtension extension,
            SdkHandler sdkHandler,
            DependencyManager dependencyManager,
            ToolingModelBuilderRegistry toolingRegistry) {
        return new ApplicationTaskManager (
                project,
                tasks,
                androidBuilder,
                extension,
                sdkHandler,
                dependencyManager,
                toolingRegistry)
    }
```

ApplicationTaskManagerは以下のようになっていて
https://android.googlesource.com/platform/tools/base/+/cb896f5/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/ApplicationTaskManager.groovy?autodive=0%2F%2F%2F%2F%2F#47

色んなタスクを追加していくみたい

```groovy
    @Override
    public void createTasksForVariantData(
            @NonNull BaseVariantData<? extends BaseVariantOutputData> variantData) {
        assert variantData instanceof ApplicationVariantData;
        ApplicationVariantData appVariantData = (ApplicationVariantData) variantData;
        createAnchorTasks(variantData);
        createCheckManifestTask(variantData);
        handleMicroApp(variantData);
        // Add a task to process the manifest(s)
        createMergeAppManifestsTask(variantData);
        // Add a task to create the res values
        createGenerateResValuesTask(variantData);
        // Add a task to compile renderscript files.
        createRenderscriptTask(variantData);
        // Add a task to merge the resource folders
        createMergeResourcesTask(variantData, true /*process9Patch*/);
```

実際にcreateTasksのメソッドが生えているのはTaskManagerクラスみたい
https://android.googlesource.com/platform/tools/base/+/cb896f5/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/TaskManager.groovy?autodive=0%2F%2F%2F%2F%2F


# Instant Runのコードを追いたい
AOSP上ではブランチがgradleのブランチが1.3までしかみつからないみたいです。
ただjcenterから落としてこれるみたい
http://jcenter.bintray.com/com/android/tools/build/gradle-core/2.0.0-alpha2/gradle-core-2.0.0-alpha2-sources.jar
jar xvf でAndroid Studio 2.0のinstant runのコードが見れる？？

com.android.build.gradle.internal.incrementalパッケージが怪しいけど少し見ただけでは全然わからないです。
読める方がいれば読んでまとめてください！