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