Brian Silverman | 26e4e52 | 2015-12-17 01:56:40 -0500 | [diff] [blame^] | 1 | // This regex matches either a Windows or Unix style file separator, then the lib part of the library, |
| 2 | // then the name of the library itself, and finally the .so extension at the end. The name of the library |
| 3 | // is in the libName capture group, which is extracted and used for the linker flags |
| 4 | def libPattern = /.*((\\/|\\).*)+lib(?<libName>.+).so$/ |
| 5 | def niLibraryArgs = [] |
| 6 | def niLibraryPath = file('ni-libraries').path |
| 7 | |
| 8 | // The NI Library tree includes all non-wpi libraries, which is everything that doesn't have libwpi in the name |
| 9 | def niLibraryTree = fileTree(niLibraryPath) |
| 10 | niLibraryTree.include '*.so' |
| 11 | niLibraryTree.exclude '*wpi*.so' |
| 12 | |
| 13 | // This adds all linker flags to the list of ni library linker flags |
| 14 | niLibraryTree.each { lib -> |
| 15 | def nameMatcher = (lib.path =~ libPattern) |
| 16 | if (nameMatcher[0].size() > 1) { |
| 17 | def name = nameMatcher.group('libName') |
| 18 | niLibraryArgs << '-l' + name |
| 19 | } |
| 20 | } |
| 21 | |
| 22 | def ntDependency = |
| 23 | project.dependencies.create("edu.wpi.first.wpilib.networktables.cpp:NetworkTables:3.0.0-SNAPSHOT:arm@zip") |
| 24 | def config = project.configurations.detachedConfiguration(ntDependency) |
| 25 | config.setTransitive(false) |
| 26 | def netTables = config.files[0].canonicalFile |
| 27 | |
| 28 | def netTablesUnzipLocation = "$buildDir/networktables" |
| 29 | |
| 30 | // Create a task that will unzip the networktables files into a temporary build directory |
| 31 | task unzipNetworkTables(type: Copy) { |
| 32 | description = 'Unzips the networktables maven dependency so that the include files and libraries can be used' |
| 33 | group = 'WPILib' |
| 34 | from zipTree(netTables) |
| 35 | into netTablesUnzipLocation |
| 36 | } |
| 37 | |
| 38 | task clean(type: Delete) { |
| 39 | description = "Deletes the build directory" |
| 40 | group = "Build" |
| 41 | delete buildDir |
| 42 | } |
| 43 | |
| 44 | subprojects { |
| 45 | plugins.withType(CppPlugin).whenPluginAdded { |
| 46 | // This defines a project property that projects depending on network tables can use to setup that dependency. |
| 47 | ext.defineNetworkTablesProperties = { |
| 48 | ext.netTables = netTablesUnzipLocation |
| 49 | ext.netTablesInclude = "$netTablesUnzipLocation/include" |
| 50 | ext.netLibLocation = "$netTablesUnzipLocation/Linux/arm" |
| 51 | ext.netSharedLib = "$netLibLocation/libntcore.so" |
| 52 | ext.netStaticLib = "$netLibLocation/libntcore.a" |
| 53 | |
| 54 | task addNetworkTablesLibraryLinks() { |
| 55 | description = 'Adds the linker flags for the networktables libraries retreived from maven' |
| 56 | group = 'WPILib' |
| 57 | dependsOn project(':').unzipNetworkTables |
| 58 | doLast { |
| 59 | binaries.all { |
| 60 | tasks.withType(CppCompile) { |
| 61 | // desktop version doesn't use all the NI libraries |
| 62 | // so only do this for arm libraries |
| 63 | String architecture = targetPlatform.architecture |
| 64 | if (architecture.contains('arm')){ |
| 65 | linker.args netStaticLib |
| 66 | } |
| 67 | } |
| 68 | } |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | model { |
| 74 | buildTypes { |
| 75 | debug |
| 76 | } |
| 77 | // Adds a custom toolchain for our compiler prefix and options |
| 78 | toolChains { |
| 79 | gcc(Gcc) { |
| 80 | target('arm') { |
| 81 | // We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name> |
| 82 | // If this ever changes, the prefix will need to be changed here |
| 83 | def compilerPrefix = 'arm-frc-linux-gnueabi-' |
| 84 | cppCompiler.executable = compilerPrefix + cppCompiler.executable |
| 85 | linker.executable = compilerPrefix + linker.executable |
| 86 | assembler.executable = compilerPrefix + assembler.executable |
| 87 | // Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports |
| 88 | // arm, and doesn't understand this flag, so it is removed from both |
| 89 | cppCompiler.withArguments { args -> |
| 90 | args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic' |
| 91 | args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-O0' << '-g3' << '-rdynamic' |
| 92 | //TODO: When the compiler allows us to actually call deprecated functions from within |
| 93 | // deprecated function, remove this line (this will cause calling deprecated functions |
| 94 | // to be treated as a warning rather than an error). |
| 95 | args << '-Wno-error=deprecated-declarations' |
| 96 | args.remove('-m32') |
| 97 | } |
| 98 | linker.withArguments { args -> |
| 99 | args << '-rdynamic' |
| 100 | args.remove('-m32') |
| 101 | } |
| 102 | staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable |
| 103 | } |
| 104 | } |
| 105 | // Workaround for OS X. Macs for some reason want to use Xcode's gcc |
| 106 | // (which just wraps Clang), so we have to explicitly make it so |
| 107 | // that trying to compile with Clang will call gcc instead |
| 108 | macGcc(Clang) { |
| 109 | target('arm') { |
| 110 | // We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name> |
| 111 | // If this ever changes, the prefix will need to be changed here |
| 112 | def compilerPrefix = 'arm-frc-linux-gnueabi-' |
| 113 | cppCompiler.executable = compilerPrefix + 'g++' |
| 114 | linker.executable = compilerPrefix + 'g++' |
| 115 | assembler.executable = compilerPrefix + 'gcc' |
| 116 | // Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports |
| 117 | // arm, and doesn't understand this flag, so it is removed from both |
| 118 | cppCompiler.withArguments { args -> |
| 119 | args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic' |
| 120 | args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-O0' << '-g3' << '-rdynamic' |
| 121 | //TODO: When the compiler allows us to actually call deprecated functions from within |
| 122 | // deprecated function, remove this line (this will cause calling deprecated functions |
| 123 | // to be treated as a warning rather than an error). |
| 124 | args << '-Wno-error=deprecated-declarations' |
| 125 | args.remove('-m32') |
| 126 | } |
| 127 | linker.withArguments { args -> |
| 128 | args << '-rdynamic' |
| 129 | args.remove('-m32') |
| 130 | } |
| 131 | staticLibArchiver.executable = compilerPrefix + 'ar' |
| 132 | } |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | // The only platform is arm linux |
| 137 | platforms { |
| 138 | arm { |
| 139 | architecture 'arm' |
| 140 | operatingSystem 'linux' |
| 141 | } |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | // This task adds the appropriate linker flags for the NI libraries |
| 146 | task addNiLibraryLinks() { |
| 147 | description = 'Adds the linker flags for the NI libraries in the ni-library folders' |
| 148 | group = 'WPILib' |
| 149 | doLast { |
| 150 | binaries.all { |
| 151 | tasks.withType(CppCompile) { |
| 152 | // desktop version doesn't use all the NI libraries |
| 153 | // so only do this for arm libraries |
| 154 | String architecture = targetPlatform.architecture |
| 155 | if (architecture.contains('arm')){ |
| 156 | linker.args << '-L' + niLibraryPath |
| 157 | linker.args.addAll(niLibraryArgs) |
| 158 | } |
| 159 | } |
| 160 | } |
| 161 | model { |
| 162 | repositories { |
| 163 | libs(PrebuiltLibraries) { libs -> |
| 164 | // Loops through all .so files (except files matching *libwpi*.so) in ../ni-libraries |
| 165 | // and includes them for linking |
| 166 | niLibraryTree.each { niLib -> |
| 167 | libs.create(niLib) { |
| 168 | binaries.withType(SharedLibraryBinary) { |
| 169 | sharedLibraryFile = file(niLib.path) |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | } |
| 174 | } |
| 175 | } |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | } |