2
0

Rakefile 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. #
  2. # Copyright (c) 2008-2014 the Urho3D project.
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining a copy
  5. # of this software and associated documentation files (the "Software"), to deal
  6. # in the Software without restriction, including without limitation the rights
  7. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. # copies of the Software, and to permit persons to whom the Software is
  9. # furnished to do so, subject to the following conditions:
  10. #
  11. # The above copyright notice and this permission notice shall be included in
  12. # all copies or substantial portions of the Software.
  13. #
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. # THE SOFTWARE.
  21. #
  22. require 'pathname'
  23. require 'json'
  24. if ENV['IOS']
  25. require 'time'
  26. end
  27. # Usage: rake sync (only intended to be used in a fork with remote 'upstream' set to urho3d/Urho3D)
  28. desc 'Fetch and merge upstream urho3d/Urho3D to a Urho3D fork'
  29. task :sync do
  30. system "cwb=`git symbolic-ref -q --short HEAD || git rev-parse --short HEAD`; export cwb && git fetch upstream && git checkout master && git pull && git merge -m 'Sync at #{Time.now.localtime}.' upstream/master && git push && git checkout $cwb"
  31. end
  32. # Usage: rake scaffolding dir=/path/to/new/project/root [project=Scaffolding] [target=Main]
  33. desc 'Create a new project using Urho3D as external library'
  34. task :scaffolding do
  35. abort 'Usage: rake scaffolding dir=/path/to/new/project/root [project=Scaffolding] [target=Main]' unless ENV['dir']
  36. abs_path = (ENV['OS'] ? ENV['dir'][1, 1] == ':' : ENV['dir'][0, 1] == '/') ? ENV['dir'] : "#{Dir.pwd}/#{ENV['dir']}"
  37. project = ENV['project'] || 'Scaffolding'
  38. target = ENV['target'] || 'Main'
  39. scaffolding(abs_path, project, target)
  40. abs_path = Pathname.new(abs_path).realpath
  41. puts "\nNew project created in #{abs_path}\n\n"
  42. puts "To build the new project, you may need to first set and export either 'URHO3D_HOME' or 'CMAKE_PREFIX_PATH' environment variable"
  43. puts "Please see http://urho3d.github.io/documentation/HEAD/_using_library.html for more detail. For example:\n\n"
  44. if ENV['OS']
  45. puts "set URHO3D_HOME=#{Dir.pwd}\ncd #{abs_path}\ncmake_vs2013.bat -DURHO3D_64BIT=1 -DURHO3D_LUAJIT=1\n\n"
  46. else
  47. puts "export URHO3D_HOME=#{Dir.pwd}\ncd #{abs_path}\n./cmake_gcc.sh -DURHO3D_LUAJIT=1\ncd Build\nmake\n\n"
  48. end
  49. end
  50. # Usage: rake android [parameter='--es pickedLibrary Urho3DPlayer'] [intent=.SampleLauncher] [package=com.github.urho3d] [success_indicator='Initialized engine'] [payload='sleep 30'] [api=19] [abi=armeabi-v7a] [avd=test_#{api}_#{abi}] [retries=10] [retry_interval=10]
  51. desc 'Test run already installed APK in Android (virtual) device, default to Urho3D Samples APK if no parameter is given'
  52. task :android do
  53. parameter = ENV['parameter'] || '--es pickedLibrary Urho3DPlayer'
  54. intent = ENV['intent'] || '.SampleLauncher'
  55. package = ENV['package'] || 'com.github.urho3d'
  56. success_indicator = ENV['success_indicator'] || 'Initialized engine'
  57. payload = ENV['payload'] || 'sleep 30'
  58. api = ENV['api'] || 19
  59. abi = ENV['abi'] || 'armeabi-v7a'
  60. avd = ENV['avd'] || "test_#{api}_#{abi}"
  61. retries = ENV['retries'] || 10 # minutes
  62. retry_interval = ENV['retry_interval'] || 10 # seconds
  63. android_prepare_device api, abi, avd or abort 'Failed to prepare Android (virtual) device for test run'
  64. android_wait_for_device retries, retry_interval or abort 'Failed to start Android (virtual) device'
  65. android_test_run parameter, intent, package, success_indicator, payload or abort "Failed to test run #{package}/#{intent}, make sure the APK has been installed"
  66. end
  67. # Usage: NOT intended to be used manually (if you insist then try: rake ci)
  68. desc 'Configure, build, and test Urho3D project'
  69. task :ci do
  70. # Unshallow the clone's history when necessary
  71. if ENV['CI'] && ENV['PACKAGE_UPLOAD'] && !ENV['RELEASE_TAG']
  72. system 'git fetch --unshallow' or abort 'Failed to unshallow cloned repository'
  73. end
  74. # Packaging always use Release configuration (temporary workaround due to Travis-CI insufficient memory, also use Release configuration when CI build runs on a bad VM)
  75. if ENV['PACKAGE_UPLOAD'] || ENV['BAD_VM']
  76. $configuration = 'Release'
  77. $testing = 0
  78. else
  79. $configuration = 'Debug'
  80. # Only 64-bit Linux environment with virtual framebuffer X server support and not MinGW build; or OSX build environment and not iOS build are capable to run tests
  81. $testing = (ENV['LINUX'] && !ENV['URHO3D_64BIT']) || (ENV['OSX'] && ENV['IOS'].to_i != 1) ? 1 : 0
  82. end
  83. # Define the build option string only when the override environment variable is given
  84. $build_options = "-DURHO3D_64BIT=#{ENV['URHO3D_64BIT']}" if ENV['URHO3D_64BIT']
  85. $build_options = "#{$build_options} -DURHO3D_OPENGL=#{ENV['URHO3D_OPENGL']}" if ENV['URHO3D_OPENGL']
  86. $build_options = "#{$build_options} -DANDROID_ABI=#{ENV['ABI']}" if ENV['ABI']
  87. $build_options = "#{$build_options} -DANDROID_NATIVE_API_LEVEL=#{ENV['API']}" if ENV['API']
  88. if ENV['XCODE']
  89. # xctool or xcodebuild
  90. xcode_ci
  91. else
  92. # GCC or Clang
  93. makefile_ci
  94. end
  95. end
  96. # Usage: NOT intended to be used manually (if you insist then try: GIT_NAME=... GIT_EMAIL=... GH_TOKEN=... rake ci_site_update)
  97. desc 'Update site documentation to GitHub Pages'
  98. task :ci_site_update do
  99. # Pull or clone
  100. system 'cd doc-Build 2>/dev/null && git pull -q -r || git clone --depth 1 -q https://github.com/urho3d/urho3d.github.io.git doc-Build' or abort 'Failed to pull/clone'
  101. # Update credits from Readme.txt to about.md
  102. system "ruby -lne 'BEGIN { credits = false }; puts $_ if credits; credits = true if /bugfixes by:/; credits = false if /^$/' Readme.txt |ruby -i -le 'credits = STDIN.read; puts ARGF.read.gsub(/(?<=bugfixes by\n).*?(?=##)/m, credits)' doc-Build/about.md" or abort 'Failed to update credits'
  103. # Setup doxygen to use minimal theme
  104. system "ruby -i -pe 'BEGIN { a = {%q{HTML_HEADER} => %q{minimal-header.html}, %q{HTML_FOOTER} => %q{minimal-footer.html}, %q{HTML_STYLESHEET} => %q{minimal-doxygen.css}, %q{HTML_COLORSTYLE_HUE} => 200, %q{HTML_COLORSTYLE_SAT} => 0, %q{HTML_COLORSTYLE_GAMMA} => 20, %q{DOT_IMAGE_FORMAT} => %q{svg}, %q{INTERACTIVE_SVG} => %q{YES}} }; a.each {|k, v| gsub(/\#{k}\s*?=.*?\n/, %Q{\#{k} = \#{v}\n}) }' Docs/Doxyfile" or abort 'Failed to setup doxygen configuration file'
  105. system 'cp doc-Build/_includes/Doxygen/minimal-* Docs' or abort 'Failed to copy minimal-themed template'
  106. release = ENV['RELEASE_TAG'] || 'HEAD'
  107. unless release == 'HEAD'
  108. system "mkdir -p doc-Build/documentation/#{release}" or abort 'Failed to create directory for new document version'
  109. system "ruby -i -pe 'gsub(/HEAD/, %q{#{release}})' Docs/minimal-header.html" or abort 'Failed to update document version in YAML Front Matter block'
  110. append_new_release release, 'doc-Build/_data/urho3d.json' or abort 'Failed to add new release to document data file'
  111. end
  112. # Generate and sync doxygen pages
  113. system "cd Build && make -j$NUMJOBS doc >/dev/null 2>&1 && ruby -i -pe 'gsub(/(<\\/?h)3([^>]*?>)/, %q{\\14\\2}); gsub(/(<\\/?h)2([^>]*?>)/, %q{\\13\\2}); gsub(/(<\\/?h)1([^>]*?>)/, %q{\\12\\2})' ../Docs/html/_*.html && rsync -a --delete ../Docs/html/ ../doc-Build/documentation/#{release}" or abort 'Failed to generate/rsync doxygen pages'
  114. # Supply GIT credentials and push site documentation to urho3d/urho3d.github.io.git
  115. system "cd doc-Build && pwd && git config user.name $GIT_NAME && git config user.email $GIT_EMAIL && git remote set-url --push origin https://[email protected]/urho3d/urho3d.github.io.git && git add -A . && ( git commit -q -m \"Travis CI: site documentation update at #{Time.now.utc}.\n\nCommit: https://github.com/$TRAVIS_REPO_SLUG/commit/$TRAVIS_COMMIT\n\nMessage: $COMMIT_MESSAGE\" || true) && git push -q >/dev/null 2>&1" or abort 'Failed to update site'
  116. # Automatically give instruction to do packaging when API has changed, unless the instruction is already given in this commit
  117. if ENV['PACKAGE_UPLOAD']
  118. instruction = 'skip'
  119. else
  120. instruction = 'package'
  121. end
  122. if !ENV['RELEASE_TAG']
  123. # Supply GIT credentials and push API documentation to urho3d/Urho3D.git (the push may not be successful if remote master has already diverged)
  124. system 'pwd && git config user.name $GIT_NAME && git config user.email $GIT_EMAIL && git remote set-url --push origin https://[email protected]/$TRAVIS_REPO_SLUG.git && git add Docs/*API*'
  125. if system("git commit -q -m 'Travis CI: API documentation update at #{Time.now.utc}.\n[ci #{instruction}]'") && !ENV['PACKAGE_UPLOAD']
  126. bump_soversion 'Source/Engine/.soversion' or abort 'Failed to bump soversion'
  127. system "git add Source/Engine/.soversion && git commit --amend -q -m 'Travis CI: API documentation update at #{Time.now.utc}.\n[ci #{instruction}]'" or abort 'Failed to stage .soversion file'
  128. end
  129. system "git push origin HEAD:master -q >/dev/null 2>&1" or abort 'Failed to update API documentation, most likely due to remote master has diverged, the API documentation update will be performed again in the subsequent CI build'
  130. end
  131. end
  132. # Usage: NOT intended to be used manually (if you insist then try: GIT_NAME=... GIT_EMAIL=... GH_TOKEN=... rake ci_rebase)
  133. desc 'Rebase all CI mirror branches'
  134. task :ci_rebase do
  135. system 'git config user.name $GIT_NAME && git config user.email $GIT_EMAIL && git remote set-url --push origin https://[email protected]/$TRAVIS_REPO_SLUG.git'
  136. baseline = ENV['RELEASE_TAG'] || "origin/#{ENV['TRAVIS_BRANCH']}"
  137. [ 'Android-CI', 'RPI-CI', 'OSX-CI' ].each { |branch| system "git fetch origin #{branch}:#{branch} && git rebase #{baseline} #{branch} && git push -qf -u origin #{branch} >/dev/null 2>&1" or abort "Failed to rebase #{branch} mirror branch" }
  138. end
  139. # Usage: NOT intended to be used manually (if you insist then try: rake ci_package_upload)
  140. desc 'Make binary package and upload it to a designated central hosting server'
  141. task :ci_package_upload do
  142. if ENV['XCODE']
  143. $configuration = 'Release'
  144. $testing = 0
  145. end
  146. if ENV['ANDROID']
  147. platform_prefix = 'android-'
  148. elsif ENV['WINDOWS']
  149. platform_prefix = 'mingw-'
  150. elsif ENV['IOS']
  151. platform_prefix = 'ios-'
  152. elsif ENV['RPI']
  153. platform_prefix = 'raspi-'
  154. else
  155. platform_prefix = ''
  156. end
  157. # Generate the documentation if necessary
  158. unless ENV['SITE_UPDATE']
  159. system 'echo Generate documentation'
  160. if ENV['XCODE']
  161. xcode_build(ENV['IOS'], "#{platform_prefix}Build/Urho3D.xcodeproj", 'doc', '>/dev/null') or abort 'Failed to generate documentation'
  162. else
  163. system "cd #{platform_prefix}Build && make -j$NUMJOBS doc >/dev/null" or abort 'Failed to generate documentation'
  164. end
  165. end
  166. # Make the package
  167. if ENV['IOS']
  168. # Skip Mach-O universal binary build if Travis-CI VM took too long to get here, as otherwise overall build time may exceed 50 minutes time limit
  169. if ENV['CI_START_TIME'] then
  170. elapsed_time = (Time.now - Time.parse(ENV['CI_START_TIME'])) / 60
  171. puts "\niOS checkpoint reached, elapsed time: #{elapsed_time}\n\n"
  172. end
  173. if !ENV['CI_START_TIME'] || elapsed_time < 15 # minutes
  174. # Build Mach-O universal binary consisting of iphoneos (universal ARM archs including 'arm64' if 64-bit is enabled) and iphonesimulator (i386 arch and also x86_64 arch if 64-bit is enabled)
  175. system 'echo Rebuild Urho3D library as Mach-O universal binary'
  176. xcode_build(0, "#{platform_prefix}Build/Urho3D.xcodeproj", 'Urho3D_universal') or abort 'Failed to build Mach-O universal binary'
  177. end
  178. # There is a bug in CMake/CPack that causes the 'package' target failed to build for IOS platform, workaround by calling cpack directly
  179. system "cd #{platform_prefix}Build && cpack -G TGZ 2>/dev/null" or abort 'Failed to make binary package'
  180. elsif ENV['XCODE']
  181. xcode_build(ENV['IOS'], "#{platform_prefix}Build/Urho3D.xcodeproj", 'package') or abort 'Failed to make binary package'
  182. else
  183. if ENV['ANDROID'] && !ENV['NO_SDK_SYSIMG']
  184. system "cd #{platform_prefix}Build && android update project -p . -t $( android list target |grep android-$API |cut -d ' ' -f2 ) && ant debug" or abort 'Failed to make Urho3D Samples APK'
  185. end
  186. system "cd #{platform_prefix}Build && make package" or abort 'Failed to make binary package'
  187. end
  188. # Determine the upload location
  189. setup_digital_keys
  190. if !ENV['RELEASE_TAG']
  191. upload_dir = "/home/frs/project/#{ENV['TRAVIS_REPO_SLUG']}/Snapshots"
  192. if ENV['SITE_UPDATE']
  193. # Download source packages from GitHub
  194. system "export SNAPSHOT_VER=$(git describe $TRAVIS_COMMIT |ruby -pe 'gsub(/-(?!g)/, %q{.})'); wget -q https://github.com/$TRAVIS_REPO_SLUG/tarball/$TRAVIS_COMMIT -O Urho3D-$SNAPSHOT_VER-Source-snapshot.tar.gz && wget -q https://github.com/$TRAVIS_REPO_SLUG/zipball/$TRAVIS_COMMIT -O Urho3D-$SNAPSHOT_VER-Source-snapshot.zip" or abort 'Failed to get source packages'
  195. # Only keep the snapshots from the last 30 revisions
  196. system "for v in $(sftp [email protected] <<EOF |tr ' ' '\n' |grep Urho3D- |cut -d '-' -f1,2 |uniq |tail -n +31
  197. cd #{upload_dir}
  198. ls -1r
  199. bye
  200. EOF
  201. ); do echo rm #{upload_dir}/${v}*; done |sftp -b - [email protected]" or abort 'Failed to housekeep snapshots'
  202. end
  203. else
  204. upload_dir = "/home/frs/project/#{ENV['TRAVIS_REPO_SLUG']}/#{ENV['RELEASE_TAG']}"
  205. if ENV['SITE_UPDATE']
  206. # Download source packages from GitHub
  207. system 'wget -q https://github.com/$TRAVIS_REPO_SLUG/archive/$RELEASE_TAG.tar.gz -O Urho3D-$RELEASE_TAG-Source.tar.gz && wget -q https://github.com/$TRAVIS_REPO_SLUG/archive/$RELEASE_TAG.zip -O Urho3D-$RELEASE_TAG-Source.zip' or abort 'Failed to get source packages'
  208. end
  209. # Make sure the release directory exists remotely, do this in all the build jobs as we don't know which one would start uploading first
  210. system "sftp [email protected] <<EOF >/dev/null 2>&1
  211. mkdir #{upload_dir}
  212. bye
  213. EOF" or abort 'Failed to create release directory remotely'
  214. end
  215. if ENV['SITE_UPDATE']
  216. # Upload the source package
  217. system "scp Urho3D-* [email protected]:#{upload_dir}" or abort 'Failed to upload source package'
  218. # Sync readme and license files, just in case they are updated in the repo
  219. system 'for f in Readme.txt License.txt; do mtime=$(git log --format=%ai -n1 $f); touch -d "$mtime" $f; done' or abort 'Failed to acquire file modified time'
  220. system 'rsync -e ssh -az Readme.txt License.txt [email protected]:/home/frs/project/$TRAVIS_REPO_SLUG' or abort 'Failed to sync readme and license files'
  221. end
  222. # Upload the package
  223. system "scp #{platform_prefix}Build/Urho3D-* [email protected]:#{upload_dir}" or abort 'Failed to upload binary package'
  224. end
  225. def scaffolding(dir, project = 'Scaffolding', target = 'Main')
  226. build_script = <<EOF
  227. # Set project name
  228. project (#{project})
  229. # Set minimum version
  230. cmake_minimum_required (VERSION 2.8.6)
  231. if (COMMAND cmake_policy)
  232. cmake_policy (SET CMP0003 NEW)
  233. if (CMAKE_VERSION VERSION_GREATER 2.8.12 OR CMAKE_VERSION VERSION_EQUAL 2.8.12)
  234. cmake_policy (SET CMP0022 NEW) # INTERFACE_LINK_LIBRARIES defines the link interface
  235. endif ()
  236. if (CMAKE_VERSION VERSION_GREATER 3.0.0 OR CMAKE_VERSION VERSION_EQUAL 3.0.0)
  237. cmake_policy (SET CMP0026 OLD) # Disallow use of the LOCATION target property - therefore we set to OLD as we still need it
  238. cmake_policy (SET CMP0042 NEW) # MACOSX_RPATH is enabled by default
  239. endif ()
  240. endif ()
  241. # Set CMake modules search path
  242. set (CMAKE_MODULE_PATH
  243. $ENV{URHO3D_HOME}/Source/CMake/Modules
  244. $ENV{CMAKE_PREFIX_PATH}/share/Urho3D/CMake/Modules
  245. ${CMAKE_INSTALL_PREFIX}/share/Urho3D/CMake/Modules
  246. CACHE PATH \"Path to Urho3D-specific CMake modules\")
  247. # Include Urho3D CMake common module
  248. include (Urho3D-CMake-common)
  249. # Find Urho3D library
  250. find_package (Urho3D REQUIRED)
  251. include_directories (${URHO3D_INCLUDE_DIRS})
  252. # Define target name
  253. set (TARGET_NAME #{target})
  254. # Define source files
  255. define_source_files ()
  256. # Setup target with resource copying
  257. setup_main_executable ()
  258. # Setup test cases
  259. if (URHO3D_ANGELSCRIPT)
  260. add_test (NAME ExternalLibAS COMMAND ${TARGET_NAME} Data/Scripts/12_PhysicsStressTest.as -w -timeout ${URHO3D_TEST_TIME_OUT})
  261. endif ()
  262. if (URHO3D_LUA)
  263. add_test (NAME ExternalLibLua COMMAND ${TARGET_NAME} Data/LuaScripts/12_PhysicsStressTest.lua -w -timeout ${URHO3D_TEST_TIME_OUT})
  264. endif ()
  265. EOF
  266. # TODO: Rewrite in pure Ruby when it supports symlink creation on Windows platform
  267. if ENV['OS']
  268. system("@echo off && (for %d in (Source,Bin) do mkdir #{dir}\\%d) && copy Source\\Tools\\Urho3DPlayer\\Urho3DPlayer.* #{dir}\\Source >nul && (for %f in (*.bat Rakefile) do mklink #{dir}\\%f %cd%\\%f >nul) && (for %d in (CoreData,Data) do mklink /D #{dir}\\Bin\\%d %cd%\\Bin\\%d >nul)") && File.write("#{dir}/Source/CMakeLists.txt", build_script) or abort 'Failed to create new project using Urho3D as external library'
  269. else
  270. system("bash -c \"mkdir -p #{dir}/{Source,Bin} && cp Source/Tools/Urho3DPlayer/Urho3DPlayer.* #{dir}/Source && for f in {.,}*.sh Rakefile; do ln -sf `pwd`/\\$f #{dir}; done && ln -sf `pwd`/Bin/{Core,}Data #{dir}/Bin\"") && File.write("#{dir}/Source/CMakeLists.txt", build_script) or abort 'Failed to create new project using Urho3D as external library'
  271. end
  272. end
  273. def makefile_ci
  274. if ENV['WINDOWS']
  275. # MinGW package on Ubuntu 12.04 LTS does not come with d3dcompiler.h file which is required by our CI build with URHO3D_OPENGL=0.
  276. # Temporarily workaround the problem by downloading the missing header from Ubuntu 14.04 LTS source package.
  277. if ENV['URHO3D_OPENGL'] && ENV['CI'] then
  278. system "sudo wget -P $(echo |$MINGW_PREFIX-gcc -v -E - 2>&1 |grep -B 1 'End of search list' |head -1) http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/mingw-w64/trusty/download/package-import%40ubuntu.com-20130624192537-vzn12bb7qd5w3iy8/d3dcompiler.h-20120402093420-bk10a737hzitlkgj-65/d3dcompiler.h" or abort 'Failed to download d3dcompiler.h header'
  279. end
  280. # LuaJIT on MinGW build is not possible on Ubuntu 12.04 LTS as its GCC cross-compiler version is too old. Fallback to use Lua library instead.
  281. jit = ''
  282. amalg = ''
  283. # Lua on MinGW build requires tolua++ tool to be built natively first
  284. system "MINGW_PREFIX= ./cmake_gcc.sh -DURHO3D_LIB_TYPE=$URHO3D_LIB_TYPE #{$build_options} -DURHO3D_LUA=1 -DURHO3D_TOOLS=0" or abort 'Failed to configure native build for tolua++ target'
  285. system "cd Build/ThirdParty/toluapp/src/bin && make -j$NUMJOBS" or abort 'Failed to build tolua++ tool'
  286. ENV['SKIP_NATIVE'] = '1'
  287. elsif ENV['ANDROID'] && ENV['ABI'] == 'arm64-v8a'
  288. # The upstream LuaJIT library does not support this Android ABI at the moment, fallback to use Lua library instead
  289. jit = ''
  290. amalg = ''
  291. else
  292. jit = 'JIT'
  293. amalg = '-DURHO3D_LUAJIT_AMALG=1'
  294. end
  295. system "./cmake_gcc.sh -DURHO3D_LIB_TYPE=$URHO3D_LIB_TYPE #{$build_options} -DURHO3D_LUA#{jit}=1 #{amalg} -DURHO3D_SAMPLES=1 -DURHO3D_TOOLS=1 -DURHO3D_EXTRAS=1 -DURHO3D_TESTING=#{$testing} -DCMAKE_BUILD_TYPE=#{$configuration}" or abort 'Failed to configure Urho3D library build'
  296. if ENV['ANDROID']
  297. if ENV['AVD'] && !ENV['PACKAGE_UPLOAD'] # Skip APK test run when packaging
  298. android_prepare_device ENV['API'], ENV['ABI'], ENV['AVD'] or abort 'Failed to prepare Android (virtual) device for test run'
  299. end
  300. # LuaJIT on Android build requires tolua++ and buildvm-android tools to be built natively first
  301. system "cd Build/ThirdParty/toluapp/src/bin && make -j$NUMJOBS" or abort 'Failed to build tolua++ tool'
  302. if !jit.empty?
  303. system "cd Build/ThirdParty/Lua#{jit}/generated/buildvm-android-#{ENV['ABI']} && make -j$NUMJOBS" or abort 'Failed to build buildvm-android tool'
  304. end
  305. # Reconfigure Android build one more time now that we have the tools built
  306. ENV['SKIP_NATIVE'] = '1'
  307. system './cmake_gcc.sh' or abort 'Failed to reconfigure Urho3D library for Android build'
  308. platform_prefix = 'android-'
  309. elsif ENV['RPI']
  310. # LuaJIT on Raspberry Pi build requires tolua++ and buildvm-raspi tools to be built natively first
  311. system "cd Build/ThirdParty/toluapp/src/bin && make -j$NUMJOBS" or abort 'Failed to build tolua++ tool'
  312. system "cd Build/ThirdParty/LuaJIT/generated/buildvm-raspi && make -j$NUMJOBS" or abort 'Failed to build buildvm-raspi tool'
  313. # Reconfigure Raspberry Pi build one more time now that we have the tools built
  314. ENV['SKIP_NATIVE'] = '1'
  315. system './cmake_gcc.sh' or abort 'Failed to reconfigure Urho3D library for Raspberry Pi build'
  316. platform_prefix = 'raspi-'
  317. elsif ENV['WINDOWS']
  318. platform_prefix = 'mingw-'
  319. else
  320. platform_prefix = ''
  321. end
  322. if $testing == 1
  323. test = '&& make test'
  324. else
  325. test = ''
  326. end
  327. system "cd #{platform_prefix}Build && make -j$NUMJOBS #{test}" or abort 'Failed to build or test Urho3D library'
  328. # Create a new project on the fly that uses newly built Urho3D library
  329. scaffolding "#{platform_prefix}Build/generated/externallib"
  330. system "URHO3D_HOME=`pwd`; export URHO3D_HOME && cd #{platform_prefix}Build/generated/externallib && echo '\nUsing Urho3D as external library in external project' && ./cmake_gcc.sh #{$build_options} -DURHO3D_LUA#{jit}=1 -DURHO3D_TESTING=#{$testing} -DCMAKE_BUILD_TYPE=#{$configuration} && cd #{platform_prefix}Build && make -j$NUMJOBS #{test}" or abort 'Failed to configure/build/test temporary project using Urho3D as external library'
  331. # Make, deploy, and test run Android APK in an Android (virtual) device
  332. if ENV['AVD'] && !ENV['PACKAGE_UPLOAD']
  333. system "cd #{platform_prefix}Build && android update project -p . -t $( android list target |grep android-$API |cut -d ' ' -f2 ) && ant debug" or abort 'Failed to make Urho3D Samples APK'
  334. if android_wait_for_device ENV['CI'] ? 1 : 10 # minutes
  335. system "cd #{platform_prefix}Build && ant -Dadb.device.arg='-s #{$specific_device}' installd" or abort 'Failed to deploy Urho3D Samples APK'
  336. android_test_run or abort 'Failed to test run Urho3D Samples APK'
  337. else
  338. puts 'Skipped test running Urho3D Samples APK as emulator failed to start in time'
  339. end
  340. end
  341. end
  342. def android_find_device api = nil, abi = nil
  343. # Return the previously found matching device or if not found yet then try to find the matching device now
  344. return $specific_device if $specific_device
  345. wait = api ? '' : 'wait-for-device'
  346. $specific_api = api.to_s if api
  347. $specific_abi = abi.to_s if abi
  348. for i in `adb #{wait} devices |tail -n +2`.split "\n"
  349. device = i.split.first
  350. if `adb -s #{device} wait-for-device shell getprop ro.build.version.sdk`.chomp == $specific_api && `adb -s #{device} shell getprop ro.product.cpu.abi`.chomp == $specific_abi
  351. return $specific_device = device
  352. end
  353. end
  354. nil
  355. end
  356. def android_prepare_device api, abi = 'armeabi-v7a', name = 'test'
  357. system 'if ! ps |grep -cq adb; then adb start-server; fi'
  358. if !android_find_device api, abi
  359. # Don't have any matching (virtual) device attached, try to attach the named device (create the named device as AVD if necessary)
  360. if !system "android list avd |grep -cq 'Name: #{name}$'"
  361. system "echo 'no' |android create avd -n #{name} -t android-#{api} --abi #{abi}" or abort "Failed to create '#{name}' Android virtual device"
  362. end
  363. system "if [ $CI ]; then export OPTS='-no-skin -no-audio -no-window -no-boot-anim -gpu off'; else export OPTS='-gpu on'; fi; emulator -avd #{name} $OPTS &"
  364. end
  365. return 0
  366. end
  367. def android_wait_for_device retries = -1, retry_interval = 10, package = 'android.process.acore' # Waiting for HOME by default
  368. # Wait until the indicator process is running or it is killed externally by user via Ctrl+C or when it exceeds the number of retries (if the retries parameter is provided)
  369. str = "\nWaiting for device..."
  370. thread = Thread.new { android_find_device }; sleep 0.5
  371. process_ready = false
  372. retries = retries * 60 / retry_interval unless retries == -1
  373. until retries == 0
  374. if thread.status == false
  375. thread.join
  376. break if process_ready
  377. process_ready = thread = Thread.new { `adb -s #{$specific_device} shell 'until ps |grep -c #{package} >/dev/null; do sleep #{retry_interval}; done; while ps |grep -c bootanimation >/dev/null; do sleep 1; done'` }; sleep 0.5
  378. next
  379. end
  380. print str; str = '.'; $stdout.flush # Flush the standard output stream in case it is buffered to prevent Travis-CI into thinking that the build/test has stalled
  381. sleep retry_interval
  382. retries -= 1 if retries > 0
  383. end
  384. puts "\n\n" if str == '.'; $stdout.flush
  385. return retries == 0 ? nil : 0
  386. end
  387. def android_test_run parameter = '--es pickedLibrary Urho3DPlayer', intent = '.SampleLauncher', package = 'com.github.urho3d', success_indicator = 'Added resource path /apk/CoreData/', payload = 'sleep 30'
  388. # The device should have been found at this point
  389. return nil unless $specific_device
  390. # Capture adb's stdout and interpret it because adb neither uses stderr nor returns proper exit code on error
  391. begin
  392. IO.popen("adb -s #{$specific_device} shell <<EOF
  393. # Try to unlock the device just in case it is locked
  394. input keyevent 82; input keyevent 4
  395. # Clear the log
  396. logcat -c
  397. # Start the app
  398. am start -a android.intent.action.MAIN -n #{package}/#{intent} #{parameter}
  399. # Wait until the process is running
  400. until ps |grep -c #{package} 1>/dev/null; do sleep 1; done
  401. # Execute the payload
  402. #{payload}
  403. # Exit and stop the app
  404. input keyevent 4 && am force-stop #{package}
  405. # Dump the log
  406. logcat -d
  407. # Bye bye
  408. exit
  409. ##
  410. EOF") { |stdout| echo = false; while output = stdout.gets do if echo && /#\s#/ !~ output then puts output else echo = true if /^##/ =~ output end; return nil if /^error/i =~ output end }
  411. # Result of the test run is determined based on the presence of the success indicator string in the log
  412. system "adb -s #{$specific_device} logcat -d |grep -cq '#{success_indicator}'"
  413. rescue
  414. nil
  415. end
  416. end
  417. def xcode_ci
  418. if ENV['IOS']
  419. # IOS platform does not support LuaJIT
  420. jit = ''
  421. amalg = ''
  422. platform_prefix = 'ios-'
  423. deployment_target = "-DIPHONEOS_DEPLOYMENT_TARGET=#{ENV['DEPLOYMENT_TARGET']}"
  424. # Lua on IOS build requires tolua++ tool to be built natively first
  425. system "./cmake_macosx.sh -DURHO3D_LIB_TYPE=$URHO3D_LIB_TYPE #{$build_options} -DURHO3D_LUA=1 -DURHO3D_TOOLS=0" or abort 'Failed to configure native build for tolua++ target'
  426. xcode_build(0, 'Build/Urho3D.xcodeproj', 'tolua++') or abort 'Failed to build tolua++ tool'
  427. else
  428. jit = 'JIT'
  429. amalg = '-DURHO3D_LUAJIT_AMALG=1'
  430. platform_prefix = ''
  431. deployment_target = "-DCMAKE_OSX_DEPLOYMENT_TARGET=#{ENV['DEPLOYMENT_TARGET']}"
  432. end
  433. system "./cmake_macosx.sh -DIOS=$IOS #{deployment_target} -DURHO3D_LIB_TYPE=$URHO3D_LIB_TYPE #{$build_options} -DURHO3D_LUA#{jit}=1 #{amalg} -DURHO3D_SAMPLES=1 -DURHO3D_TOOLS=1 -DURHO3D_EXTRAS=1 -DURHO3D_TESTING=#{$testing}" or abort 'Failed to configure Urho3D library build'
  434. xcode_build(ENV['IOS'], "#{platform_prefix}Build/Urho3D.xcodeproj") or abort 'Failed to build or test Urho3D library'
  435. # Create a new project on the fly that uses newly built Urho3D library
  436. scaffolding "#{platform_prefix}Build/generated/externallib"
  437. system "URHO3D_HOME=`pwd`; export URHO3D_HOME && cd #{platform_prefix}Build/generated/externallib && echo '\nUsing Urho3D as external library in external project' && ./cmake_macosx.sh -DIOS=$IOS #{deployment_target} #{$build_options} -DURHO3D_LUA#{jit}=1 -DURHO3D_TESTING=#{$testing}" or abort 'Failed to configure temporary project using Urho3D as external library'
  438. xcode_build(ENV['IOS'], "#{platform_prefix}Build/generated/externallib/#{platform_prefix}Build/Scaffolding.xcodeproj") or abort 'Failed to configure/build/test temporary project using Urho3D as external library'
  439. end
  440. def xcode_build(ios, project, target = 'ALL_BUILD', extras = '')
  441. sdk = ios.to_i == 1 ? '-sdk iphonesimulator' : ''
  442. # Use xcpretty to filter output from xcodebuild when building
  443. system "xcodebuild -project #{project} -target #{target} -configuration #{$configuration} #{sdk} |xcpretty -c #{extras} && exit ${PIPESTATUS[0]}" or return nil
  444. if $testing == 1 && target == 'ALL_BUILD' # Disable testing for other targets such as 'doc', 'package', etc
  445. # Use vanila xcodebuild when testing as its output is instantaneous (ensure Travis-CI does not kill the process during testing)
  446. system "xcodebuild -project #{project} -target RUN_TESTS -configuration #{$configuration} #{sdk} #{extras}" or return nil
  447. end
  448. return 0
  449. end
  450. def append_new_release release, filename
  451. begin
  452. urho3d_hash = JSON.parse File.read filename
  453. unless urho3d_hash['releases'].last == release
  454. urho3d_hash['releases'] << release
  455. end
  456. File.open filename, 'w' do |file|
  457. file.puts urho3d_hash.to_json
  458. end
  459. return 0
  460. rescue
  461. nil
  462. end
  463. end
  464. def bump_soversion filename
  465. begin
  466. version = File.read(filename).split '.'
  467. bump_version version, 2
  468. File.open filename, 'w' do |file|
  469. file.puts version.join '.'
  470. end
  471. return 0
  472. rescue
  473. nil
  474. end
  475. end
  476. def bump_version version, index
  477. if index > 0 && version[index].to_i == 255
  478. version[index] = 0
  479. bump_version version, index - 1
  480. else
  481. version[index] = version[index].to_i + 1
  482. end
  483. end
  484. def setup_digital_keys
  485. system 'mkdir -p ~/.ssh && chmod 700 ~/.ssh' or abort 'Failed to create ~/.ssh directory'
  486. system "cat <<EOF >>~/.ssh/known_hosts
  487. frs.sourceforge.net,216.34.181.57 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2uifHZbNexw6cXbyg1JnzDitL5VhYs0E65Hk/tLAPmcmm5GuiGeUoI/B0eUSNFsbqzwgwrttjnzKMKiGLN5CWVmlN1IXGGAfLYsQwK6wAu7kYFzkqP4jcwc5Jr9UPRpJdYIK733tSEmzab4qc5Oq8izKQKIaxXNe7FgmL15HjSpatFt9w/ot/CHS78FUAr3j3RwekHCm/jhPeqhlMAgC+jUgNJbFt3DlhDaRMa0NYamVzmX8D47rtmBbEDU3ld6AezWBPUR5Lh7ODOwlfVI58NAf/aYNlmvl2TZiauBCTa7OPYSyXJnIPbQXg6YQlDknNCr0K769EjeIlAfY87Z4tw==
  488. EOF" or abort 'Failed to append frs.sourceforge.net server public key to known_hosts'
  489. # Workaround travis encryption key size limitation. Rather than using the solution in their FAQ (using AES to encrypt/decrypt the file and check in the encrypted file into repo), our solution is more pragmatic. The private key below is incomplete. Only the missing portion is encrypted. Much less secure than the original 2048-bit RSA has to offer but good enough for our case.
  490. system "cat <<EOF >~/.ssh/id_rsa
  491. -----BEGIN RSA PRIVATE KEY-----
  492. MIIEpQIBAAKCAQEAnZGzFEypdXKY3KDT0Q3NLY4Bv74yKgJ4LIgbXothx8w4CfM0
  493. VeWBL/AE2iRISEWGB07LruM9y+U/wt58WlCVu001GuJuvXwWenlljsvH8qQlErYi
  494. oXlCwAeVVeanILGL8CPS7QlyzOwwnVF6NdcmfDJjTthBVFbvHrWGo5if86zcZyMR
  495. 2BB5QVEr5fU0yOPFp0+2p7J3cA6HQSKwjUiDtJ+lM62UQp7InCCT3qeh5KYHQcYb
  496. KVJTyj5iycVuBujHDwNAivLq82ojG7LcKjP+Ia8fblardCOQyFk6pSDM79NJJ2Dg
  497. 3ZbYIJeUmqSqFhRW/13Bro7Z1aNGrdh/XZkkHwIDAQABAoIBACHcBFJxYtzVIloO
  498. yVWcFKIcaO3OLjNu0monWVJIu1tW3BfvRijLJ6aoejJyJ4I4RmPdn9FWDZp6CeiT
  499. LL+vn21fWvELBWb8ekwZOCSmT7IpaboKn4h5aUmgl4udA/73iC2zVQkQxbWZb5zu
  500. vEdDk4aOwV5ZBDjecYX01hjjnEOdZHGJlF/H/Xs0hYX6WDG3/r9QCJJ0nfd1/Fk2
  501. zdbZRtAbyRz6ZHiYKnFQ441qRRaEbzunkvTBEwu9iqzlE0s/g49LJL0mKEp7rt/J
  502. 4iS3LZTQbJNx5J0ti8ZJKHhvoWb5RJxNimwKvVHC0XBZKTiLMrhnADmcpjLz53F8
  503. $SF_KEY
  504. sx27yCaeBeKXV0tFOeZmgK664VM9EgesjIX4sVOJ5mA3xBJBOtz9n66LjoIlIM58
  505. dvsAnJt7MUBdclL/RBHEjbUxgGBDcazfWSuJe0sGczhnXMN94ox4MSECgYEAx5cv
  506. cs/2KurjtWPanDGSz71LyGNdL/xQrAud0gi49H0tyYr0XmzNoe2CbZ/T5xGSZB92
  507. PBcz4rnHQ/oujo/qwjNpDD0xVLEU70Uy/XiY5/v2111TFC4clfE/syZPywKAztt3
  508. y2l5z+QdsNigRPDhKw+7CFYaAnYBEISxR6nabT8CgYEAqHrM8fdn2wsCNE6XvkZQ
  509. O7ZANHNIKVnaRqW/8HW7EFAWQrlQTgzFbtR4uNBIqAtPsvwSx8Pk652+OR1VKfSv
  510. ya3dtqY3rY/ErXWyX0nfPQEbYj/oh8LbS6zPw75yIorP3ACIwMw3GRNWIvkdAGTn
  511. BMUgpWHUDLWWpWRrSzNi90ECgYEAkxxzQ6vW5OFGv17/NdswO+BpqCTc/c5646SY
  512. ScRWFxbhFclOvv5xPqYiWYzRkmIYRaYO7tGnU7jdD9SqVjfrsAJWrke4QZVYOdgG
  513. cl9eTLchxLGr15b5SOeNrQ1TCO4qZM3M6Wgv+bRI0h2JW+c0ABpTIBzehOvXcwZq
  514. 6MhgD98CgYEAtOPqc4aoIRUy+1oijpWs+wU7vAc8fe4sBHv5fsv7naHuPqZgyQYY
  515. 32a54xZxlsBw8T5P4BDy40OR7fu+6miUfL+WxUdII4fD3grlIPw6bpNE0bCDykv5
  516. RLq28S11hDrKf/ZetXNuIprfTlhl6ISBy+oWQibhXmFZSxEiXNV6hCQ=
  517. -----END RSA PRIVATE KEY-----
  518. EOF" or abort 'Failed to create user private key to id_rsa'
  519. system 'chmod 600 ~/.ssh/id_rsa' or abort 'Failed to change id_rsa file permission'
  520. end
  521. # Load custom rake scripts
  522. Dir['.rake/*.rake'].each { |r| load r }
  523. # vi: set ts=2 sw=2 expandtab: