3
3
import os
4
4
import sys
5
5
6
+ # Workaround for MinGW. See:
7
+ # http://www.scons.org/wiki/LongCmdLinesOnWin32
8
+ if (os .name == "nt" ):
9
+ import subprocess
10
+
11
+ def mySubProcess (cmdline ,env ):
12
+ #print "SPAWNED : " + cmdline
13
+ startupinfo = subprocess .STARTUPINFO ()
14
+ startupinfo .dwFlags |= subprocess .STARTF_USESHOWWINDOW
15
+ proc = subprocess .Popen (cmdline , stdin = subprocess .PIPE , stdout = subprocess .PIPE ,
16
+ stderr = subprocess .PIPE , startupinfo = startupinfo , shell = False , env = env )
17
+ data , err = proc .communicate ()
18
+ rv = proc .wait ()
19
+ if rv :
20
+ print ("=====" )
21
+ print (err .decode ("utf-8" ))
22
+ print ("=====" )
23
+ return rv
24
+
25
+ def mySpawn (sh , escape , cmd , args , env ):
26
+
27
+ newargs = ' ' .join (args [1 :])
28
+ cmdline = cmd + " " + newargs
29
+
30
+ rv = 0
31
+ if len (cmdline ) > 32000 and cmd .endswith ("ar" ) :
32
+ cmdline = cmd + " " + args [1 ] + " " + args [2 ] + " "
33
+ for i in range (3 ,len (args )) :
34
+ rv = mySubProcess ( cmdline + args [i ], env )
35
+ if rv :
36
+ break
37
+ else :
38
+ rv = mySubProcess ( cmdline , env )
39
+
40
+ return rv
6
41
7
42
def add_sources (sources , dir , extension ):
8
43
for f in os .listdir (dir ):
@@ -29,7 +64,7 @@ opts.Add(EnumVariable(
29
64
'platform' ,
30
65
'Target platform' ,
31
66
host_platform ,
32
- allowed_values = ('linux' , 'osx' , 'windows' ),
67
+ allowed_values = ('linux' , 'osx' , 'windows' , 'android' ),
33
68
ignorecase = 2
34
69
))
35
70
opts .Add (EnumVariable (
@@ -73,16 +108,33 @@ opts.Add(BoolVariable(
73
108
'Generate GDNative API bindings' ,
74
109
False
75
110
))
111
+ opts .Add (EnumVariable (
112
+ 'android_arch' ,
113
+ 'Target Android architecture' ,
114
+ 'armv7' ,
115
+ ['armv7' ,'arm64v8' ,'x86' ,'x86_64' ]
116
+ ))
117
+ opts .Add (
118
+ 'android_api_level' ,
119
+ 'Target Android API level' ,
120
+ '18' if ARGUMENTS .get ("android_arch" , 'armv7' ) in ['armv7' , 'x86' ] else '21'
121
+ )
122
+ opts .Add (
123
+ 'ANDROID_NDK_ROOT' ,
124
+ 'Path to your Android NDK installation. By default, uses ANDROID_NDK_ROOT from your defined environment variables.' ,
125
+ os .environ .get ("ANDROID_NDK_ROOT" , None )
126
+ )
76
127
77
- env = Environment ()
128
+ env = Environment (ENV = os . environ )
78
129
opts .Update (env )
79
130
Help (opts .GenerateHelpText (env ))
80
131
81
132
is64 = sys .maxsize > 2 ** 32
82
133
if (
83
134
env ['TARGET_ARCH' ] == 'amd64' or
84
135
env ['TARGET_ARCH' ] == 'emt64' or
85
- env ['TARGET_ARCH' ] == 'x86_64'
136
+ env ['TARGET_ARCH' ] == 'x86_64' or
137
+ env ['TARGET_ARCH' ] == 'arm64-v8a'
86
138
):
87
139
is64 = True
88
140
@@ -92,7 +144,7 @@ if env['bits'] == 'default':
92
144
# This makes sure to keep the session environment variables on Windows.
93
145
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
94
146
# all the required tools
95
- if host_platform == 'windows' :
147
+ if host_platform == 'windows' and env [ 'platform' ] != 'android' :
96
148
if env ['bits' ] == '64' :
97
149
env = Environment (TARGET_ARCH = 'amd64' )
98
150
elif env ['bits' ] == '32' :
@@ -173,6 +225,62 @@ elif env['platform'] == 'windows':
173
225
'-static-libgcc' ,
174
226
'-static-libstdc++' ,
175
227
])
228
+ elif env ['platform' ] == 'android' :
229
+ if host_platform == 'windows' :
230
+ env = env .Clone (tools = ['mingw' ])
231
+ env ["SPAWN" ] = mySpawn
232
+
233
+ # Verify NDK root
234
+ if not 'ANDROID_NDK_ROOT' in env :
235
+ raise ValueError ("To build for Android, ANDROID_NDK_ROOT must be defined. Please set ANDROID_NDK_ROOT to the root folder of your Android NDK installation." )
236
+
237
+ # Validate API level
238
+ api_level = int (env ['android_api_level' ])
239
+ if env ['android_arch' ] in ['x86_64' , 'arm64v8' ] and api_level < 21 :
240
+ print ("WARN: 64-bit Android architectures require an API level of at least 21; setting android_api_level=21" )
241
+ env ['android_api_level' ] = '21'
242
+ api_level = 21
243
+
244
+ # Setup toolchain
245
+ toolchain = env ['ANDROID_NDK_ROOT' ] + "/toolchains/llvm/prebuilt/"
246
+ if host_platform == "windows" :
247
+ toolchain += "windows"
248
+ import platform as pltfm
249
+ if pltfm .machine ().endswith ("64" ):
250
+ toolchain += "-x86_64"
251
+ elif host_platform == "linux" :
252
+ toolchain += "linux-x86_64"
253
+ elif host_platform == "osx" :
254
+ toolchain += "darwin-x86_64"
255
+ env .PrependENVPath ('PATH' , toolchain + "/bin" ) # This does nothing half of the time, but we'll put it here anyways
256
+
257
+ # Get architecture info
258
+ arch_info_table = {
259
+ "armv7" : {
260
+ "march" :"armv7-a" , "target" :"armv7a-linux-androideabi" , "tool_path" :"arm-linux-androideabi" , "compiler_path" :"armv7a-linux-androideabi" ,
261
+ "ccflags" : ['-mfpu=neon' ]
262
+ },
263
+ "arm64v8" : {
264
+ "march" :"armv8-a" , "target" :"aarch64-linux-android" , "tool_path" :"aarch64-linux-android" , "compiler_path" :"aarch64-linux-android" ,
265
+ "ccflags" : []
266
+ },
267
+ "x86" : {
268
+ "march" :"i686" , "target" :"i686-linux-android" , "tool_path" :"i686-linux-android" , "compiler_path" :"i686-linux-android" ,
269
+ "ccflags" : ['-mstackrealign' ]
270
+ },
271
+ "x86_64" : {"march" :"x86-64" , "target" :"x86_64-linux-android" , "tool_path" :"x86_64-linux-android" , "compiler_path" :"x86_64-linux-android" ,
272
+ "ccflags" : []
273
+ }
274
+ }
275
+ arch_info = arch_info_table [env ['android_arch' ]]
276
+
277
+ # Setup tools
278
+ env ['CC' ] = toolchain + "/bin/clang"
279
+ env ['CXX' ] = toolchain + "/bin/clang++"
280
+ env ['AR' ] = toolchain + "/bin/" + arch_info ['tool_path' ] + "-ar"
281
+
282
+ env .Append (CCFLAGS = ['--target=' + arch_info ['target' ] + env ['android_api_level' ], '-march=' + arch_info ['march' ], '-fPIC' ])#, '-fPIE', '-fno-addrsig', '-Oz'])
283
+ env .Append (CCFLAGS = arch_info ['ccflags' ])
176
284
177
285
env .Append (CPPPATH = [
178
286
'.' ,
@@ -202,10 +310,11 @@ add_sources(sources, 'src/core', 'cpp')
202
310
add_sources (sources , 'src/gen' , 'cpp' )
203
311
204
312
library = env .StaticLibrary (
205
- target = 'bin/' + 'libgodot-cpp.{}.{}.{}' .format (
313
+ target = 'bin/' + 'libgodot-cpp.{}.{}.{}{} ' .format (
206
314
env ['platform' ],
207
315
env ['target' ],
208
- env ['bits' ],
316
+ env ['bits' ] if env ['platform' ] != 'android' else env ['android_arch' ],
317
+ env ['LIBSUFFIX' ]
209
318
), source = sources
210
319
)
211
320
Default (library )
0 commit comments