dweiss commented on a change in pull request #2068: URL: https://github.com/apache/lucene-solr/pull/2068#discussion_r523406193
########## File path: gradle/native/disable-native.gradle ########## @@ -17,20 +17,65 @@ // This is the master switch to disable all tasks that compile // native (cpp) code. -def buildNative = propertyOrDefault("build.native", true).toBoolean() +rootProject.ext { + buildNative = propertyOrDefault("build.native", true).toBoolean() +} + +// Explicitly list all projects that should be configured for native extensions. +// We could scan for projects with a the cpp-library plugin but this is faster. +def nativeProjects = allprojects.findAll {it.path in [ + ":lucene:misc:native" +]} + +def javaProjectsWithNativeDeps = allprojects.findAll {it.path in [ + ":lucene:misc" +]} + +// Set up defaults for projects with native dependencies. +configure(javaProjectsWithNativeDeps, { + configurations { Review comment: Right. This is gradle deep-waters but not too complicated once you get the hang of it. I am personally font of simple and straightforward code, coming from assembly, but these days it's hard to avoid higher-level constructs. Sorry about this! So, the code you asked about essentially applies ('configure') a code block (secont argument to configure - the closure) to all objects that are in the collection that is the first argument to configure. When you look at that patch we create two such collections - nativeProjects and javaProjectsWithNativeDeps, each one with Project instances that match a corresponding path. This is very much as if you copy-pasted the same code in each gradle.build of each corresponding project - avoids repetition, centralises common configuration. The inside of this closure block is where things get more interesting and more gradle-sque. The "configurations" block is a project property that declares the project's configurations to which artifacts (or dependencies) can be added. You should understand how this works because this is the core of how it works. See here, for example (gradle documentation is very good, if sometimes scattered across multiple documents): https://docs.gradle.org/current/userguide/dependency_management.html#declaring-dependencies So, for any project in javaProjectsWithNativeDeps we declare a configuration called "nativeDeps". To this configuration we will attach a dependency to a "native" project - our cpp-library modules. In case of :lucene:misc we attach it inside build.gradle: ``` nativeDeps project(":lucene:misc:native") ``` Then the code declares two project "extra (ext) properties - testOptions and nativeDepsDir. The testOptions is a an array we use to collect various test attributes from bits and pieces of configuration scattered around other files. To make the evaluation work in the right order (ensure the array is there) we put everything in a deferred-execution block (this is why plugins.withType(JavaPlugin) stuff is needed...). Finally, we apply a code closure configuring any of the project's tasks that have the type "Test", adding java.library.path system property pointing at the nativeDepsDir property location and a dependency on a task that will copy all dependencies (artifacts produced by dependencies attached to the nativeDeps configuration) to that folder. These two steps are only needed if we indeed plan to run with native libraries so they're wrapped in an 'if'. > and the copyNativeDeps task below copies only the needed library artifact without all the nested folder structure It actually synchronizes the state of the target folder with source files. Note that the "source" files are pointed to by the configuration (artifacts produced by this configuration dependencies). The cpp-library produces *multiple* configuration variants (debug, release - with possibly multiple artifacts). This is where it gets tricky and this is why we declared the nativeDeps configuration with some "attributes" that allow gradle to pick just one of the produced configurations out of multiple choices. In most Java projects you'd never have to use this but you combined cpp and java. Try removing those attributes from configuration definition and see what happens. Then see this: https://docs.gradle.org/current/userguide/variant_model.html Sorry for throwing so much on you but you asked for it! :) ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org For additional commands, e-mail: issues-h...@lucene.apache.org