Rakefile 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  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 always use Release configuration for MinGW and Android build)
  75. if ENV['PACKAGE_UPLOAD'] || (ENV['CI'] && (ENV['WINDOWS'] || ENV['ANDROID']))
  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. if ENV['XCODE']
  88. # xctool or xcodebuild
  89. xcode_ci
  90. else
  91. # GCC or Clang
  92. makefile_ci
  93. end
  94. end
  95. # Usage: NOT intended to be used manually (if you insist then try: GIT_NAME=... GIT_EMAIL=... GH_TOKEN=... rake ci_site_update)
  96. desc 'Update site documentation to GitHub Pages'
  97. task :ci_site_update do
  98. # Pull or clone
  99. 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'
  100. # Update credits from Readme.txt to about.md
  101. 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'
  102. # Setup doxygen to use minimal theme
  103. 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'
  104. system 'cp doc-Build/_includes/Doxygen/minimal-* Docs' or abort 'Failed to copy minimal-themed template'
  105. release = ENV['RELEASE_TAG'] || 'HEAD'
  106. unless release == 'HEAD'
  107. system "mkdir -p doc-Build/documentation/#{release}" or abort 'Failed to create directory for new document version'
  108. system "ruby -i -pe 'gsub(/HEAD/, %q{#{release}})' Docs/minimal-header.html" or abort 'Failed to update document version in YAML Front Matter block'
  109. append_new_release release, 'doc-Build/_data/urho3d.json' or abort 'Failed to add new release to document data file'
  110. end
  111. # Generate and sync doxygen pages
  112. 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'
  113. # Supply GIT credentials and push site documentation to urho3d/urho3d.github.io.git
  114. 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'
  115. # Automatically give instruction to do packaging when API has changed, unless the instruction is already given in this commit
  116. if ENV['PACKAGE_UPLOAD']
  117. instruction = 'skip'
  118. else
  119. instruction = 'package'
  120. end
  121. # Supply GIT credentials and push API documentation to urho3d/Urho3D.git (the push may not be successful if remote master has already diverged)
  122. 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*'
  123. if system("git commit -q -m 'Travis CI: API documentation update at #{Time.now.utc}.\n[ci #{instruction}]'") && !ENV['PACKAGE_UPLOAD']
  124. bump_soversion 'Source/Engine/.soversion' or abort 'Failed to bump soversion'
  125. 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'
  126. end
  127. 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'
  128. end
  129. # Usage: NOT intended to be used manually (if you insist then try: GIT_NAME=... GIT_EMAIL=... GH_TOKEN=... rake ci_rebase)
  130. desc 'Rebase all CI mirror branches'
  131. task :ci_rebase do
  132. 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'
  133. head = `git rev-parse --short HEAD`
  134. [ 'Android-CI', 'RPI-CI', 'OSX-CI' ].each { |branch| system "git fetch origin #{branch}:#{branch} && git rebase HEAD #{branch} && git push -qf -u origin #{branch} >/dev/null 2>&1 && git checkout -q #{head}" or abort "Failed to rebase #{branch} mirror branch" }
  135. end
  136. # Usage: NOT intended to be used manually (if you insist then try: rake ci_package_upload)
  137. desc 'Make binary package and upload it to a designated central hosting server'
  138. task :ci_package_upload do
  139. if ENV['XCODE']
  140. $configuration = 'Release'
  141. $testing = 0
  142. end
  143. if ENV['ANDROID']
  144. platform_prefix = 'android-'
  145. elsif ENV['WINDOWS']
  146. platform_prefix = 'mingw-'
  147. elsif ENV['IOS']
  148. platform_prefix = 'ios-'
  149. elsif ENV['RPI']
  150. platform_prefix = 'raspi-'
  151. else
  152. platform_prefix = ''
  153. end
  154. # Generate the documentation if necessary
  155. unless ENV['SITE_UPDATE']
  156. system 'echo Generate documentation'
  157. if ENV['XCODE']
  158. xcode_build(ENV['IOS'], "#{platform_prefix}Build/Urho3D.xcodeproj", 'doc', '>/dev/null') or abort 'Failed to generate documentation'
  159. else
  160. system "cd #{platform_prefix}Build && make -j$NUMJOBS doc >/dev/null" or abort 'Failed to generate documentation'
  161. end
  162. end
  163. # Make the package
  164. if ENV['IOS']
  165. # 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
  166. if ENV['CI_START_TIME'] then
  167. elapsed_time = (Time.now - Time.parse(ENV['CI_START_TIME'])) / 60
  168. puts "\niOS checkpoint reached, elapsed time: #{elapsed_time}\n\n"
  169. end
  170. if !ENV['CI_START_TIME'] || elapsed_time < 15 # minutes
  171. # 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)
  172. system 'echo Rebuild Urho3D library as Mach-O universal binary'
  173. xcode_build(0, "#{platform_prefix}Build/Urho3D.xcodeproj", 'Urho3D_universal') or abort 'Failed to build Mach-O universal binary'
  174. end
  175. # There is a bug in CMake/CPack that causes the 'package' target failed to build for IOS platform, workaround by calling cpack directly
  176. system "cd #{platform_prefix}Build && cpack -G TGZ 2>/dev/null" or abort 'Failed to make binary package'
  177. elsif ENV['XCODE']
  178. xcode_build(ENV['IOS'], "#{platform_prefix}Build/Urho3D.xcodeproj", 'package') or abort 'Failed to make binary package'
  179. else
  180. if ENV['ANDROID'] && !ENV['NO_SDK_SYSIMG']
  181. 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'
  182. end
  183. system "cd #{platform_prefix}Build && make package" or abort 'Failed to make binary package'
  184. end
  185. # Determine the upload location
  186. setup_digital_keys
  187. if !ENV['RELEASE_TAG']
  188. upload_dir = "/home/frs/project/#{ENV['TRAVIS_REPO_SLUG']}/Snapshots"
  189. if ENV['SITE_UPDATE']
  190. # Download source packages from GitHub
  191. 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'
  192. # Only keep the snapshots from the last 30 revisions
  193. system "for v in $(sftp [email protected] <<EOF |tr ' ' '\n' |grep Urho3D- |cut -d '-' -f1,2 |uniq |tail -n +31
  194. cd #{upload_dir}
  195. ls -1r
  196. bye
  197. EOF
  198. ); do echo rm #{upload_dir}/${v}*; done |sftp -b - [email protected]" or abort 'Failed to housekeep snapshots'
  199. end
  200. else
  201. upload_dir = "/home/frs/project/#{ENV['TRAVIS_REPO_SLUG']}/#{ENV['RELEASE_TAG']}"
  202. if ENV['SITE_UPDATE']
  203. # Download source packages from GitHub
  204. 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'
  205. end
  206. # 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
  207. system "sftp [email protected] <<EOF >/dev/null 2>&1
  208. mkdir #{upload_dir}
  209. bye
  210. EOF" or abort 'Failed to create release directory remotely'
  211. end
  212. if ENV['SITE_UPDATE']
  213. # Upload the source package
  214. system "scp Urho3D-* [email protected]:#{upload_dir}" or abort 'Failed to upload source package'
  215. # Sync readme and license files, just in case they are updated in the repo
  216. 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'
  217. 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'
  218. end
  219. # Upload the package
  220. system "scp #{platform_prefix}Build/Urho3D-* [email protected]:#{upload_dir}" or abort 'Failed to upload binary package'
  221. end
  222. def scaffolding(dir, project = 'Scaffolding', target = 'Main')
  223. build_script = <<EOF
  224. # Set project name
  225. project (#{project})
  226. # Set minimum version
  227. cmake_minimum_required (VERSION 2.8.6)
  228. if (COMMAND cmake_policy)
  229. cmake_policy (SET CMP0003 NEW)
  230. if (CMAKE_VERSION VERSION_GREATER 2.8.12 OR CMAKE_VERSION VERSION_EQUAL 2.8.12)
  231. cmake_policy (SET CMP0022 NEW) # INTERFACE_LINK_LIBRARIES defines the link interface
  232. endif ()
  233. if (CMAKE_VERSION VERSION_GREATER 3.0.0 OR CMAKE_VERSION VERSION_EQUAL 3.0.0)
  234. cmake_policy (SET CMP0026 OLD) # Disallow use of the LOCATION target property - therefore we set to OLD as we still need it
  235. cmake_policy (SET CMP0042 NEW) # MACOSX_RPATH is enabled by default
  236. endif ()
  237. endif ()
  238. # Set CMake modules search path
  239. set (CMAKE_MODULE_PATH
  240. $ENV{URHO3D_HOME}/Source/CMake/Modules
  241. $ENV{CMAKE_PREFIX_PATH}/share/Urho3D/CMake/Modules
  242. ${CMAKE_INSTALL_PREFIX}/share/Urho3D/CMake/Modules
  243. CACHE PATH \"Path to Urho3D-specific CMake modules\")
  244. # Include Urho3D CMake common module
  245. include (Urho3D-CMake-common)
  246. # Find Urho3D library
  247. find_package (Urho3D REQUIRED)
  248. include_directories (${URHO3D_INCLUDE_DIRS})
  249. # Define target name
  250. set (TARGET_NAME #{target})
  251. # Define source files
  252. define_source_files ()
  253. # Setup target with resource copying
  254. setup_main_executable ()
  255. # Setup test cases
  256. if (URHO3D_ANGELSCRIPT)
  257. add_test (NAME ExternalLibAS COMMAND ${TARGET_NAME} Data/Scripts/12_PhysicsStressTest.as -w -timeout ${URHO3D_TEST_TIME_OUT})
  258. endif ()
  259. if (URHO3D_LUA)
  260. add_test (NAME ExternalLibLua COMMAND ${TARGET_NAME} Data/LuaScripts/12_PhysicsStressTest.lua -w -timeout ${URHO3D_TEST_TIME_OUT})
  261. endif ()
  262. EOF
  263. # TODO: Rewrite in pure Ruby when it supports symlink creation on Windows platform
  264. if ENV['OS']
  265. system("@echo off && (for %d in (Source,Bin) do mkdir #{dir}\\%d) && copy Source\\Tools\\Urho3DPlayer\\Urho3DPlayer.* #{dir}\\Source >nul && (for %f in (*.bat) 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'
  266. else
  267. system("bash -c \"mkdir -p #{dir}/{Source,Bin} && cp Source/Tools/Urho3DPlayer/Urho3DPlayer.* #{dir}/Source && for f in {.,}*.sh; 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'
  268. end
  269. end
  270. def makefile_ci
  271. if ENV['WINDOWS']
  272. # 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.
  273. # Temporarily workaround the problem by downloading the missing header from Ubuntu 14.04 LTS source package.
  274. if ENV['URHO3D_OPENGL'] && ENV['CI'] then
  275. 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'
  276. end
  277. # 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.
  278. jit = ''
  279. amalg = ''
  280. # Lua on MinGW build requires tolua++ tool to be built natively first
  281. 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'
  282. system "cd Build/ThirdParty/toluapp/src/bin && make -j$NUMJOBS" or abort 'Failed to build tolua++ tool'
  283. ENV['SKIP_NATIVE'] = '1'
  284. elsif ENV['ANDROID'] && ENV['ABI'] == 'arm64-v8a'
  285. # The upstream LuaJIT library does not support this Android ABI at the moment, fallback to use Lua library instead
  286. jit = ''
  287. amalg = ''
  288. else
  289. jit = 'JIT'
  290. amalg = '-DURHO3D_LUAJIT_AMALG=1'
  291. end
  292. 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'
  293. if ENV['ANDROID']
  294. if ENV['AVD']
  295. android_prepare_device ENV['API'], ENV['ABI'], ENV['AVD'] or abort 'Failed to prepare Android (virtual) device for test run'
  296. end
  297. # LuaJIT on Android build requires tolua++ and buildvm-android tools to be built natively first
  298. system "cd Build/ThirdParty/toluapp/src/bin && make -j$NUMJOBS" or abort 'Failed to build tolua++ tool'
  299. if !jit.empty?
  300. system "cd Build/ThirdParty/Lua#{jit}/generated/buildvm-android-#{ENV['ABI']} && make -j$NUMJOBS" or abort 'Failed to build buildvm-android tool'
  301. end
  302. # Reconfigure Android build one more time now that we have the tools built
  303. ENV['SKIP_NATIVE'] = '1'
  304. system './cmake_gcc.sh' or abort 'Failed to reconfigure Urho3D library for Android build'
  305. platform_prefix = 'android-'
  306. elsif ENV['RPI']
  307. # LuaJIT on Raspberry Pi build requires tolua++ and buildvm-raspi tools to be built natively first
  308. system "cd Build/ThirdParty/toluapp/src/bin && make -j$NUMJOBS" or abort 'Failed to build tolua++ tool'
  309. system "cd Build/ThirdParty/LuaJIT/generated/buildvm-raspi && make -j$NUMJOBS" or abort 'Failed to build buildvm-raspi tool'
  310. # Reconfigure Raspberry Pi build one more time now that we have the tools built
  311. ENV['SKIP_NATIVE'] = '1'
  312. system './cmake_gcc.sh' or abort 'Failed to reconfigure Urho3D library for Raspberry Pi build'
  313. platform_prefix = 'raspi-'
  314. elsif ENV['WINDOWS']
  315. platform_prefix = 'mingw-'
  316. else
  317. platform_prefix = ''
  318. end
  319. if $testing == 1
  320. test = '&& make test'
  321. else
  322. test = ''
  323. end
  324. system "cd #{platform_prefix}Build && make -j$NUMJOBS #{test}" or abort 'Failed to build or test Urho3D library'
  325. # Create a new project on the fly that uses newly built Urho3D library
  326. scaffolding "#{platform_prefix}Build/generated/externallib"
  327. 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'
  328. # Make, deploy, and test run Android APK in an Android (virtual) device
  329. if ENV['AVD']
  330. 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'
  331. if android_wait_for_device ENV['CI'] ? 1 : 10 # minutes
  332. system "cd #{platform_prefix}Build && ant -Dadb.device.arg='-s #{$specific_device}' installd" or abort 'Failed to deploy Urho3D Samples APK'
  333. android_test_run or abort 'Failed to test run Urho3D Samples APK'
  334. else
  335. puts 'Skipped test running Urho3D Samples APK as emulator failed to start in time'
  336. end
  337. end
  338. end
  339. def android_find_device api = nil, abi = nil
  340. # Return the previously found matching device or if not found yet then try to find the matching device now
  341. return $specific_device if $specific_device
  342. wait = api ? '' : 'wait-for-device'
  343. $specific_api = api.to_s if api
  344. $specific_abi = abi.to_s if abi
  345. for i in `adb #{wait} devices |tail -n +2`.split "\n"
  346. device = i.split.first
  347. 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
  348. return $specific_device = device
  349. end
  350. end
  351. nil
  352. end
  353. def android_prepare_device api, abi = 'armeabi-v7a', name = 'test'
  354. system 'if ! ps |grep -cq adb; then adb start-server; fi'
  355. if !android_find_device api, abi
  356. # Don't have any matching (virtual) device attached, try to attach the named device (create the named device as AVD if necessary)
  357. if !system "android list avd |grep -cq 'Name: #{name}$'"
  358. system "echo 'no' |android create avd -n #{name} -t android-#{api} --abi #{abi}" or abort "Failed to create '#{name}' Android virtual device"
  359. end
  360. 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 &"
  361. end
  362. return 0
  363. end
  364. def android_wait_for_device retries = -1, retry_interval = 10, package = 'android.process.acore' # Waiting for HOME by default
  365. # 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)
  366. str = "\nWaiting for device..."
  367. thread = Thread.new { android_find_device }; sleep 0.5
  368. process_ready = false
  369. retries = retries * 60 / retry_interval unless retries == -1
  370. until retries == 0
  371. if thread.status == false
  372. thread.join
  373. break if process_ready
  374. 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
  375. next
  376. end
  377. 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
  378. sleep retry_interval
  379. retries -= 1 if retries > 0
  380. end
  381. puts "\n\n" if str == '.'; $stdout.flush
  382. return retries == 0 ? nil : 0
  383. end
  384. def android_test_run parameter = '--es pickedLibrary Urho3DPlayer', intent = '.SampleLauncher', package = 'com.github.urho3d', success_indicator = 'Added resource path /apk/CoreData/', payload = 'sleep 30'
  385. # The device should have been found at this point
  386. return nil unless $specific_device
  387. # Capture adb's stdout and interpret it because adb neither uses stderr nor returns proper exit code on error
  388. begin
  389. IO.popen("adb -s #{$specific_device} shell <<EOF
  390. # Try to unlock the device just in case it is locked
  391. input keyevent 82; input keyevent 4
  392. # Clear the log
  393. logcat -c
  394. # Start the app
  395. am start -a android.intent.action.MAIN -n #{package}/#{intent} #{parameter}
  396. # Wait until the process is running
  397. until ps |grep -c #{package} 1>/dev/null; do sleep 1; done
  398. # Execute the payload
  399. #{payload}
  400. # Exit and stop the app
  401. input keyevent 4 && am force-stop #{package}
  402. # Dump the log
  403. logcat -d
  404. # Bye bye
  405. exit
  406. ##
  407. 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 }
  408. # Result of the test run is determined based on the presence of the success indicator string in the log
  409. system "adb -s #{$specific_device} logcat -d |grep -cq '#{success_indicator}'"
  410. rescue
  411. nil
  412. end
  413. end
  414. def xcode_ci
  415. if ENV['IOS']
  416. # IOS platform does not support LuaJIT
  417. jit = ''
  418. amalg = ''
  419. platform_prefix = 'ios-'
  420. deployment_target = "-DIPHONEOS_DEPLOYMENT_TARGET=#{ENV['DEPLOYMENT_TARGET']}"
  421. # Lua on IOS build requires tolua++ tool to be built natively first
  422. 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'
  423. xcode_build(0, 'Build/Urho3D.xcodeproj', 'tolua++') or abort 'Failed to build tolua++ tool'
  424. else
  425. jit = 'JIT'
  426. amalg = '-DURHO3D_LUAJIT_AMALG=1'
  427. platform_prefix = ''
  428. deployment_target = "-DCMAKE_OSX_DEPLOYMENT_TARGET=#{ENV['DEPLOYMENT_TARGET']}"
  429. end
  430. 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'
  431. xcode_build(ENV['IOS'], "#{platform_prefix}Build/Urho3D.xcodeproj") or abort 'Failed to build or test Urho3D library'
  432. # Create a new project on the fly that uses newly built Urho3D library
  433. scaffolding "#{platform_prefix}Build/generated/externallib"
  434. 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'
  435. 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'
  436. end
  437. def xcode_build(ios, project, target = 'ALL_BUILD', extras = '')
  438. sdk = ios.to_i == 1 ? '-sdk iphonesimulator' : ''
  439. # Use xcpretty to filter output from xcodebuild when building
  440. system "xcodebuild -project #{project} -target #{target} -configuration #{$configuration} #{sdk} |xcpretty -c #{extras} && exit ${PIPESTATUS[0]}" or return nil
  441. if $testing == 1 && target == 'ALL_BUILD' # Disable testing for other targets such as 'doc', 'package', etc
  442. # Use vanila xcodebuild when testing as its output is instantaneous (ensure Travis-CI does not kill the process during testing)
  443. system "xcodebuild -project #{project} -target RUN_TESTS -configuration #{$configuration} #{sdk} #{extras}" or return nil
  444. end
  445. return 0
  446. end
  447. def append_new_release release, filename
  448. begin
  449. urho3d_hash = JSON.parse File.read filename
  450. unless urho3d_hash['releases'].last == release
  451. urho3d_hash['releases'] << release
  452. end
  453. File.open filename, 'w' do |file|
  454. file.puts urho3d_hash.to_json
  455. end
  456. return 0
  457. rescue
  458. nil
  459. end
  460. end
  461. def bump_soversion filename
  462. begin
  463. version = File.read(filename).split '.'
  464. bump_version version, 2
  465. File.open filename, 'w' do |file|
  466. file.puts version.join '.'
  467. end
  468. return 0
  469. rescue
  470. nil
  471. end
  472. end
  473. def bump_version version, index
  474. if index > 0 && version[index].to_i == 255
  475. version[index] = 0
  476. bump_version version, index - 1
  477. else
  478. version[index] = version[index].to_i + 1
  479. end
  480. end
  481. def setup_digital_keys
  482. system 'mkdir -p ~/.ssh && chmod 700 ~/.ssh' or abort 'Failed to create ~/.ssh directory'
  483. system "cat <<EOF >>~/.ssh/known_hosts
  484. frs.sourceforge.net,216.34.181.57 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2uifHZbNexw6cXbyg1JnzDitL5VhYs0E65Hk/tLAPmcmm5GuiGeUoI/B0eUSNFsbqzwgwrttjnzKMKiGLN5CWVmlN1IXGGAfLYsQwK6wAu7kYFzkqP4jcwc5Jr9UPRpJdYIK733tSEmzab4qc5Oq8izKQKIaxXNe7FgmL15HjSpatFt9w/ot/CHS78FUAr3j3RwekHCm/jhPeqhlMAgC+jUgNJbFt3DlhDaRMa0NYamVzmX8D47rtmBbEDU3ld6AezWBPUR5Lh7ODOwlfVI58NAf/aYNlmvl2TZiauBCTa7OPYSyXJnIPbQXg6YQlDknNCr0K769EjeIlAfY87Z4tw==
  485. EOF" or abort 'Failed to append frs.sourceforge.net server public key to known_hosts'
  486. # 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.
  487. system "cat <<EOF >~/.ssh/id_rsa
  488. -----BEGIN RSA PRIVATE KEY-----
  489. MIIEpQIBAAKCAQEAnZGzFEypdXKY3KDT0Q3NLY4Bv74yKgJ4LIgbXothx8w4CfM0
  490. VeWBL/AE2iRISEWGB07LruM9y+U/wt58WlCVu001GuJuvXwWenlljsvH8qQlErYi
  491. oXlCwAeVVeanILGL8CPS7QlyzOwwnVF6NdcmfDJjTthBVFbvHrWGo5if86zcZyMR
  492. 2BB5QVEr5fU0yOPFp0+2p7J3cA6HQSKwjUiDtJ+lM62UQp7InCCT3qeh5KYHQcYb
  493. KVJTyj5iycVuBujHDwNAivLq82ojG7LcKjP+Ia8fblardCOQyFk6pSDM79NJJ2Dg
  494. 3ZbYIJeUmqSqFhRW/13Bro7Z1aNGrdh/XZkkHwIDAQABAoIBACHcBFJxYtzVIloO
  495. yVWcFKIcaO3OLjNu0monWVJIu1tW3BfvRijLJ6aoejJyJ4I4RmPdn9FWDZp6CeiT
  496. LL+vn21fWvELBWb8ekwZOCSmT7IpaboKn4h5aUmgl4udA/73iC2zVQkQxbWZb5zu
  497. vEdDk4aOwV5ZBDjecYX01hjjnEOdZHGJlF/H/Xs0hYX6WDG3/r9QCJJ0nfd1/Fk2
  498. zdbZRtAbyRz6ZHiYKnFQ441qRRaEbzunkvTBEwu9iqzlE0s/g49LJL0mKEp7rt/J
  499. 4iS3LZTQbJNx5J0ti8ZJKHhvoWb5RJxNimwKvVHC0XBZKTiLMrhnADmcpjLz53F8
  500. $SF_KEY
  501. sx27yCaeBeKXV0tFOeZmgK664VM9EgesjIX4sVOJ5mA3xBJBOtz9n66LjoIlIM58
  502. dvsAnJt7MUBdclL/RBHEjbUxgGBDcazfWSuJe0sGczhnXMN94ox4MSECgYEAx5cv
  503. cs/2KurjtWPanDGSz71LyGNdL/xQrAud0gi49H0tyYr0XmzNoe2CbZ/T5xGSZB92
  504. PBcz4rnHQ/oujo/qwjNpDD0xVLEU70Uy/XiY5/v2111TFC4clfE/syZPywKAztt3
  505. y2l5z+QdsNigRPDhKw+7CFYaAnYBEISxR6nabT8CgYEAqHrM8fdn2wsCNE6XvkZQ
  506. O7ZANHNIKVnaRqW/8HW7EFAWQrlQTgzFbtR4uNBIqAtPsvwSx8Pk652+OR1VKfSv
  507. ya3dtqY3rY/ErXWyX0nfPQEbYj/oh8LbS6zPw75yIorP3ACIwMw3GRNWIvkdAGTn
  508. BMUgpWHUDLWWpWRrSzNi90ECgYEAkxxzQ6vW5OFGv17/NdswO+BpqCTc/c5646SY
  509. ScRWFxbhFclOvv5xPqYiWYzRkmIYRaYO7tGnU7jdD9SqVjfrsAJWrke4QZVYOdgG
  510. cl9eTLchxLGr15b5SOeNrQ1TCO4qZM3M6Wgv+bRI0h2JW+c0ABpTIBzehOvXcwZq
  511. 6MhgD98CgYEAtOPqc4aoIRUy+1oijpWs+wU7vAc8fe4sBHv5fsv7naHuPqZgyQYY
  512. 32a54xZxlsBw8T5P4BDy40OR7fu+6miUfL+WxUdII4fD3grlIPw6bpNE0bCDykv5
  513. RLq28S11hDrKf/ZetXNuIprfTlhl6ISBy+oWQibhXmFZSxEiXNV6hCQ=
  514. -----END RSA PRIVATE KEY-----
  515. EOF" or abort 'Failed to create user private key to id_rsa'
  516. system 'chmod 600 ~/.ssh/id_rsa' or abort 'Failed to change id_rsa file permission'
  517. end
  518. # vi: set ts=2 sw=2 expandtab: