forked from NationalSecurityAgency/ghidra
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdistributableGhidraModule.gradle
212 lines (180 loc) · 7.03 KB
/
distributableGhidraModule.gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*****************************************************************************************
This file is a "mix-in" gradle script that individual gradle projects should include if it
has content that should be included in a distribution. (Unless the content should be included
as an "extension", in which case it should include "extensionModule" instead)
A gradle project can add itself to the distribution build by adding the following to its
build.gradle file:
apply from: "$rootProject.projectDir/gradle/support/distributableGhidraModule.gradle"
*****************************************************************************************/
apply from: "$rootProject.projectDir/gradle/support/distributionCommon.gradle"
rootProject.assembleDistribution {
def p = this.project
def zipPath = getZipPath(p)
from (p.projectDir.toString() + "/Module.manifest") {
into { zipPath }
}
from (p.projectDir.toString() + "/data") {
into { zipPath + "/data" }
exclude 'build.xml' // associated with language modules (dev use only)
}
from (BIN_REPO + '/' + getGhidraRelativePath(p) + "/data") {
into { zipPath + "/data" }
}
from (p.projectDir.toString() + "/build/LICENSE.txt") {
into { zipPath }
}
// handle special case where modules build data artifacts into the build dir
from (p.projectDir.toString() + "/build/data") {
into {zipPath + "/data" }
}
/////////////////
// SOURCE FOR BUILD
//
// Some projects require that we provide source that can be built (makefiles,
// gradle build files, c-code, etc...). If a project has a task for that
// purpose, execute it here.
//
// Note the 'afterEvaluate' call - this must be done so the zip task in the
// subproject is added to the task graph before the 'dependsOn' clause is
// executed. If we don't do this, that dependsOn relationship won't be respected
// and the subproject zip task won't be executed.
/////////////////
p.tasks.each { t ->
if (t.name == "zipBuildableSource") {
assembleDistribution.dependsOn {t}
from (t) {
into zipPath
}
}
}
///////////////////////
// copy Global files - files in a module under 'src/global' are copied to the project root
// relative to its location under 'src/global'
///////////////////////
// First get a list of all files that are under 'src/global'.
FileTree fileTree = p.fileTree('src/global') {
include '**/*'
}
// Now loop over each one, copying it into the zip we're creating. Each will be placed
// at the root level, starting with the first folder AFTER 'src/global/'.
//
// eg: If the file is '/Ghidra/Configurations/Common/src/global/docs/hello.html', then
// the file in the zip will be at /docs/hello.html
//
fileTree.each { File file ->
String filePath = getGlobalFilePathSubDirName(file)
from (file) {
into filePath
}
}
}
// copy os specific files for each platform
rootProject.PLATFORMS.each { platform ->
rootProject.tasks.findAll {it.name == "assembleDistribution_${platform.name}"}.each { t ->
def p = this.project
// the getZipPath calls here are not in closures because we are already in a taskGraph.whenReady closure
t.from (p.projectDir.toString() + "/build/os/${platform.name}") {
exclude '*.lib'
exclude '*.exp'
into getZipPath(p) + "/os/${platform.name}"
}
t.from (p.projectDir.toString() + "/os/${platform.name}") {
into getZipPath(p) + "/os/${platform.name}"
}
}
}
// For win_x86_64 build, we have to also include any win_x86_32 binaries in the final zip.
rootProject.assembleDistribution_win_x86_64 {
from (this.project.projectDir.toString() + "/build/os/win_x86_32") {
into getZipPath(this.project) + "/os/win_x86_32"
}
}
/*********************************************************************************
* Takes the given file and returns a string representing the file path with everything
* up-to and including 'src/global' removed, as well as the filename.
*
* eg: If the file path is '/Ghidra/Configurations/Common/src/global/docs/hello.html',
* the returned string will be at /docs
*
* Note: We have to use 'File.separator' instead of a slash ('/') because of how
* windows/unix handle slashes ('/' vs. '\'). We only need to do this in cases where we're
* using java string manipulation libraries (eg String.replace); Gradle already
* understands how to use the proper slash.
*********************************************************************************/
String getGlobalFilePathSubDirName(File file) {
// First strip off everything before 'src/global/ in the file path.
def slashIndex = file.path.indexOf('src' + File.separator + 'global')
String filePath = file.path.substring(slashIndex);
// Now remove 'src/global/' from the string.
filePath = filePath.replace('src' + File.separator + 'global' + File.separator, "");
// Now we need to strip off the filename itself, which we do by finding the last
// instance of a slash ('/') in the string.
//
// Note that it's possible there is no slash (all we have is a filename), meaning
// this file will be placed at the root level.
//
slashIndex = filePath.lastIndexOf(File.separator)
if (slashIndex != -1) {
filePath = filePath.substring(0, slashIndex+1) // +1 for the slash
}
else {
filePath = ""
}
return filePath
}
plugins.withType(JavaPlugin) {
// build up a java classpath for javadocs
rootProject.ghidraPath.from(sourceSets.main.compileClasspath)
rootProject.assembleSource {
from (this.project.zipSourceSubproject) {
into rootProject.ext.ZIP_DIR_PREFIX + "/" + getZipPath(this.project) + "/lib"
}
}
rootProject.assembleDistribution {
dependsOn assemble
def p = this.project
def zipPath = getZipPath(p)
from (p.jar) {
// use closures for getting zip path to delay evaluation. See note at top of file.
into { zipPath + "/lib" }
}
from (p.projectDir.toString() + "/ghidra_scripts") {
exclude 'bin/'
into { zipPath + "/ghidra_scripts" }
}
// External Libraries
gradle.taskGraph.whenReady { taskGraph ->
List<String> externalPaths = getExternalRuntimeDependencies(p)
externalPaths.each { path ->
from (path) {
into {zipPath + "/lib" }
}
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Native
/////////////////////////////////////////////////////////////////////////////
plugins.withType(CPlugin) {
rootProject.PLATFORMS.each { platform ->
rootProject.tasks.findAll {it.name == "assembleDistribution_${platform.name}"}.each { t ->
t.dependsOn this.assemble
}
}
}