From 77cf3adf64a2e8474d6861ceb0f5383effb886c7 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 24 Sep 2015 23:32:55 -0400 Subject: [PATCH] This commit updates the gradle files to be cleaner. It also builds for the current platform by default, and only builds tests when building for the current platform. Mac builds and VS2015 builds are fixed. The other big change in this update is the introduction of Debug and Release builds. Debug builds are built with -O0 and -g. Release builds are built with -O2 and -g. For GCC-based builds, the resulting shared object is copied, stripped of debug information, and a debug link is set up to the copied shared object. This allows the release build to clock in at around 600 KB. On Windows, the debug info is already stored in a separate PDB file, so this copy and strip is not necessary. ntcore is being separated out from the rest of allwpilib. All other builds will consume a published maven dependency from this project. There are 4 possible publishing targets now: release, stable, beta, and development. These are specified on the command line via -Prepo=. Change-Id: Ie8cb21f910953e09b80a5192317033eb0866cb70 --- build.gradle | 394 ++++++++--------------- gmock/build.gradle | 92 +++--- gradle/wrapper/gradle-wrapper.jar | Bin 52266 -> 53638 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 6 +- java/java.gradle | 120 +++++++ publish.gradle | 50 +++ settings.gradle | 3 +- test/build.gradle | 59 ---- test/tests.gradle | 45 +++ toolchains/arm.gradle | 66 ++++ toolchains/linux.gradle | 70 ++++ toolchains/mac.gradle | 57 ++++ toolchains/windows.gradle | 49 +++ 14 files changed, 650 insertions(+), 365 deletions(-) create mode 100644 java/java.gradle create mode 100644 publish.gradle delete mode 100644 test/build.gradle create mode 100644 test/tests.gradle create mode 100644 toolchains/arm.gradle create mode 100644 toolchains/linux.gradle create mode 100644 toolchains/mac.gradle create mode 100644 toolchains/windows.gradle diff --git a/build.gradle b/build.gradle index f53e82b0ce..64fab29076 100644 --- a/build.gradle +++ b/build.gradle @@ -1,284 +1,164 @@ -import org.apache.tools.ant.taskdefs.condition.Os +import org.gradle.internal.os.OperatingSystem -if (!project.hasProperty('skipJava')) { - apply plugin: 'java' - apply plugin: 'maven-publish' -} apply plugin: 'cpp' apply plugin: 'visual-studio' -def generatedJNIHeaderLoc = 'build/include' +// 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' + } +} -def platformSpecificIncludeFlag(loc, cppCompiler) { - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - cppCompiler.args "/I$loc" - } else { - cppCompiler.args '-I', loc - } +ext.getPlatformPath = { binary -> + if (binary.targetPlatform.architecture.arm) { + return 'Linux/arm' + } else if (binary.targetPlatform.operatingSystem.linux) { + if (binary.targetPlatform.architecture.amd64) { + return 'Linux/amd64' + } else { + return 'Linux/' + binary.targetPlatform.architecture.name + } + } else if (binary.targetPlatform.operatingSystem.windows) { + if (binary.targetPlatform.architecture.amd64) { + return 'Windows/amd64' + } else { + return 'Windows/' + binary.targetPlatform.architecture.name + } + } else { + return binary.targetPlatform.operatingSystem.name + '/' + binary.targetPlatform.architecture.name + } +} + +// 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()}.") +} + +// 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 { - toolChains { - gcc(Gcc) { - 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 - def compilerPrefix = 'arm-frc-linux-gnueabi-' - cppCompiler.executable = compilerPrefix + cppCompiler.executable - linker.executable = compilerPrefix + linker.executable - assembler.executable = compilerPrefix + assembler.executable - // 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') + platforms { + if (project.buildPlatform == 'arm') { + arm { + architecture 'arm' + operatingSystem 'linux' + } + } else { + x86 { + architecture 'x86' + operatingSystem project.buildPlatform + } + x64 { + architecture 'x86_64' + operatingSystem project.buildPlatform + } } - linker.withArguments { args -> - args << '-rdynamic' - args.remove('-m32') - } - staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable - } - target('x86') { - cppCompiler.withArguments { args -> - args << '-std=c++11' << '-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 << '-m32' - } - linker.withArguments { args -> - args << '-rdynamic' - args << '-m32' - } - } - target('x64') { - cppCompiler.withArguments { args -> - args << '-std=c++11' << '-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' - } - linker.withArguments { args -> - args << '-rdynamic' - } - } } - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - visualCpp(VisualCpp) { - def vs14Dir = file('C:\\Program Files (x86)\\Microsoft Visual Studio 14.0') - // If vs2015 is installed, fall back to vs2013 for now, until Gradle pulls in the right - // includes for the win10 sdk. - if (vs14Dir.exists()) { - def vs12Dir = file('C:\\Program Files (x86)\\Microsoft Visual Studio 12.0') - if (!vs12Dir.exists()) { - throw new GradleException('Compilation with VS 2015 is not currently supported by Gradle. Please install VS 2013, or use the CMake build option.') - } - installDir = vs12Dir - } - eachPlatform { - cppCompiler.withArguments { args -> - args << '/EHsc' << '/DNOMINMAX' << '/D_SCL_SECURE_NO_WARNINGS' << '/D_WINSOCK_DEPRECATED_NO_WARNINGS' - } - linker.withArguments { args -> - args << '/DEF:ntcore.def' - } - } - } - } - } - platforms { - arm { - architecture "arm" - operatingSystem 'linux' - } - x86 { - architecture "x86" - } - x64 { - architecture "x86_64" - } - } - - components { - ntcore(NativeLibrarySpec) { - targetPlatform 'arm' - targetPlatform 'x86' - targetPlatform 'x64' - binaries.all { - tasks.withType(CppCompile) { - - - if (!project.hasProperty('skipJava')) { - if (targetPlatform == platforms.arm) { - // ARM JDK is included for jni.h. We also need the arm-linux specific headers. - // This does not need to change when compiling on Windows - // The JNI headers are put into the build/include directory by the jniHeaders task - sources { - arm(CppSourceSet) { - source { - includes "java/arm-linux" - includes "java/arm-linux/linux" - } + components { + ntcore(NativeLibrarySpec) { + if (project.buildPlatform == 'arm') { + targetPlatform 'arm' + binaries.all { + if (project.hasProperty('debug')) { + setupDebugDefines(cppCompiler, linker) + } else { + setupReleaseDefines(cppCompiler, linker) + } } - } } else { - def jdkLocation = org.gradle.internal.jvm.Jvm.current().javaHome - platformSpecificIncludeFlag("${jdkLocation}/include", cppCompiler) - - if (targetPlatform.operatingSystem.macOsX) { - platformSpecificIncludeFlag("${jdkLocation}/include/darwin", cppCompiler) - } else if (targetPlatform.operatingSystem.linux) { - platformSpecificIncludeFlag("${jdkLocation}/include/linux", cppCompiler) - } else if (targetPlatform.operatingSystem.windows) { - platformSpecificIncludeFlag("${jdkLocation}/include/win32", cppCompiler) - } else if (targetPlatform.operatingSystem.freeBSD) { - platformSpecificIncludeFlag("${jdkLocation}/include/freebsd", cppCompiler) - } + targetPlatform 'x86' + targetPlatform 'x64' + binaries.all { + if (project.hasProperty('debug')) { + setupDebugDefines(cppCompiler, linker) + } else { + setupReleaseDefines(cppCompiler, linker) + } + } } - jniHeadersNetworkTables.outputs.files.each { file -> - if (targetPlatform == platforms.arm) { - cppCompiler.args '-I', file.getPath() - } else { - platformSpecificIncludeFlag(file.getPath(), cppCompiler) - } - } - dependsOn jniHeadersNetworkTables - } - } - } - sources { - cpp { - source { - srcDirs = ["src"] if (!project.hasProperty('skipJava')) { - srcDirs "java/lib" + setupJniIncludes(binaries) } - includes = ["**/*.cpp"] - } - exportedHeaders { - srcDirs = ["include"] - if (!project.hasProperty('skipJava')) { - jniHeadersNetworkTables.outputs.files.each { file -> - srcDirs file.getPath() - } + + sources { + cpp { + source { + srcDirs = ['src'] + if (!project.hasProperty('skipJava')) { + srcDirs "java/lib" + } + includes = ['**/*.cpp'] + } + exportedHeaders { + srcDirs = ['include'] + if (!project.hasProperty('skipJava')) { + jniHeadersNetworkTables.outputs.files.each { file -> + srcDirs file.getPath() + } + } + includes = ['**/*.h'] + } + } } - includes = ["**/*.h"] - } } - } } - } } -if (!project.hasProperty('skipJava')) { - - publishing { - publications { - java(MavenPublication) { - artifact jar - artifact (networktablesJavaSource) { - classifier = 'sources' - } - artifact(networktablesJavadoc) { - classifier = 'javadoc' - } - - groupId 'edu.wpi.first.wpilib.networktables.java' - artifactId 'NetworkTables' - version '3.0.0-SNAPSHOT' - } - } - } - - compileJava { - options.compilerArgs << "-Xlint:unchecked" - } - - sourceSets { - main { - java { - srcDirs = ["java/src"] - } - } - } - - jar { - description = 'Generates NetworkTables jar, with the JNI shared libraries embedded' - dependsOn { armNtcoreSharedLibrary } - dependsOn { x64NtcoreSharedLibrary } - dependsOn { x86NtcoreSharedLibrary } - dependsOn { classes } - binaries.withType(SharedLibraryBinary) { binary -> - from(file(binary.sharedLibraryFile)) { - if (binary.targetPlatform == platforms.arm) { - into "Linux/arm" - } else if (binary.targetPlatform.operatingSystem.name == "Linux") { - if (binary.targetPlatform.architecture.name == "x86-64") { - into "Linux/amd64" - } else { - into "Linux/" + binary.targetPlatform.architecture.name - } - } else if (binary.targetPlatform.operatingSystem.name.startsWith("Windows")) { - if (binary.targetPlatform.architecture.name == "x86-64") { - into "Windows/amd64" - } else { - into "Windows/" + binary.targetPlatform.architecture.name - } - } else { - into binary.targetPlatform.operatingSystem.name + "/" + binary.targetPlatform.architecture.name - } - } - } - } - - task networktablesJavaSource(type: Jar, dependsOn: classes) { - description = 'Generates the source jar for NetworkTables java' +task ntcoreZip(type: Zip) { + description = 'Creates platform-specific zip of the desktop ntcore libraries.' group = 'WPILib' - classifier = 'classes' - from sourceSets.main.allJava - } + destinationDir = project.buildDir - task networktablesJavadoc(type: Jar, dependsOn: javadoc) { - description = 'Generates the javadoc jar for NetworkTables java' - group = 'WPILib' - classifier = 'javadoc' - from javadoc.destinationDir - } - - /** - * Generates the JNI headers - */ - task jniHeadersNetworkTables { - description = 'Generates JNI headers from edu.wpi.first.wpilibj.networktables.*' - group = 'WPILib' - def outputFolder = file(generatedJNIHeaderLoc) - inputs.files sourceSets.main.output - outputs.file outputFolder - doLast { - outputFolder.mkdirs() - exec { - executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah') - args '-d', outputFolder - args '-classpath', sourceSets.main.output.classesDir - args 'edu.wpi.first.wpilibj.networktables.NetworkTablesJNI' - } + from(file('include')) { + into 'include' } - } - clean { - delete generatedJNIHeaderLoc - } + binaries.withType(StaticLibraryBinarySpec) { binary -> + from(binary.staticLibraryFile) { + into getPlatformPath(binary) + } + } -} // skipJava + binaries.withType(SharedLibraryBinarySpec) { binary -> + from(binary.sharedLibraryFile) { + into getPlatformPath(binary) + } + } +} + +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: 'publish.gradle' diff --git a/gmock/build.gradle b/gmock/build.gradle index ef44c6c2fe..4bcebfa153 100644 --- a/gmock/build.gradle +++ b/gmock/build.gradle @@ -1,45 +1,55 @@ -import org.apache.tools.ant.taskdefs.condition.Os +import org.gradle.internal.os.OperatingSystem + apply plugin: 'cpp' apply plugin: 'visual-studio' -model { - toolChains { - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - visualCpp(VisualCpp) { - def vs14Dir = file('C:\\Program Files (x86)\\Microsoft Visual Studio 14.0') - // If vs2015 is installed, fall back to vs2013 for now, until Gradle pulls in the right - // includes for the win10 sdk. - if (vs14Dir.exists()) { - def vs12Dir = file('C:\\Program Files (x86)\\Microsoft Visual Studio 12.0') - if (!vs12Dir.exists()) { - throw new GradleException('Compilation with VS 2015 is not currently supported by Gradle. Please install VS 2013, or use the CMake build option.') - } - installDir = vs12Dir - } - } - } - } - components { - gmock(NativeLibrarySpec) { - sources { - cpp { - source { - srcDirs = ['src', 'gtest/src'] - includes = ['*-all.cc'] - } - exportedHeaders { - srcDirs = ['include', 'gtest/include', '.', 'gtest'] - includes = ['**/*.h', '**/*.cc'] - } - } - } - binaries.all { - if (toolChain in VisualCpp) { - cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1' - } else { - cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-lpthreads', '-fPIC' - } - } - } - } +// 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()}.") +} + +model { + platforms { + x86 { + architecture 'x86' + operatingSystem OperatingSystem.current().getFamilyName() + } + x64 { + architecture 'x86_64' + operatingSystem OperatingSystem.current().getFamilyName() + } + } + components { + gmock(NativeLibrarySpec) { + targetPlatform 'x86' + targetPlatform 'x64' + sources { + cpp { + source { + srcDirs = ['src', 'gtest/src'] + includes = ['*-all.cc'] + } + exportedHeaders { + srcDirs = ['include', 'gtest/include', '.', 'gtest'] + includes = ['**/*.h', '**/*.cc'] + } + } + } + binaries.all { + if (toolChain in VisualCpp) { + cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1' + } else { + cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-lpthreads', '-fPIC' + } + } + } + } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index b5166dad4d90021f6a0b45268c0755719f1d5cd4..e8c6bf7bb47dff6b81c2cf7a349eb7e912c9fbe2 100644 GIT binary patch delta 12509 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 CY2(!Z delta 11130 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

