forked from NationalSecurityAgency/ghidra
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nativeBuildProperties.gradle
204 lines (183 loc) · 7.78 KB
/
nativeBuildProperties.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
/****************************************************************************
* nativeBuildProperties.gradle
*
* This script contains global settings used by all projects that have
* native build requirements.
*
* This is NOT a complete build script for those
* projects; it is only meant to capture items that are common to all so
* we don't need to define them over and over again.
****************************************************************************/
/****************************************************************************
* Always apply the cpp and c plugin, for obvious reasons
****************************************************************************/
apply plugin: 'cpp'
apply plugin: 'c'
project.ext.VISUAL_STUDIO_BASE_DIR = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017"
// Ok, this is stupid, but mac and linux can't handle files paths that start with c:
// These paths are actually only used when running on windows, but the paths gets evaulated
// as a file no matter what platform you run gradle on. So the best solution I can think of is as
// follows.
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
project.ext.VISUAL_STUDIO_INSTALL_DIR = project.ext.VISUAL_STUDIO_BASE_DIR + "\\Professional"
if (!file(project.ext.VISUAL_STUDIO_INSTALL_DIR).exists()) {
project.ext.VISUAL_STUDIO_INSTALL_DIR = project.ext.VISUAL_STUDIO_BASE_DIR + "\\Community"
}
// TODO: Use of this will require coping with VC version in path
project.ext.WINDOWS_KITS_DIR = "C:/Program Files (x86)/Windows Kits/10.0"
project.ext.VISUAL_STUDIO_VCVARS_CMD = "\"${VISUAL_STUDIO_INSTALL_DIR}\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x86_amd64"
// TODO: force VisualCpp installDir and windowsSdkDir
// NOTE: Windows 7 targeting requires the use of the Windows 8.1 SDK and setting the
// WINVER property a value of "0x0601" which may be specified to the compiler/linker.
// If using a VS Solution this must be specified within the project file(s).
project.ext.WINVER = "0x0601"
}
else {
project.ext.VISUAL_STUDIO_INSTALL_DIR = "/"
project.ext.WINDOWS_KITS_DIR = "/"
project.ext.VISUAL_STUDIO_VCVARS_CMD = "NA"
}
/****************************************************************************
* Defines the platforms we have to support in Ghidra. This model is used
* for all native builds and should be extended by each module as-needed.
****************************************************************************/
model {
// define the platforms that we support in ghidra
platforms {
win32 {
architecture 'x86'
operatingSystem 'windows'
}
win64 {
architecture 'x86_64'
operatingSystem 'windows'
}
linux64 {
architecture 'x86_64'
operatingSystem 'linux'
}
osx64 {
architecture 'x86_64'
operatingSystem 'osx'
}
}
}
/*******************************************************************************************
* If task1 contains the given platform name, then it needs to be executed before
* task2. The task1 must be of type LinkExecutable or LinkSharedLibrary so that the
* targetPlatform may be inspected.
*
******************************************************************************************/
def addTaskDependencyForMyPlatform(task1, task2, platform) {
if (platform.equals(task1.targetPlatform.get().name)) {
task2.dependsOn task1.path
}
}
/*******************************************************************************************
* Returns true if the given task is a custom Make task (starts with the platform name and
* ends with "Make").
*
* Note that this is a Ghidra-specific task and is not one created dynamically by Gradle.
*
******************************************************************************************/
def isNativeBinaryMakeTask(Task task, String platform) {
if (task.name.startsWith(platform) && task.name.endsWith("Make")) {
return true
}
return false
}
/*******************************************************************************************
* Task Rule : builds all the natives in this module for a given platform.
*
* Example : gradle buildNatives_win64 will build all win64 native executables and shared libraries.
*
* NOTE: you must be on the appropriate platform for this to work.
*
******************************************************************************************/
tasks.addRule("Pattern: buildNatives_<platform name>]: build all natives for given platform") { String taskName ->
if (taskName.startsWith("buildNatives_")) {
String platform = taskName - "buildNatives_"
task(taskName) { myTask ->
project.tasks.withType(LinkExecutable) { t ->
addTaskDependencyForMyPlatform(t, myTask, platform)
}
project.tasks.withType(LinkSharedLibrary) { t ->
addTaskDependencyForMyPlatform(t, myTask, platform)
}
project.tasks.each { t ->
if (isNativeBinaryMakeTask(t, platform)) {
myTask.dependsOn t.path
}
}
// add callbacks to look for native build tasks when new tasks are added later
project.tasks.withType(LinkExecutable).whenTaskAdded { t ->
addTaskDependencyForMyPlatform(t, myTask, platform)
}
project.tasks.withType(LinkSharedLibrary).whenTaskAdded { t ->
addTaskDependencyForMyPlatform(t, myTask, platform)
}
project.tasks.whenTaskAdded { t ->
if (isNativeBinaryMakeTask(t, platform)) {
myTask.dependsOn t.path
}
}
doFirst {
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
// ensure that required MS Visual Studio is installed where expected
String msg = "Microsoft Visual Studio install not found: ${project.ext.VISUAL_STUDIO_BASE_DIR}\n" +
"Adjust path in Ghidra/GPL/nativeBuildProperties.gradle if needed."
assert file(project.ext.VISUAL_STUDIO_BASE_DIR).exists() : msg
assert file(project.ext.VISUAL_STUDIO_INSTALL_DIR).exists() : msg
}
}
}
}
}
/*******************************************************************************************
* Task Rule : builds all the natives in this module for a given platform and copies the
* results to the bin repo.
*
* Example : gradle prebuildNatives_win64 will build all win64 native executables and shared
* libraries and copy the results to the appropriate project/os directory in the bin
* repo.
*
* NOTE: you must be on the appropriate platform for this to work.
*
******************************************************************************************/
tasks.addRule("Pattern: prebuildNatives_<platform name>]: build all natives for given platform") { String taskName ->
if (taskName.startsWith("prebuildNatives_")) {
String platform = taskName - "prebuildNatives_"
task(taskName) { myTask ->
dependsOn "buildNatives_$platform"
doLast {
copy {
from "${projectDir}/build/os/${platform}"
into "${getProjectLocationInBinRepo(project)}/os/${platform}"
exclude "*.exp"
exclude "*.lib"
}
}
}
}
}
/*****************************************************************************************
* The following block of code changes the output directory for native builds
* to <projectDir>/build/os/<platform>/<executable> ?? is there a better way to do this?
****************************************************************************************/
gradle.taskGraph.whenReady {
def p = this.project
p.tasks.withType(LinkExecutable).each { t ->
File f = t.linkedFile.getAsFile().get()
String filename = f.getName()
NativePlatform platform = t.targetPlatform.get()
String osName = platform.getName()
t.linkedFile = p.file("build/os/${osName}/$filename")
}
p.tasks.withType(LinkSharedLibrary).each { t ->
File f = t.linkedFile.getAsFile().get()
String filename = f.getName()
NativePlatform platform = t.targetPlatform.get()
String osName = platform.getName()
t.linkedFile = p.file("build/os/${osName}/$filename")
}
}