25

I want to know is it possible to configure Gradle to use one global build directory for all projects? I need this because I store all my projects in Google Drive folder (for backup and fast access from other devices) and when I build project Google Drive is loading CPU while syncing project build directory. So I want to move build directories outside of Google Drive.

Also this option will be useful for those who want to build projects using RAM disk as storage for build directory.

mixel
  • 25,177
  • 13
  • 126
  • 165
  • 2
    Aren't there any `.driveignore` file ;-) ? – Paul Verest Mar 18 '15 at 07:49
  • @PaulVerest May be. But now I do not store projects in any cloud storage and use global build directory only for build process boosting and for fast cleanup. – mixel Mar 18 '15 at 09:00
  • 2
    Try version control, like Git. – madhead Apr 08 '15 at 21:57
  • @madhead I use Git :) I stored my projects in Google Drive as backup option and to have fast access to source access via cloud from mobile and other devices. – mixel Apr 09 '15 at 06:20
  • @madhead Question was not about where to store source code but about how to create global build directory for Gradle. And that is very useful because you can place it on RAM drive and speed up Gradle builds. – mixel Apr 09 '15 at 06:27
  • @mixel Did you do measurements of RAM VS disk build? I guess you were still using HDD instead of SSD at that time. – TWiStErRob Jul 06 '16 at 17:27
  • 1
    @TWiStErRob No, I was using SSD and did not do any measurements. My primary goal was to move build directories of all projects to one place to easily clean up disk space. Now I'm not using RAM drive because it does not give be noticeable performance boost but I still have global build directory in my home directory. – mixel Jul 06 '16 at 17:41
  • 2
    @mixel Thanks for the detailed reply. A tip: consider [SSD aging](http://techreport.com/review/27909/the-ssd-endurance-experiment-theyre-all-dead), even if it's equally fast. – TWiStErRob Jul 06 '16 at 17:47

3 Answers3

60

Thanks to Peter Niederwieser. I decided to post my own answer because of additional details.

To setup global build directory you need to add these lines to ~/.gradle/init.gradle:

gradle.projectsLoaded {
    rootProject.allprojects {
        buildDir = "/path/to/build/${rootProject.name}/${project.name}"
    }
}

Nice option to have global build directory on the RAM disk.

If you are macOS (OS X) user you can do this with:

diskutil erasevolume HFS+ 'RAMDiskName' `hdiutil attach -nomount ram://XXXXXX`

where XXXXXX is a count of 512-byte blocks (for example, it's 262114 for 128MB RAM disk)

And buildDir line will be:

buildDir = "/Volumes/RAMDiskName/${rootProject.name}/${project.name}"

Also you can extend configuration to:

  1. get global build path from environment variable or fallback to build directory inside project directory;
  2. include project group in path, this makes path more unique especially if you have several projects with the same name.

~/.gradle/init.gradle:

def configProject(p, buildDir) {
    p.buildDir = "${buildDir}/${p.name}"  
    p.subprojects { s ->
        configProject(s, "${p.buildDir}")
    }
}

def buildDir = System.env.GRADLE_GLOBAL_BUILD_PATH
if (!buildDir?.trim()) {
    buildDir = "build"
}

gradle.projectsLoaded {
    if (ext.has("group")) {
        buildDir += "/${ext.group}"
    }
    configProject(rootProject, buildDir)
}

And in project settings.gradle:

gradle.ext.group = 'com.example.yourproject'

Also you can use this setting in project build.gradle to set project group but this is optional:

allprojects {
    ...
    group gradle.ext.group
}
mixel
  • 25,177
  • 13
  • 126
  • 165
7

build.gradle:

def baseDir = "/global/build/dir/$project.name"
buildDir = baseDir + "/root"
subprojects {
    buildDir = baseDir + project.path.replaceFirst(":", "/").replace(":", ".")
}
Peter Niederwieser
  • 121,412
  • 21
  • 324
  • 259
0

You could also go the opposite way. Replace the build folder with a global folder.

  1. Remove project's build folder
  2. mklink /d ...disk\path\to\project\build ...RAM\path\to\project (or ln in Unix)
  3. Build fast

You can automate this in the clean task, so a gradlew clean cleans the folder contents and recreates the link.

With some quick testing it seems that Google Drive doesn't recognize directory in junction links on Windows. It'll sync the folders, but not the contents. Weirdly if I upload files to Drive into those folders, they're synced into the local copy. But, if I delete the synced file from the disk, the deletion is not synced back. It seems links cause Drive to be one way.

TWiStErRob
  • 44,762
  • 26
  • 170
  • 254