crown-android.rb 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. # Copyright (c) 2013 Daniele Bartolini, Michele Rossi
  2. # Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
  3. #
  4. # Permission is hereby granted, free of charge, to any person
  5. # obtaining a copy of this software and associated documentation
  6. # files (the "Software"), to deal in the Software without
  7. # restriction, including without limitation the rights to use,
  8. # copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. # copies of the Software, and to permit persons to whom the
  10. # Software is furnished to do so, subject to the following
  11. # conditions:
  12. #
  13. # The above copyright notice and this permission notice shall be
  14. # included in all copies or substantial portions of the Software.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. # OTHER DEALINGS IN THE SOFTWARE.
  24. require 'optparse'
  25. require 'ostruct'
  26. require 'fileutils'
  27. $config_h =
  28. "
  29. #define CROWN_VERSION_MAJOR 0
  30. #define CROWN_VERSION_MINOR 1
  31. #define CROWN_VERSION_MICRO 13
  32. #define PRId64 \"lld\"
  33. #define PRIu64 \"llu\"
  34. #define PRIi64 \"lli\"
  35. #define PRIx64 \"llx\"
  36. #define CE_PIXELS_PER_METER 32
  37. #define CE_MAX_TEXTURE_UNITS 8
  38. #define CE_MAX_TEXTURES 32
  39. #define CE_MAX_RENDER_TARGETS 32
  40. #define CE_MAX_VERTEX_BUFFERS 1024
  41. #define CE_MAX_INDEX_BUFFERS 1024
  42. #define CE_MAX_SHADERS 512
  43. #define CE_MAX_GPU_PROGRAMS 512
  44. #define CE_MAX_UNIFORMS 128
  45. #define CE_TRANSIENT_VERTEX_BUFFER_SIZE 6 * 1024 * 1024 // In bytes
  46. #define CE_TRANSIENT_INDEX_BUFFER_SIZE 2 * 1024 * 1024 // In bytes
  47. #define CE_MAX_UNIFORM_NAME_LENGTH 64 // Including NUL character
  48. #define CE_MAX_WORLDS 1024
  49. #define CE_MAX_UNITS 65000 // Per world
  50. #define CE_MAX_CAMERAS 16 // Per world
  51. #define CE_MAX_ACTORS 1024 // Per world
  52. #define CE_MAX_CONTROLLERS 16 // Per world
  53. #define CE_MAX_TRIGGERS 1024 // Per world
  54. #define CE_MAX_JOINTS 512 // Per world
  55. #define CE_MAX_SOUND_INSTANCES 64 // Per world
  56. #define CE_MAX_RAYCASTS 8 // Per World
  57. #define CE_MAX_RAY_INTERSECTIONS 16
  58. #define CE_MAX_CAMERA_COMPONENTS 16 // Per unit
  59. #define CE_MAX_MESH_COMPONENTS 16 // Per unit
  60. #define CE_MAX_SPRITE_COMPONENTS 16 // Per unit
  61. #define CE_MAX_ACTOR_COMPONENTS 16 // Per unit
  62. #define CE_MAX_MATERIAL_COMPONENTS 16 // Per unit
  63. #define CE_MAX_CONSOLE_CLIENTS 32
  64. #define CE_MAX_GUI_RECTS 64 // Per Gui
  65. #define CE_MAX_GUI_TRIANGLES 64 // Per Gui
  66. #define CE_MAX_GUI_IMAGES 64 // Per Gui
  67. #define CE_MAX_GUI_TEXTS 64 // Per Gui
  68. #define CE_MAX_DEBUG_LINES 2 * 1024 // Per DebugLine
  69. #define CE_MAX_LUA_VECTOR2 4096
  70. #define CE_MAX_LUA_VECTOR3 4096
  71. #define CE_MAX_LUA_MATRIX4X4 4096
  72. #define CE_MAX_LUA_QUATERNION 4096
  73. "
  74. $application_mk =
  75. "
  76. APP_PLATFORM := android-10
  77. APP_STL := gnustl_static
  78. APP_ABI := armeabi-v7a
  79. "
  80. # Commands
  81. $android_create = "android create project"
  82. $android_update = "android update project"
  83. $activity = "CrownActivity"
  84. $package = "crown.android"
  85. # Paths
  86. $engine_src = "../engine/."
  87. $android_src = "../engine/os/android/java/."
  88. $android_manifest = "../engine/os/android/AndroidManifest.xml"
  89. $luajit = "../third/luajit/android"
  90. $physx = "../third/physx/android"
  91. #------------------------------------------------------------------------------
  92. def validate_command_line(args)
  93. if args.length < 8
  94. return false
  95. end
  96. if args[0] != "--build"
  97. return false
  98. end
  99. if args[2] != "--target"
  100. return false
  101. end
  102. if args[4] != "--name"
  103. return false
  104. end
  105. if args[6] != "--path"
  106. return false
  107. end
  108. return true
  109. end
  110. #------------------------------------------------------------------------------
  111. def parse_command_line(args)
  112. banner = "Usage: crown-android.rb --build BUILD --target TARGET --name NAME --path PATH [--res RES]\n"
  113. if not validate_command_line(args)
  114. print banner
  115. exit
  116. end
  117. options = OpenStruct.new
  118. OptionParser.new do |opts|
  119. opts.banner = banner
  120. opts.on("-b", "--build BUILD", "Crown build") do |b|
  121. options.build = b
  122. end
  123. opts.on("-t", "--target TARGET", "Android target") do |t|
  124. options.target = t
  125. end
  126. opts.on("-n", "--name NAME", "Android project name") do |n|
  127. options.name = n
  128. end
  129. opts.on("-p", "--path PATH", "Android project path") do |p|
  130. options.path = p
  131. end
  132. opts.on("-r", "--res RES", "Android project compiled resources") do |r|
  133. options.res = r
  134. end
  135. opts.on_tail("-h", "--help", "Show this message") do
  136. puts opts
  137. exit
  138. end
  139. end.parse!(args)
  140. return options
  141. end
  142. #------------------------------------------------------------------------------
  143. def generate_config_h(build, dest)
  144. if build == "debug"
  145. $config_h << "#define CROWN_DEBUG"
  146. elsif build == "development"
  147. $config_h << "#define CROWN_DEVELOPMENT"
  148. elsif build == "release"
  149. $config_h << "#define CROWN_RELEASE"
  150. end
  151. f = File.new(dest, File::WRONLY|File::CREAT|File::TRUNC, 0644)
  152. f.write($config_h)
  153. f.close()
  154. end
  155. #------------------------------------------------------------------------------
  156. def generate_application_mk(target, dest)
  157. f = File.new(dest, File::WRONLY|File::CREAT|File::TRUNC, 0644)
  158. f.write($application_mk)
  159. f.write("APP_APPLICATION := " + target)
  160. f.close()
  161. end
  162. #------------------------------------------------------------------------------
  163. def create_android_project(target, name, path)
  164. engine_dest = path + "/jni"
  165. android_dest = path + "/src/crown/android"
  166. assets_dest = path + "/assets"
  167. # Creates path if not exists
  168. if not Dir.exists?(path)
  169. print "Creating directory " + path + "..."
  170. FileUtils.mkdir_p(path)
  171. print "OK!\n"
  172. end
  173. # Project path is not empty
  174. if not Dir["#{path}/."].empty?
  175. print "Cleaning directory " + path + "..."
  176. FileUtils.rm_rf("#{path}/.", :secure => true)
  177. print "OK!\n"
  178. end
  179. # Creates android project
  180. print "Creating android project...\n"
  181. system($android_create + " --target " + target + " --name " + name + " --path " + path + " --activity " + $activity + " --package " + $package)
  182. print "OK!\n"
  183. # if jni dir does not exists, create it!
  184. if not Dir.exists?(engine_dest)
  185. print "Creating directory " + engine_dest + "..."
  186. FileUtils.mkdir_p(engine_dest)
  187. print "OK!\n"
  188. end
  189. # if assets dir does not exists, create it!
  190. if not Dir.exists?(assets_dest)
  191. print "Creating directory " + assets_dest + "..."
  192. FileUtils.mkdir_p(assets_dest)
  193. print "OK!\n"
  194. end
  195. end
  196. #------------------------------------------------------------------------------
  197. def fill_android_project(build, target, res, path)
  198. engine_dest = path + "/jni"
  199. android_dest = path + "/src/crown/android"
  200. resources_dest = path + "/assets"
  201. print "Filling Android project..."
  202. # Copy Engine files
  203. FileUtils.cp_r($engine_src, engine_dest, :remove_destination => true)
  204. FileUtils.cp_r($engine_src + "/../third", engine_dest, :remove_destination => true)
  205. # Generate android Config.h
  206. generate_config_h(build, engine_dest + "/Config.h")
  207. # Generate Application.mk
  208. generate_application_mk(target, engine_dest + "/Application.mk")
  209. # Copy luajit lib
  210. FileUtils.cp($luajit + "/lib/libluajit-5.1.so.2.0.2", engine_dest + "/libluajit-5.1.so")
  211. # Copy physx lib
  212. FileUtils.cp($physx + "/lib/libPhysX3.a", engine_dest)
  213. FileUtils.cp($physx + "/lib/libSimulationController.a", engine_dest)
  214. FileUtils.cp($physx + "/lib/libLowLevel.a", engine_dest)
  215. FileUtils.cp($physx + "/lib/libLowLevelCloth.a", engine_dest)
  216. FileUtils.cp($physx + "/lib/libPxTask.a", engine_dest)
  217. FileUtils.cp($physx + "/lib/libPhysXProfileSDK.a", engine_dest)
  218. FileUtils.cp($physx + "/lib/libPhysX3Extensions.a", engine_dest)
  219. FileUtils.cp($physx + "/lib/libSceneQuery.a", engine_dest)
  220. FileUtils.cp($physx + "/lib/libPhysX3Common.a", engine_dest)
  221. FileUtils.cp($physx + "/lib/libPhysX3CharacterKinematic.a", engine_dest)
  222. FileUtils.cp($physx + "/lib/libPhysX3Vehicle.a", engine_dest)
  223. FileUtils.cp($physx + "/lib/libPhysX3Cooking.a", engine_dest)
  224. FileUtils.cp($physx + "/lib/libPvdRuntime.a", engine_dest)
  225. # Copy java files
  226. FileUtils.cp_r(Dir.glob($android_src), android_dest, :remove_destination => true)
  227. # Copy android manifest
  228. FileUtils.cp($android_manifest, path)
  229. if build == "release"
  230. FileUtils.cp_r(res + "/.", resources_dest)
  231. end
  232. print "OK!\n"
  233. end
  234. #------------------------------------------------------------------------------
  235. def build_android_project(path)
  236. print "Building...\n"
  237. # Move to root directory of Android project
  238. Dir.chdir(path)
  239. # Build libraries
  240. if not system("ndk-build")
  241. print "Critical error: Unable to build crown libraries"
  242. return
  243. end
  244. # Build apk
  245. # FIXME: it's convenient to build apk in debug mode because we avoid apk signature.
  246. # In a near future, we'll manage the build process in release mode
  247. # N.B: you can build crown in release mode and run 'ant debug' for achieving the same result of a final product
  248. if not system("ant debug")
  249. print "Critical error: Unable to build crown project"
  250. return
  251. else
  252. print "Done!\n"
  253. end
  254. end
  255. #------------------------------------------------------------------------------
  256. opts = parse_command_line(ARGV)
  257. create_android_project(opts.target, opts.name, opts.path)
  258. fill_android_project(opts.build, opts.target, opts.res, opts.path)
  259. build_android_project(opts.path)