66

I create a simple project in AndroidStudio with a few modules. Each module's gradle script contains the following code:

android {
    compileSdkVersion 18
    buildToolsVersion "18.1.1"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 18
    }
}

How can I move this code to the main build.gradle script (project's script)? This code is common for all the submodules.

HotIceCream
  • 2,271
  • 2
  • 19
  • 27

9 Answers9

64

You could create a build.gradle at the root of your project (i.e. the folder that contains all your modules), and use it to configure your rootProject.

For instance, if you have:

MyApp
  - Module1/
      - build.gradle
  - Module2/
      - build.gradle
  - settings.gradle

You can add a build.gradle next to settings.gradle.

In the example above you actually have 3 Gradle projects: Module1, Module2 and the rootProject.

So inside this build.gradle, you could do:

// use the ext object to add any properties to the project
project.ext {
   compileSdkVersion = 18
}

Then in your modules, you can do:

android {
    // here we reference the root project with the "rootProject" object.
    compileSdkVersion rootProject.ext.compileSdkVersion
}
Sufian
  • 6,405
  • 16
  • 66
  • 120
Xavier Ducrohet
  • 28,383
  • 5
  • 88
  • 64
  • this doesn't work with gradle plugin 0.12.2 and gradle 1.1 `Could not find method compileSdkVersion() for arguments [20] on root project 'android'.` – Roman Oct 15 '14 at 08:52
  • 8
    Change `compileSdkVersion 18` to `compileSdkVersion = 18` – VenomVendor Oct 22 '14 at 22:29
34

Defining this in the top-most build.gradle seems to work

subprojects {
    afterEvaluate {project ->
        if (project.hasProperty("android")) {
            android {
                compileSdkVersion 22
                buildToolsVersion '22.0.1'
            }
        }
    }
}
user4979992
  • 341
  • 3
  • 2
  • I used this handy approach in conjuction with this: http://stackoverflow.com/questions/20827885/android-studio-0-4-duplicate-files-copied-in-apk-meta-inf-license-txt – CasualT Jun 25 '15 at 00:06
  • 2
    This works otherwise nicely, but this way no subproject can override the default value. You should check for compileSdkVersion and buildToolsVersion existence before setting the values. – Kung Foo Mar 30 '16 at 12:05
  • it works well,this config will override all subproject. – androidmalin Apr 10 '18 at 09:11
  • Great! I used it to patch just one value in a git submodule: `project(':submoduleName') { afterEvaluate { project -> android { defaultConfig { minSdkVersion 19 }}}}` – Giszmo Sep 16 '20 at 15:52
13

This works for me in Android Studio 0.8.9. using the default gradle wrapper 1.12-all.

App is a library used by Lite and Pro where Lite/Pro are two different flavours of the app I'm making. I wanted to share config between all modules. The global config is located in the root gradle.build file and all subprojects/modules can read these properties.

My project structure is:

Project/
 gradle.build
 settings.gradle
 App/
  gradle.build
 Lite/
  gradle.build
 Pro/
  gradle.build

In Project/gradle.build I've added a subprojects config:

subprojects {
    ext.global_compileSdkVersion = 19
    ext.global_buildToolsVersion = "20.0.0"
    ...
}

ext.[var name] adds variables whch can be read in the subprojects. I've added the prefix "global_" so it will be easier to see my properties. (Also note that I'm using an equals sign to assign the value to the variable)

In each subproject/module the gradle file looks like this:

android {
    compileSdkVersion global_compileSdkVersion
    buildToolsVersion global_buildToolsVersion
    ...
}

Note!

The Android Studio IDE doesn't seem to know about "ext" in subprojects, but gradle does. So it shows up as a warning when viewing the gradle files, but builds will still work. Because it doesn't know about "ext" it doesn't seem to know about the varables you add either, so these will also be underlined in the IDE as warnings. But it works :)

Peter
  • 1,006
  • 7
  • 15
11

Hmm interesting that I did not find solution that works as I expet it should in Android Studio. But only this solution I present here works so there is no warning in Android Studio editor and works.

define in root build.gradle as everybody do:

buildscript {
    ext {
        projectAppCompatVersion = 'com.android.support:appcompat-v7:23.3.0'
        projectSupportVersion = 'com.android.support:support-v4:23.3.0'
        projectCompileSdkVersion = 23
        projectMinSdkVersion = 22      // 15 android 4.0.3 for release
        projectTargetSdkVersion = 23   //23 requires permission requests , 22 for release
        projectBuildToolsVersion = "24.0.0rc2"
    }
 }

and to access without warnings:

compileSdkVersion project.properties.projectCompileSdkVersion
buildToolsVersion project.properties.projectBuildToolsVersion

but code completion and variables resolution is not working as I would expect for android studio.

Renetik
  • 5,887
  • 1
  • 47
  • 66
6

In build.gradle of main project you should write something like next:

project.extensions.add("buildToolsVersion", "19.0.3")

In subproject you can use this extensions:

buildToolsVersion rootProject.buildToolsVersion

More info you can find here

HotIceCream
  • 2,271
  • 2
  • 19
  • 27
  • This doesn't quite work: Could not determine the dependencies of task ':myproject:mysubproject:compileDebugJava'. > android.buildToolsVersion is missing! As you can see, the android closure is missing – Markw May 07 '14 at 16:30
5

Create a custom property for your project. To set a single property use:

project.ext.compileSdkVersion = 21

to set multiple properties use:

project.ext {
    compileSdkVersion = 21
    buildToolsVersion = "21.0.1"
    targetSdkVersion = 21
}
brunodles
  • 913
  • 8
  • 9
2

Simply referencing 'android' closure from top level build doesn't work if top level build is not an android build. The 'android' method is not available until after evaluate. Originally, I had a working solution based on setting the config afterEvaluate but it no longer works (Android Studio 0.6.0):

Android tasks have already been created. This happens when calling android.applicationVariants, android.libraryVariants or android.testVariants. Once these methods are called, it is not possible to continue configuring the model.

Markw
  • 141
  • 1
  • 10
2

There is a new way simpler method, in the updated Android Studio. You have a file named "gradle.properties" in the top project hierarchy exactly for that. Simply define your parameters there:

common_parameter='I am common"

And use it in the modules' gradle files (build.gradle) as such:

module_parameter = common_parameter

That's it.

Ronen Rabinovici
  • 8,680
  • 5
  • 34
  • 46
  • It does not work for me using gradle 2.14.1, I get the error `Error:(24, 1) A problem occurred evaluating root project 'MyRootProject'. > Could not set unknown property 'common_parameter' for project ':MySubLibraryProject' of type org.gradle.api.Project.` – arberg Sep 09 '16 at 06:50
0

You can define version in project level gradle.properties, for example:

In gradle.properties file:

TARGET_SDK_VERSION = 33
COMPILE_SDK_VERSION = 33
BUILD_TOOLS_VERSION = 33.0.0

Then, use it in module build.gradle:

android {
    compileSdkVersion COMPILE_SDK_VERSION.toInteger()
    buildToolsVersion BUILD_TOOLS_VERSION

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion TARGET_SDK_VERSION
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    ...

Pay attention to compileSdkVersion, it will need an extra .toInteger() call.

Glorin
  • 160
  • 2
  • 7