DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • On SBOMs, BitBucket, and OWASP Dependency Track
  • Why Do We Need to Keep Our Builds Green?
  • Understanding Dependencies...Visually!
  • DevOps Fast Forward with Go

Trending

  • Is Agile Right for Every Project? When To Use It and When To Avoid It
  • Automating Data Pipelines: Generating PySpark and SQL Jobs With LLMs in Cloudera
  • 5 Subtle Indicators Your Development Environment Is Under Siege
  • The Human Side of Logs: What Unstructured Data Is Trying to Tell You
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Introducing Source Dependencies in Gradle

Introducing Source Dependencies in Gradle

Want to learn more about the newest source dependencies? Check out this post to learn more about Gradle dependency management.

By 
Adam Murdoch user avatar
Adam Murdoch
·
Oct. 04, 18 · Presentation
Likes (3)
Comment
Save
Tweet
Share
17.9K Views

Join the DZone community and get the full member experience.

Join For Free

This post introduces a new Gradle dependency management feature called “source dependencies."

Normally, when you declare a dependency on a library, Gradle looks for the library’s binaries in a binary repository, such as JCenter or Maven Central, and downloads the binaries for use in the build.

Source dependencies allow you to, instead, have Gradle automatically check out the source for the library from Git and build the binaries locally on your machine, rather than downloading them.

We’d love to get your feedback on this feature. Please try it out and let us know what works for you and any problems you run into. You can leave feedback on the Gradle forums or raise issues on the Gradle native GitHub repository.

You should be aware that this feature is currently incubating and may change in breaking ways in future releases of Gradle. Please do not use this feature in production until the feature is promoted to stable in a future release.

How Can you Try It?

You can find many samples that use source dependencies in the native-samples repository. C++ builds are a natural place to use source dependencies, but this isn’t a C++ specific feature. Source dependencies work for any type of build that use Gradle’s dependency management features, such as Java, Kotlin, or Android builds. You can try this feature out with the latest Gradle 4.10 or a nightly.

Let’s look at an example application. This sample shows an application that uses a library that lives in a separate Git repository.

A source dependency looks the same as a binary dependency in the build file. You declare a dependency on a particular version of a module, such as a library. Here, our sample needs version 1.0 of the “utilities” library:

dependencies {
    implementation 'org.gradle.cpp-samples:utilities:1.0'
}


You also need to tell Gradle where to find the source for the library. This is similar to how you need to tell Gradle where to find binaries by defining some binary repositories in your build, however, the syntax is different. In the settings.gradle file, we define a source mapping:

sourceControl {
    gitRepository("https://github.com/gradle/native-samples-cpp-library.git") {
        producesModule("org.gradle.cpp-samples:utilities")
    }
}


Now, when Gradle needs to find a version of the “utilities” library, it will look for a matching tag in the Git repository. Gradle will check out the matching Git tag, build the binaries, and make the result available. This works the same way as an included build.

Here’s the result of running gradle assemble on this sample:

> Task :native-samples-cpp-library:list:compileDebugCpp
> Task :native-samples-cpp-library:utilities:compileDebugCpp
> Task :native-samples-cpp-library:list:linkDebug
> Task :compileDebugCpp
> Task :native-samples-cpp-library:utilities:linkDebug
> Task :linkDebug
> Task :installDebug
> Task :assemble

BUILD SUCCESSFUL in 4s
3 actionable tasks: 3 executed


Gradle has cloned the source of the libraries, built the library binaries, and then linked the application against these.

You can also declare a dependency on a branch, using a slightly different syntax. This example application demonstrates how to do this.

dependencies {
    implementation('org.gradle.cpp-samples:utilities') {
        version {
            branch = 'release'
        }
    }
}


Source dependencies work for plugins too, but currently, they need some additional configuration in the settings.gradle in order to work. This example library shows how to do this.

What Are Source Dependencies Useful For?

Source dependencies are useful when the binaries for a module that you use are not available in a binary repository. For example:

  • When you’re working off a branch of a library and binaries that have not yet been published for this branch, for example, you may want to use a bug fix from a branch that has not yet been merged or released.
  • When you’re using a library that publishes a source and no binaries, this is common for C++ libraries and applications where the libraries are released in source form only and you have to build your own binaries.
  • When you’re using a native library that does not publish binaries for your target platform, it is common for a C++ library or application to publish binaries only for certain common operating systems or toolchains. To use the library on other platforms, you have to build your own binaries.
  • When you don’t want to have to wait for another system, such as a CI server, to publish binaries for a dependency, for example, you might want to experiment with changes to several libraries.

Source dependencies make these use cases simpler to implement. Gradle takes care of automatically checking out the correct versions of dependencies, making sure the binaries are built when required. It does this everywhere that the build is run. The checked out project doesn’t even need to have an existing Gradle build. This example shows a Gradle build consuming two source dependencies that have no build system by injecting a Gradle build via plugins. The injected configuration could do anything a regular Gradle plugin can do, such as wrapping an existing CMake or Maven build.

Source dependencies can be combined with the Gradle build cache to make these use cases efficient when everyone on your team is building the same dependencies from source. The Gradle build cache ensures that once the binaries have been built, they are reused everywhere else.

Source dependencies can be used alongside binary dependencies, and you can mix and match so that some dependencies are built from source and others are downloaded as binaries. Source dependencies also work nicely with composite builds.

How Is This Different From a Composite Build?

Mostly, it’s not. Source dependencies are based on Gradle’s composite build feature and add automatic provisioning of the source code to help with some specific use cases.

Source dependencies are different to included builds in intent. An included build represents some module that you are currently working on. Dependency resolution will always use binaries from the included build — regardless of which version of the module is requested in the build — so that you can see the effect of your changes.

A source dependency, on the other hand, represents some module that you use, but that just happens to be available in source form rather than binary form. Dependency resolution will always select a version of the source dependency that matches whatever is requested in the build. With an included build, you can modify sources and directly see the changes, but with source dependencies, you need to commit and push changes before you can see their effect.

Missing Features

Source dependency support is very much experimental and missing some important features:

  • Build scans do not yet support builds that use source dependencies.
  • IDE support is mostly not yet available. Most IDE integrations will fail with an error when source dependencies are used by the build. Source dependencies are currently only supported by Gradle’s Xcode integration for C++.
  • Dependency locking does not support source dependencies.
  • Source dependencies also have the same restrictions as included builds.
  • You cannot have a source dependency on a build that contains included builds. However, you can have a source dependency on a build that uses source dependencies.
  • You cannot yet mix source and binary dependencies for a particular module. Each module must come either from a Git repository or from a binary repository, but not both.
  • Only Git repositories are supported.

Roadmap

We’d like to get your feedback and based on this implement the missing features listed above. Once we’re happy that the DSL and APIs are useful and behave well, we will promote the feature to stable. Let us know what you think on the Gradle forums or the Gradle native GitHub repository.

Dependency Gradle Continuous Integration/Deployment

Published at DZone with permission of Adam Murdoch, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • On SBOMs, BitBucket, and OWASP Dependency Track
  • Why Do We Need to Keep Our Builds Green?
  • Understanding Dependencies...Visually!
  • DevOps Fast Forward with Go

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: