Referencing native components properly


(Mark E. Scott, Jr.) #1

I have muddled my way through getting native libraries compiled, and working alongside existing Java tasks, in addition to the netflix os-package plugin for generating RPMs (https://github.com/nebula-plugins/gradle-ospackage-plugin).

What is not working, is up to date checks for building the RPM. My guess is that I’m using incorrect syntax, because the up to date checks work for previous syntax (similar to copy syntax).

model {
platforms {
	x64 {
		architecture "x64"
	}
}

components {
	mynativelibrary(NativeLibrarySpec) {
		targetPlatform "x64"

		binaries.all {
			if (toolChain in Gcc) {
				cCompiler.args "-Wall", "-Werror", "-fpic"
			}
		}
	}
}

tasks {
	buildRpm {
		packageName = 'rpm-package-name
		summary = 'My Package'

		into(topLevelDir) {
			into('my/path/') {
				from linkMynativelibrarySharedLibrary.outputs.files
				from jar.outputs.files
			}
		}
	}
}
}

As long as I delete the RPM manually, it builds properly, and places the .so file. However, I can delete the library, forcing a recompile, and I see that it does it, but follows up with the buildRpm task showing “UP-TO-DATE”.

Is the syntax I’m using correct for referencing the outputs of a native compilation?

Mark


(Mark E. Scott, Jr.) #2

I did find that the dependency resolution was still working. It seemed not to work, as I could delete the outputs, recreate, and it would show up to date. However, once I actually made a change to a c source file, causing different output, it did indeed re-run.

One thing I found that didn’t work as expected was adding additional include directories.

I have a set of tasks which download and extract some archives that contain C headers needed for compilation.

I added those sources as:

sources {
  c {
    source {
      include "${project.buildDir}/library/usr/include"
    }
  }
}

What was interesting, as that when I did this, all of a sudden the linkMynativelibrarySharedLibrary completely disappeared. If I commented out the “include” line, it returned (with the compile error, since it couldn’t find the proper header).

I ended up doing the following to solve it (adding the include folder to the compiler command line, but I’m going to try and see if I can figure out the right way.

binaries.all {
  if (toolChain in Gcc) {
    cCompiler.args '-Wall'
    cCompiler.args '-fpic'
    cCompiler.args "-I${project.buildDir}/library/usr/include"
  }
}

(Chris Doré) #3

It is likely that the link task disappears because that include method is for filtering the input source files. It has nothing to do with the compiler include paths. I’m guessing that Gradle saw there was nothing to link and therefore no need for a link task.
It’s not immediately apparent from the javadoc (seems like CSourceSet is not displaying all the inherited methods), but the docs for LanguageSourceSet show that getSource returns a SourceDirectorySet, which is what contains the include method being called.