G(;4eI7C?++(cQMC>R}|&hR>Z zti?w;&QCUen5wqXcAK@J|HAS~c1BRCSq2cwjYF-S1vJ9CIHiK~-jK*~l6{x>a3sY-i6 zmVns+6OUJ!G=W+Lw2SX%N4oOC`(NYHCqja2-6*a18TFP+=Yu{G(h_TeL9Wa%r`icq zE_}7kNHm&V2Ae=%iYaXc9wn$d0`i21mCYnos_)`&Qai&aD{jpst>TUn;kX zyXA)3YPKSxPR6RD&lF7%f%)hMwAQZo z+eht`SyI*YhX>-?UY{FoNy!4xsIRAC42Cyod{CLS@ChNty+d3}uAX`R% zgvMhlhoop-hWa&H3U)3k_XQzw7_$ylv=p*|)E-`Zq7jW6-#7oZmDeEP<6XrWAhp{N z-St;Iz9-8bJ;=c%qZR79du@_Iq4yokO3)m~q& zScG{W=9nvNB%P}0w$4xX9-6m-TMPQU5u3F?4TbkQnLiE0`~46I$bZv+ZvKKU@za0{ zL~#>c&Y-(($_?0p>5>jw{+1=h9Z_k3qr}U{X)1kyh;`yytsYS_IbV)y3n^)53zYI(*%ai5|8U00FIE_lj-_*A&p+?D zN493saAGr{NW``m_g^r=;gt-Ia7$M7{G|9klb>KJcoaC61{?vco>4j&Gv7;=G7P>{ z3wc?Md}Kl)*r#@g`O-atdl%QTnt29w`7+us)2>0aw|S`K<2IE|kXUhhLk=Exqf~9B{3wNJg&!%5j}Zu!@ZBybV!Ep2^s^&78x9uy-+2-@^A(QmfH;VAEFcA5iO3|g4eI4xGLP7u`p`Xvd_g#X(%5UCAB zMEcV<5Z}J6^%}fuD5;LlsH}OaTn6Oe(B$B$f~M9`g0q}k!-S)OkD&}&YIUJlfy+XU*s z7edZFR>NAKhafq&5*l^6UGb<2FMr-GC`+n%47S4j>VJLQ5}a8Z&B%2rboL!4DZ;ox zw zqllLKsJ~FJiZcNKFiIrlqG^cPws>;~V(5vw;JZ(~p-t)jJE%34uj6drT9 zY#kzPryswX6-B0;x!}}6-g&rJY$DT!JD}MN3@OJyLJ>nFxj^{ua{kE^>}kvl`^Ts) zG7f{r`eSh!n#UA8roQ|5VgOf1y#Sk;J?@Twd??KCp`R@(tKGjAnr%GPQ=Axq)x#hH z01$=)0Ej%r;g68kp4v?#JcsnVlEXY(J0606En05~+%xve{}$@mx(WR9H)1Mc>MxcT zRRWFvM?y$`9f2h_05HG=X7{E9W7fgf2F7?`KS%z~KK(1|EN}I%^`)>L_W9H3GH945 zp$%PC?~)%Iqe>ocL;eb#B&}Vm%=sGpMfKNI_CH{B)(MbJ&>QC>Vs)K^Yh52uT7}%+c`#&9G;Ld}5SV0z!8{nHW#w(nJW{;0E;7o1Jp?~2$VJdxu&zQ|4_K^@AFhC71>cgh|w_67QpnNQr|M{y6*r5P(4v>OXDdE9) zeW=d_sQtvy!t76^BK>qv1pgdL{!jGdSQntg^E^BHpEFA0XM*-ef-j;^_;EkY6TyFP zCIJBIe+VWN9u;srIoVL!#MVIp09r5r0RKNuWU7z($Ud`=4iH1rt3R@nfnf)+|F3O@ zVh|4+qzgVXqy_5@qEi03-v8Mg9$5+hVZ_h_hYiv_)f>2akQf?EA3Q!t_Wb_%@x8b{ zm}7znJZVe}78yc)#+8SNp+^nC5@t*+s!IQ@hCdUjOCpgKJyz=VW2FlJGf|`AV*m|U z)tm(U`+tbghKZq@O~Bcej9?ureDLwuv)Wx6v~#&frAm)Pod1yIn?I6}f~$sUp3?f~ z3;d6xkR`ai|-%Dw~kNK-??J`XZkIZS^D)yXNSkFLF^xA zkjqmJgzw4!!%XcptQ!vp0HmM+0CfL2x4S)QeeI13ZXI}*k#46yS@@V(!T)n%!QM|Y z%18e${lq9SbgVBpt&AFsI)?p}Y@`IQozG)1%44wLKQmc{fJMjTpRY~C*kjR#J;@v% z<9x>MAF=)LM~oUQJpN2(h#?Beeaw;ZF-Puy$P&_@g4uGg|DTI1H*Ikk{}`11nD4(q z;aN}eZ^j9qq`s%y02)1Z&=I2m07Cz;+vPl#lftts-w9%9+QP>i+5WRY|7>*s1TvRA z&hXz0N)IcKO7yrGmVa{i$C14JY1yl4F#Z(mlN_mO{O$e6Rr7h2^KVi5RXim-KS}@O z2nGnH{8{3=M^=G|ytsjp7 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a2d2e54a8b..c0d783e643 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Sep 19 10:44:07 EDT 2015 +#Sat Oct 31 11:10:48 EDT 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip diff --git a/gradlew b/gradlew index 91a7e269e1..97fac783e1 100755 --- a/gradlew +++ b/gradlew @@ -42,11 +42,6 @@ case "`uname`" in ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" @@ -114,6 +109,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` diff --git a/java/java.gradle b/java/java.gradle new file mode 100644 index 0000000000..a0b634eca9 --- /dev/null +++ b/java/java.gradle @@ -0,0 +1,120 @@ +import org.gradle.internal.os.OperatingSystem + +apply plugin: 'java' + +def generatedJNIHeaderLoc = 'build/include' + +sourceSets { + main { + java { + srcDirs = ['java/src'] + } + } +} + +jar { + description = 'Generates NetworkTables jar, with the JNI shared libraries embedded' + + if (buildPlatform == 'arm') { + dependsOn { ntcoreSharedLibrary } + } else { + dependsOn { x64NtcoreSharedLibrary } + dependsOn { x86NtcoreSharedLibrary } + } + + dependsOn { classes } + binaries.withType(SharedLibraryBinary) { binary -> + from(file(binary.sharedLibraryFile)) { + into getPlatformPath(binary) + } + } +} + +task networktablesJavaSource(type: Jar, dependsOn: classes) { + description = 'Generates the source jar for NetworkTables java' + group = 'WPILib' + classifier = 'source' + from sourceSets.main.allJava +} + +task networktablesJavadoc(type: Jar, dependsOn: javadoc) { + description = 'Generates the javadoc jar for NetworkTables java' + group = 'WPILib' + classifier = 'javadoc' + from javadoc.destinationDir +} + +/** + * Generates the JNI headers + */ +task jniHeadersNetworkTables { + description = 'Generates JNI headers from edu.wpi.first.wpilibj.networktables.*' + group = 'WPILib' + def outputFolder = file(generatedJNIHeaderLoc) + inputs.files sourceSets.main.output + outputs.file outputFolder + doLast { + outputFolder.mkdirs() + exec { + executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah') + args '-d', outputFolder + args '-classpath', sourceSets.main.output.classesDir + args 'edu.wpi.first.wpilibj.networktables.NetworkTablesJNI' + } + } +} + +clean { + delete generatedJNIHeaderLoc +} + +compileJava { + options.compilerArgs << '-Xlint:unchecked' +} + +javadoc { + options.addStringOption('Xdoclint:none', '-quiet') +} + +// This creates a lambda that the main build.gradle can access, which sets up the JNI includes for the +// target build platform. This lambda is exposed as a property in the main build.gradle. +ext.setupJniIncludes = { binaries -> + def platformSpecificIncludeFlag = { loc, cppCompiler -> + if (OperatingSystem.current().isWindows()) { + cppCompiler.args "/I$loc" + } else { + cppCompiler.args '-I', loc + } + } + 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 + } else { + def jdkLocation = org.gradle.internal.jvm.Jvm.current().javaHome + platformSpecificIncludeFlag("${jdkLocation}/include", cppCompiler) + + if (targetPlatform.operatingSystem.macOsX) { + platformSpecificIncludeFlag("${jdkLocation}/include/darwin", cppCompiler) + } else if (targetPlatform.operatingSystem.linux) { + platformSpecificIncludeFlag("${jdkLocation}/include/linux", cppCompiler) + } else if (targetPlatform.operatingSystem.windows) { + platformSpecificIncludeFlag("${jdkLocation}/include/win32", cppCompiler) + } else if (targetPlatform.operatingSystem.freeBSD) { + platformSpecificIncludeFlag("${jdkLocation}/include/freebsd", cppCompiler) + } + } + + jniHeadersNetworkTables.outputs.files.each { file -> + if (buildPlatform == 'arm') { + cppCompiler.args '-I', file.getPath() + } else { + platformSpecificIncludeFlag(file.getPath(), cppCompiler) + } + } + + dependsOn jniHeadersNetworkTables + } + } +} diff --git a/publish.gradle b/publish.gradle new file mode 100644 index 0000000000..af89b236db --- /dev/null +++ b/publish.gradle @@ -0,0 +1,50 @@ +import org.gradle.internal.os.OperatingSystem + +apply plugin: 'maven-publish' + +publishing { + publications { + if (!project.hasProperty('skipJava')) { + java(MavenPublication) { + artifact jar { + // If we're building the regular ntcore for arm, it has no classifier. Otherwise, classify + // the platform this jar is built for. + classifier = buildPlatform + } + artifact (networktablesJavaSource) { + classifier = 'sources' + } + artifact(networktablesJavadoc) { + classifier = 'javadoc' + } + + groupId 'edu.wpi.first.wpilib.networktables.java' + artifactId 'NetworkTables' + version '3.0.0-SNAPSHOT' + } + } + cpp(MavenPublication) { + artifact ntcoreZip { + classifier = buildPlatform + } + + groupId 'edu.wpi.first.wpilib.networktables.cpp' + artifactId 'NetworkTables' + version '3.0.0-SNAPSHOT' + } + } + + // If we want to publish to a specific repository on Jenkins, we specify it on the command line. The valid + // repository names are: + // release + // stable + // beta + // development + if (project.hasProperty('repo')) { + repositories { + maven { + url "${System.getProperty('user.home')}/releases/maven/$repo" + } + } + } +} diff --git a/settings.gradle b/settings.gradle index 36b155565f..e573a5cd10 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,2 @@ -include 'gmock', 'test' +if (!hasProperty('armBuild')) + include 'gmock' diff --git a/test/build.gradle b/test/build.gradle deleted file mode 100644 index bd8f22bf49..0000000000 --- a/test/build.gradle +++ /dev/null @@ -1,59 +0,0 @@ -import org.apache.tools.ant.taskdefs.condition.Os -apply plugin: 'cpp' -apply plugin: 'google-test' -apply plugin: 'visual-studio' - -model { - toolChains { - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - visualCpp(VisualCpp) { - def vs14Dir = file('C:\\Program Files (x86)\\Microsoft Visual Studio 14.0') - // If vs2015 is installed, fall back to vs2013 for now, until Gradle pulls in the right - // includes for the win10 sdk. - if (vs14Dir.exists()) { - def vs12Dir = file('C:\\Program Files (x86)\\Microsoft Visual Studio 12.0') - if (!vs12Dir.exists()) { - throw new GradleException('Compilation with VS 2015 is not currently supported by Gradle. Please install VS 2013, or use the CMake build option.') - } - installDir = vs12Dir - } - } - } - } - components { - tests(NativeLibrarySpec) { - sources { - cpp { - source { - srcDirs = ["unit", "../src"] - includes = ["**/*.cpp"] - } - exportedHeaders { - srcDirs = ["../include", "../src", "../gmock/include", "../gmock/gtest/include"] - includes = ["**/*.h"] - } - } - } - binaries.all { - lib project: ':gmock', library: "gmock", linkage: "static" - if (toolChain in Gcc) { - cppCompiler.args '-std=c++1y', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-unused-parameter' - linker.args '-pthread' - } - if (toolChain in VisualCpp) { - cppCompiler.args '/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS' - } - } - } - } -} -binaries.withType(GoogleTestTestSuiteBinarySpec) { - lib project: ':gmock', library: "gmock", linkage: "static" - if (targetPlatform.operatingSystem.linux) { - cppCompiler.args '-pthread', '-std=c++1y' - linker.args '-pthread' - } else { - cppCompiler.args '/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS' - } -} - diff --git a/test/tests.gradle b/test/tests.gradle new file mode 100644 index 0000000000..a830965143 --- /dev/null +++ b/test/tests.gradle @@ -0,0 +1,45 @@ +apply plugin: 'google-test' +task check() {} + +model { + testSuites { + ntcoreTest { + if (!project.hasProperty('skipJava')) { + setupJniIncludes(binaries) + } + sources { + cpp { + source { + srcDirs = ['test/unit'] + includes = ['**/*.cpp'] + } + exportedHeaders { + 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" + } + } + } + } +} + +binaries.withType(GoogleTestTestSuiteBinarySpec) { + if (project.hasProperty('wpilib')) { + lib project: ':ntcore:gmock', library: "gmock", linkage: "static" + } else { + lib project: ':gmock', library: "gmock", linkage: "static" + } + if (targetPlatform.operatingSystem.linux) { + cppCompiler.args '-pthread', '-std=c++1y' + linker.args '-pthread' + } else { + cppCompiler.args '/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS' + } +} diff --git a/toolchains/arm.gradle b/toolchains/arm.gradle new file mode 100644 index 0000000000..27a96656c8 --- /dev/null +++ b/toolchains/arm.gradle @@ -0,0 +1,66 @@ +def compilerPrefix = 'arm-frc-linux-gnueabi-' +model { + toolChains { + gcc(Gcc) { + 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 + cppCompiler.executable + linker.executable = compilerPrefix + linker.executable + assembler.executable = compilerPrefix + assembler.executable + // 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' << '-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 + staticLibArchiver.executable + } + } + } +} + +ext.setupReleaseDefines = { cppCompiler, linker -> + cppCompiler.args '-O2', '-g' +} + +ext.setupDebugDefines = { cppCompiler, linker -> + cppCompiler.args '-g', '-O0' +} + +ext.releaseSetup = { releaseTask -> + binaries.withType(SharedLibraryBinarySpec) { binary -> + if (!project.hasProperty('debug')) { + def library = binary.sharedLibraryFile.absolutePath + def debugLibrary = binary.sharedLibraryFile.absolutePath + ".debug" + if (project.tasks.findByName("firstObjcopy${binary.name}") == null) { + def firstObjcopy = project.tasks.create("firstObjcopy${binary.name}", Exec) { task -> + task.commandLine "${compilerPrefix}objcopy", '--only-keep-debug', library, debugLibrary + } + def strip = project.tasks.create("strip${binary.name}", Exec) { task -> + task.commandLine "${compilerPrefix}strip", '-g', library + } + def secondObjcopy = project.tasks.create("secondObjcopy${binary.name}", Exec) { task -> + task.commandLine "${compilerPrefix}objcopy", "--add-gnu-debuglink=$debugLibrary", library + } + secondObjcopy.dependsOn strip + strip.dependsOn firstObjcopy + binary.tasks.whenObjectAdded { task -> + if (task.name.contains('link')) { + firstObjcopy.dependsOn task + } + } + } + releaseTask.dependsOn project.tasks.getByName("secondObjcopy${binary.name}") + } + } +} diff --git a/toolchains/linux.gradle b/toolchains/linux.gradle new file mode 100644 index 0000000000..9295604215 --- /dev/null +++ b/toolchains/linux.gradle @@ -0,0 +1,70 @@ +model { + toolChains { + gcc(Gcc) { + target('x86') { + cppCompiler.withArguments { args -> + args << '-std=c++11' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic' + args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-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 << '-m32' + } + linker.withArguments { args -> + args << '-rdynamic' + args << '-m32' + } + } + target('x64') { + cppCompiler.withArguments { args -> + args << '-std=c++11' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic' + args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-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' + } + linker.withArguments { args -> + args << '-rdynamic' + } + } + } + } +} + +ext.setupReleaseDefines = { cppCompiler, linker -> + cppCompiler.args '-O2', '-g' +} + +ext.setupDebugDefines = { cppCompiler, linker -> + cppCompiler.args '-g', '-O0' +} + +ext.releaseSetup = { releaseTask -> + binaries.withType(SharedLibraryBinarySpec) { binary -> + if (!project.hasProperty('debug')) { + def library = binary.sharedLibraryFile.absolutePath + def debugLibrary = binary.sharedLibraryFile.absolutePath + ".debug" + if (project.tasks.findByName("firstObjcopy${binary.name}") == null) { + def firstObjcopy = project.tasks.create("firstObjcopy${binary.name}", Exec) { task -> + task.commandLine 'objcopy', '--only-keep-debug', library, debugLibrary + } + def strip = project.tasks.create("strip${binary.name}", Exec) { task -> + task.commandLine 'strip', '-g', library + } + def secondObjcopy = project.tasks.create("secondObjcopy${binary.name}", Exec) { task -> + task.commandLine 'objcopy', "--add-gnu-debuglink=$debugLibrary", library + } + secondObjcopy.dependsOn strip + strip.dependsOn firstObjcopy + binary.tasks.whenObjectAdded { task -> + if (task.name.contains('link')) { + firstObjcopy.dependsOn task + } + } + } + releaseTask.dependsOn project.tasks.getByName("secondObjcopy${binary.name}") + } + } +} diff --git a/toolchains/mac.gradle b/toolchains/mac.gradle new file mode 100644 index 0000000000..9515609c94 --- /dev/null +++ b/toolchains/mac.gradle @@ -0,0 +1,57 @@ +model { + toolChains { + clang(Clang) { + target('x86') { + cppCompiler.withArguments { args -> + args << '-std=c++11' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic-errors' + args << '-Wno-unused-parameter' << '-fPIC' << '-m32' + } + linker.withArguments { args -> + args << '-m32' + } + } + target('x64') { + cppCompiler.withArguments { args -> + args << '-std=c++11' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic-errors' + args << '-Wno-unused-parameter' << '-fPIC' + } + } + } + } +} + +ext.setupReleaseDefines = { cppCompiler, linker -> + cppCompiler.args '-O2' +} + +ext.setupDebugDefines = { cppCompiler, linker -> + cppCompiler.args '-g', '-O0' +} + +ext.releaseSetup = { releaseTask -> + binaries.withType(SharedLibraryBinarySpec) { binary -> + if (!project.hasProperty('debug')) { + def library = binary.sharedLibraryFile.absolutePath + def debugLibrary = binary.sharedLibraryFile.absolutePath + ".debug" + if (project.tasks.findByName("firstObjcopy${binary.name}") == null) { + def firstObjcopy = project.tasks.create("firstObjcopy${binary.name}", Exec) { task -> + task.commandLine 'objcopy', '--only-keep-debug', library, debugLibrary + } + def strip = project.tasks.create("strip${binary.name}", Exec) { task -> + task.commandLine 'strip', '-g', library + } + def secondObjcopy = project.tasks.create("secondObjcopy${binary.name}", Exec) { task -> + task.commandLine 'objcopy', "--add-gnu-debuglink=$debugLibrary", library + } + secondObjcopy.dependsOn strip + strip.dependsOn firstObjcopy + binary.tasks.whenObjectAdded { task -> + if (task.name.contains('link')) { + firstObjcopy.dependsOn task + } + } + } + releaseTask.dependsOn project.tasks.getByName("secondObjcopy${binary.name}") + } + } +} diff --git a/toolchains/windows.gradle b/toolchains/windows.gradle new file mode 100644 index 0000000000..b24f962672 --- /dev/null +++ b/toolchains/windows.gradle @@ -0,0 +1,49 @@ +model { + toolChains { + visualCpp(VisualCpp) { + // Workaround for VS2015 adapted from https://github.com/couchbase/couchbase-lite-java-native/issues/23 + def VS_2015_INCLUDE_DIR = "C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt" + def VS_2015_LIB_DIR = "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.10240.0/ucrt" + def VS_2015_INSTALL_DIR = 'C:/Program Files (x86)/Microsoft Visual Studio 14.0' + def vsInstallDir = file(VS_2015_INSTALL_DIR) + + // If you ever happen to install and uninstall any other version of VS, Gradle will misdetect the compiler + // and linker to run. This fixes that by manually setting the install dir + if (vsInstallDir.exists()) { + installDir = vsInstallDir + } + + eachPlatform { + cppCompiler.withArguments { args -> + args << '/EHsc' << '/DNOMINMAX' << '/D_SCL_SECURE_NO_WARNINGS' << '/D_WINSOCK_DEPRECATED_NO_WARNINGS' + if (file(VS_2015_INCLUDE_DIR).exists()) { + args << "/I$VS_2015_INCLUDE_DIR" + } + } + linker.withArguments { args -> + if (file(VS_2015_LIB_DIR).exists()) { + if (platform.architecture.name == 'x86') { + args << "/LIBPATH:$VS_2015_LIB_DIR/x86" + } else { + args << "/LIBPATH:$VS_2015_LIB_DIR/x64" + } + } + } + } + } + } +} + +ext.setupReleaseDefines = { cppCompiler, linker -> + cppCompiler.args '/O2', '/Zi', '/FS' + linker.args '/DEF:ntcore.def' +} + +ext.setupDebugDefines = { cppCompiler, linker -> + cppCompiler.args '/Zi', '/FS' + linker.args '/DEBUG', '/DEF:ntcore.def' +} + +// This is a noop on Windows. On gcc platforms, we strip the release binary and create a separate +// debug library, but Windows already separates debug symbols into a .pdb file. +ext.releaseSetup = {}