diff --git a/.gitignore b/.gitignore index 979dd27575..842b79cfa3 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ build/ *.sdf *.sublime-project *.sublime-workspace + +native/ +arm/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index 9d1591a199..87a5933f5e 100644 --- a/build.gradle +++ b/build.gradle @@ -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' diff --git a/gmock/build.gradle b/gmock/build.gradle index 36ccde3f74..809c55c150 100644 --- a/gmock/build.gradle +++ b/gmock/build.gradle @@ -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' diff --git a/java/java.gradle b/java/java.gradle index 5f55750f90..8ff6a7bc2b 100644 --- a/java/java.gradle +++ b/java/java.gradle @@ -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) diff --git a/publish.gradle b/publish.gradle index d403a01f0e..f978419f93 100644 --- a/publish.gradle +++ b/publish.gradle @@ -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}" } } } diff --git a/settings.gradle b/settings.gradle index e573a5cd10..b262f4ed0e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1 @@ -if (!hasProperty('armBuild')) - include 'gmock' +include 'arm', 'native', 'gmock' \ No newline at end of file diff --git a/test/tests.gradle b/test/tests.gradle index fcedcbfc2d..8499e20040 100644 --- a/test/tests.gradle +++ b/test/tests.gradle @@ -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 { diff --git a/toolchains/arm.gradle b/toolchains/arm.gradle index 27a96656c8..4faa6f3c6d 100644 --- a/toolchains/arm.gradle +++ b/toolchains/arm.gradle @@ -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- + // 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' + } + } } } diff --git a/toolchains/windows.gradle b/toolchains/windows.gradle index b24f962672..41d18ff60e 100644 --- a/toolchains/windows.gradle +++ b/toolchains/windows.gradle @@ -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