Updated ntcore build to build both arm and native versions

Change-Id: I515f051bbb816a1a82667462ad4e140cdb0fabdc
This commit is contained in:
Fredric Silberberg
2015-11-24 15:58:28 -05:00
parent 3cd20d3ff2
commit db91e20ec7
9 changed files with 231 additions and 179 deletions

3
.gitignore vendored
View File

@@ -35,3 +35,6 @@ build/
*.sdf
*.sublime-project
*.sublime-workspace
native/
arm/

View File

@@ -1,24 +1,18 @@
import org.gradle.internal.os.OperatingSystem
apply plugin: 'cpp'
apply plugin: 'visual-studio'
// Find the target platform. The main wpilib build will set the target platform as a project property. You can also manually build for
// arm by using ./gradlew build -PbuildPlatform=arm
allprojects {
if (!project.hasProperty('armBuild')) {
ext.buildPlatform = OperatingSystem.current().getFamilyName()
} else {
ext.buildPlatform = 'arm'
// Determine what repo to publish to. Default is development. Valid options are development, beta, stable, and release
if (!hasProperty('repo')) {
allprojects {
ext.repo = 'development'
}
}
if (!project.hasProperty('repo')) {
ext.repo = 'development'
if (hasProperty('makeDesktop')) {
println 'Making desktop classifier jar. NOTE: This desktop version should only be used for local testing.' +
'It will only support the current platform, and will override fetching the latest development version from' +
' the maven repo until you manually delete it!'
}
ext.useExtension = repo != 'release'
ext.getPlatformPath = { binary ->
if (binary.targetPlatform.architecture.arm) {
return 'Linux/arm'
@@ -45,89 +39,69 @@ ext.getPlatformPath = { binary ->
}
}
// Apply the correct toolchain settings for the target platform
if (buildPlatform == 'arm') {
apply from: 'toolchains/arm.gradle'
} else if (OperatingSystem.current().isLinux()) {
apply from: 'toolchains/linux.gradle'
} else if (OperatingSystem.current().isMacOsX()) {
apply from: 'toolchains/mac.gradle'
} else if (OperatingSystem.current().isWindows()) {
apply from: 'toolchains/windows.gradle'
} else {
throw new GradleException("ntcore does not support building on ${OperatingSystem.current().getFamilyName()}.")
}
def includeJava = !hasProperty('skipJava')
// We only build and run the tests when building for the native platform. If we just build arm, there's not much point.
if (buildPlatform != 'arm') {
apply from: 'test/tests.gradle'
}
if (!hasProperty('skipJava')) {
apply from: 'java/java.gradle'
}
model {
platforms {
if (project.buildPlatform == 'arm') {
arm {
architecture 'arm'
operatingSystem 'linux'
}
} else {
x86 {
architecture 'x86'
}
x64 {
architecture 'x86_64'
}
}
}
components {
ntcore(NativeLibrarySpec) {
if (project.buildPlatform == 'arm') {
targetPlatform 'arm'
binaries.all {
if (project.hasProperty('debug')) {
setupDebugDefines(cppCompiler, linker)
} else {
setupReleaseDefines(cppCompiler, linker)
}
// This is a closure to set up the model for compiling a c++ build. In order to run the tests only on the
// native build, we have two pseudoprojects, native and arm. Native compiles for x86/x64, and arm compiles
// for arm. This closure takes two parameters:
// project - the project to configure
// isArm - whether the project should use arm include files or not.
def setupModel = { project, isArm ->
project.model {
platforms {
if (isArm) {
arm {
architecture 'arm'
operatingSystem 'linux'
}
} else {
targetPlatform 'x86'
targetPlatform 'x64'
x86 {
architecture 'x86'
}
x64 {
architecture 'x86_64'
}
}
}
components {
ntcore(NativeLibrarySpec) {
if (isArm) {
targetPlatform 'arm'
} else {
targetPlatform 'x86'
targetPlatform 'x64'
}
binaries.all {
if (project.hasProperty('debug')) {
setupDebugDefines(cppCompiler, linker)
project.setupDebugDefines(cppCompiler, linker)
} else {
setupReleaseDefines(cppCompiler, linker)
project.setupReleaseDefines(cppCompiler, linker)
}
}
}
if (!project.hasProperty('skipJava')) {
setupJniIncludes(binaries)
}
if (includeJava) {
project.setupJniIncludes(binaries)
}
sources {
cpp {
source {
srcDirs = ['src']
if (!project.hasProperty('skipJava')) {
srcDirs "java/lib"
}
includes = ['**/*.cpp']
}
exportedHeaders {
srcDirs = ['include', 'src']
if (!project.hasProperty('skipJava')) {
jniHeadersNetworkTables.outputs.files.each { file ->
srcDirs file.getPath()
sources {
cpp {
source {
srcDirs = ['../src']
if (includeJava) {
srcDirs "../java/lib"
}
includes = ['**/*.cpp']
}
exportedHeaders {
srcDirs = ['../include', '../src']
if (includeJava) {
project.jniHeadersNetworkTables.outputs.files.each { file ->
srcDirs file.getPath()
}
}
includes = ['**/*.h']
}
includes = ['**/*.h']
}
}
}
@@ -135,80 +109,125 @@ model {
}
}
task ntcoreZip(type: Zip) {
description = 'Creates platform-specific zip of the desktop ntcore libraries.'
group = 'WPILib'
destinationDir = project.buildDir
baseName = 'ntcore'
classifier = "$buildPlatform${useExtension ? '-' + repo : ''}"
def ntcoreZipTask = { project ->
project.ext.ntcoreZip = project.tasks.create("${project.isArm ? 'arm' : 'native'}NtcoreZip", Zip) {
description = 'Creates platform-specific zip of the desktop ntcore libraries.'
group = 'WPILib'
destinationDir = project.buildDir
baseName = 'ntcore'
classifier = "${project.buildPlatform}"
from(file('include')) {
into 'include'
}
from(file('include')) {
into 'include'
}
if (!hasProperty('skipJava')) {
jniHeadersNetworkTables.outputs.each {
from(it) {
into 'include'
if (!hasProperty('skipJava')) {
project.jniHeadersNetworkTables.outputs.each {
from(it) {
into 'include'
}
}
}
project.binaries.withType(StaticLibraryBinarySpec) { binary ->
from(binary.staticLibraryFile) {
into getPlatformPath(binary)
}
}
project.binaries.withType(SharedLibraryBinarySpec) { binary ->
from(binary.sharedLibraryFile) {
into getPlatformPath(binary)
}
}
}
binaries.withType(StaticLibraryBinarySpec) { binary ->
from(binary.staticLibraryFile) {
into getPlatformPath(binary)
}
}
project.build.dependsOn project.ntcoreZip
binaries.withType(SharedLibraryBinarySpec) { binary ->
from(binary.sharedLibraryFile) {
into getPlatformPath(binary)
project.releaseSetup(project.ntcoreZip)
project.tasks.whenTaskAdded { task ->
def name = task.name.toLowerCase()
if (name.contains("ntcoresharedlibrary") || name.contains("ntcorestaticlibrary") ||
name.contains("ntcoretest")) {
project.ntcoreZip.dependsOn task
}
}
}
task ntcoreSourceZip(type: Zip) {
description = 'Creates a sources-zip of the ntcore source files'
group = 'WPILib'
destinationDir = project.buildDir
baseName = 'ntcore'
classifier = "sources${useExtension ? '-' + repo : ''}"
def ntcoreSourceZipTask = { project ->
project.ext.ntcoreSourceZip = project.tasks.create("${project.isArm ? 'arm' : 'native'}NtcoreSourceZip", Zip) {
description = 'Creates a sources-zip of the ntcore source files'
group = 'WPILib'
destinationDir = project.buildDir
baseName = 'ntcore'
classifier = "sources"
from ('src') {
into 'src'
}
from('include') {
into 'include'
}
if (!hasProperty('java')) {
from('java/lib') {
from ('src') {
into 'src'
}
jniHeadersNetworkTables.outputs.each {
from(it) {
into 'include'
from('include') {
into 'include'
}
if (includeJava) {
from('java/lib') {
into 'src'
}
project.jniHeadersNetworkTables.outputs.each {
from(it) {
into 'include'
}
}
}
}
project.build.dependsOn project.ntcoreSourceZip
}
project(':arm') {
apply plugin: 'cpp'
build.dependsOn ntcoreSourceZip
ext.buildPlatform = 'arm'
ext.isArm = true
releaseSetup(ntcoreZip)
if (!hasProperty('skipJava')) {
jar.dependsOn ntcoreZip
}
tasks.whenTaskAdded { task ->
def name = task.name.toLowerCase()
if (name.contains("ntcoresharedlibrary") || name.contains("ntcorestaticlibrary") ||
name.contains("ntcoretest")) {
ntcoreZip.dependsOn task
apply from: '../toolchains/arm.gradle'
if (includeJava) {
apply from: '../java/java.gradle'
}
setupModel(project, true)
ntcoreZipTask(project)
ntcoreSourceZipTask(project)
}
project(':native') {
apply plugin: 'cpp'
task check
ext.buildPlatform = OperatingSystem.current().getFamilyName()
ext.isArm = false
if (OperatingSystem.current().isLinux()) {
apply from: '../toolchains/linux.gradle'
} else if (OperatingSystem.current().isMacOsX()) {
apply from: '../toolchains/mac.gradle'
} else if (OperatingSystem.current().isWindows()) {
apply from: '../toolchains/windows.gradle'
} else {
throw new GradleException("ntcore does not support building on ${OperatingSystem.current().getFamilyName()}.")
}
apply from: '../test/tests.gradle'
if (includeJava) {
apply from: '../java/java.gradle'
}
setupModel(project, false)
ntcoreZipTask(project)
ntcoreSourceZipTask(project)
}
apply from: 'publish.gradle'

View File

@@ -4,9 +4,7 @@ apply plugin: 'cpp'
apply plugin: 'visual-studio'
// Apply the correct toolchain settings for the target platform
if (buildPlatform == 'arm') {
apply from: '../toolchains/arm.gradle'
} else if (OperatingSystem.current().isLinux()) {
if (OperatingSystem.current().isLinux()) {
apply from: '../toolchains/linux.gradle'
} else if (OperatingSystem.current().isMacOsX()) {
apply from: '../toolchains/mac.gradle'

View File

@@ -2,12 +2,12 @@ import org.gradle.internal.os.OperatingSystem
apply plugin: 'java'
def generatedJNIHeaderLoc = 'build/include'
def generatedJNIHeaderLoc = '../build/include'
sourceSets {
main {
java {
srcDirs = ['java/src']
srcDirs = ['../java/src']
}
}
}
@@ -15,14 +15,7 @@ sourceSets {
jar {
description = 'Generates NetworkTables jar, with the JNI shared libraries embedded'
baseName = 'ntcore'
classifier = "$buildPlatform${useExtension ? '-' + repo : ''}"
if (buildPlatform == 'arm') {
dependsOn { ntcoreSharedLibrary }
} else {
dependsOn { x64NtcoreSharedLibrary }
dependsOn { x86NtcoreSharedLibrary }
}
classifier = "$buildPlatform"
dependsOn { classes }
binaries.withType(SharedLibraryBinary) { binary ->
@@ -32,11 +25,20 @@ jar {
}
}
project.tasks.whenTaskAdded { task->
if (isArm) {
if (task.name == 'ntcoreSharedLibrary') jar.dependsOn task
} else {
if (task.name == 'x64NtcoreSharedLibrary' || task.name == 'x86NtcoreSharedLibrary')
jar.dependsOn task
}
}
task networktablesJavaSource(type: Jar, dependsOn: classes) {
description = 'Generates the source jar for NetworkTables java'
group = 'WPILib'
baseName = 'ntcore'
classifier = "sources${useExtension ? '-' + repo : ''}"
classifier = "sources"
from sourceSets.main.allJava
}
@@ -44,7 +46,7 @@ task networktablesJavadoc(type: Jar, dependsOn: javadoc) {
description = 'Generates the javadoc jar for NetworkTables java'
group = 'WPILib'
baseName = 'ntcore'
classifier = "javadoc${useExtension ? '-' + repo : ''}"
classifier = "javadoc"
from javadoc.destinationDir
}
@@ -96,8 +98,8 @@ ext.setupJniIncludes = { binaries ->
binaries.all {
tasks.withType(CppCompile) {
if (buildPlatform == 'arm') {
cppCompiler.args '-I', file('java/arm-linux').absolutePath
cppCompiler.args '-I', file('java/arm-linux/linux').absolutePath
cppCompiler.args '-I', file('../java/arm-linux').absolutePath
cppCompiler.args '-I', file('../java/arm-linux/linux').absolutePath
} else {
def jdkLocation = org.gradle.internal.jvm.Jvm.current().javaHome
platformSpecificIncludeFlag("${jdkLocation}/include", cppCompiler)

View File

@@ -2,15 +2,24 @@ import org.gradle.internal.os.OperatingSystem
apply plugin: 'maven-publish'
// We classify the different artifacts by whether they are sources, and what development
// stage they are in. Release gets no classifier; stable, beta, and development get classifiers.
// We change what repo we publish to depending on whether this is a development, beta, stable, or full
// release. This is set up in the main gradle file.
publishing {
publications {
def nat = project('native')
def arm = project('arm')
if (!project.hasProperty('skipJava')) {
java(MavenPublication) {
artifact jar
artifact networktablesJavaSource
artifact networktablesJavadoc
artifact nat.jar
artifact arm.jar
artifact nat.networktablesJavaSource
artifact nat.networktablesJavadoc
if (project.hasProperty('makeDesktop')) {
artifact nat.jar, {
classifier = 'desktop'
}
}
groupId 'edu.wpi.first.wpilib.networktables.java'
artifactId 'NetworkTables'
@@ -18,8 +27,9 @@ publishing {
}
}
cpp(MavenPublication) {
artifact ntcoreZip
artifact ntcoreSourceZip
artifact nat.ntcoreZip
artifact arm.ntcoreZip
artifact nat.ntcoreSourceZip
groupId 'edu.wpi.first.wpilib.networktables.cpp'
artifactId 'NetworkTables'
@@ -29,7 +39,7 @@ publishing {
repositories {
maven {
url "${System.getProperty('user.home')}/releases/maven/"
url "${System.getProperty('user.home')}/releases/maven/${project.repo}"
}
}
}

View File

@@ -1,2 +1 @@
if (!hasProperty('armBuild'))
include 'gmock'
include 'arm', 'native', 'gmock'

View File

@@ -1,5 +1,4 @@
apply plugin: 'google-test'
task check() {}
model {
testSuites {
@@ -10,32 +9,26 @@ model {
sources {
cpp {
source {
srcDirs = ['test/unit']
srcDirs = ['../test/unit']
includes = ['**/*.cpp']
}
exportedHeaders {
srcDirs = ['include', 'src', 'gmock/include', 'gmock/gtest/include']
srcDirs = ['../include', '../src', '../gmock/include', '../gmock/gtest/include']
includes = ['**/*.h']
}
}
}
binaries.all {
if (project.hasProperty('wpilib')) {
lib project: ':ntcore:gmock', library: "gmock", linkage: "static"
} else {
lib project: ':gmock', library: "gmock", linkage: "static"
}
lib project: ':gmock', library: 'gmock', linkage: 'static'
lib library: 'ntcore', linkage: 'static'
}
}
}
}
binaries.withType(GoogleTestTestSuiteBinarySpec) {
if (project.hasProperty('wpilib')) {
lib project: ':ntcore:gmock', library: "gmock", linkage: "static"
} else {
lib project: ':gmock', library: "gmock", linkage: "static"
}
lib project: ':gmock', library: "gmock", linkage: "static"
lib library: 'ntcore', linkage: 'static'
if (targetPlatform.operatingSystem.windows) {
cppCompiler.args '/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS'
} else {

View File

@@ -26,6 +26,34 @@ model {
staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable
}
}
// Workaround for OS X. Macs for some reason want to use Xcode's gcc
// (which just wraps Clang), so we have to explicitly make it so
// that trying to compile with Clang will call gcc instead
macGcc(Clang) {
target('arm') {
// We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
// If this ever changes, the prefix will need to be changed here
cppCompiler.executable = compilerPrefix + 'g++'
linker.executable = compilerPrefix + 'g++'
assembler.executable = compilerPrefix + 'gcc'
// Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
// arm, and doesn't understand this flag, so it is removed from both
cppCompiler.withArguments { args ->
args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-O0' << '-g3' << '-rdynamic'
//TODO: When the compiler allows us to actually call deprecated functions from within
// deprecated function, remove this line (this will cause calling deprecated functions
// to be treated as a warning rather than an error).
args << '-Wno-error=deprecated-declarations'
args.remove('-m32')
}
linker.withArguments { args ->
args << '-rdynamic'
args.remove('-m32')
}
staticLibArchiver.executable = compilerPrefix + 'ar'
}
}
}
}

View File

@@ -36,12 +36,12 @@ model {
ext.setupReleaseDefines = { cppCompiler, linker ->
cppCompiler.args '/O2', '/Zi', '/FS'
linker.args '/DEF:ntcore.def'
linker.args '/DEF:../ntcore.def'
}
ext.setupDebugDefines = { cppCompiler, linker ->
cppCompiler.args '/Zi', '/FS'
linker.args '/DEBUG', '/DEF:ntcore.def'
linker.args '/DEBUG', '/DEF:../ntcore.def'
}
// This is a noop on Windows. On gcc platforms, we strip the release binary and create a separate