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 fond of simple and straightforward code, coming 
from assembly myself, 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

Reply via email to