Jakefile 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. // patch in our local node_modules
  2. process.env.NODE_PATH = __dirname + "/Build/node_modules";
  3. require('module').Module._initPaths();
  4. var fs = require('fs-extra');
  5. var path = require('path');
  6. var os = require('os');
  7. var host = os.platform();
  8. var jakeRoot = __dirname;
  9. var jenkinsBuild = process.env.ATOMIC_JENKINS_BUILD == 1
  10. var generateJSDoc = true;
  11. var artifactsFolder = jakeRoot + "/Artifacts";
  12. // cmake
  13. var cmakeDevBuild = false;
  14. var includeDeployments = jenkinsBuild;
  15. var deployments = {
  16. osx: true,
  17. android: true,
  18. windows: true,
  19. ios: true,
  20. web: true
  21. }
  22. // build folder
  23. var windowsBuildFolder = artifactsFolder + "/Windows_Build";
  24. var macOSXBuildFolder = artifactsFolder + "/MacOSX_Build";
  25. var androidBuildFolder = artifactsFolder + "/Android_Build";
  26. var iosBuildFolder = artifactsFolder + "/IOS_Build";
  27. var iosDeployBuildFolder = artifactsFolder + "/ios-deploy";
  28. var webBuildFolder = artifactsFolder + "/Web_Build";
  29. var linuxBuildFolder = artifactsFolder + "/Linux_Build";
  30. var jsDocFolder = artifactsFolder + "/JSDoc";
  31. // binaries
  32. if (host == "darwin") {
  33. var atomicToolBinary = macOSXBuildFolder + "/Source/AtomicTool/Release/AtomicTool"
  34. var atomicEditorBinary = macOSXBuildFolder + "/Source/AtomicEditor/Release/AtomicEditor.app/Contents/MacOS/AtomicEditor"
  35. var atomicPlayerBinary = macOSXBuildFolder + "/Source/AtomicPlayer/Application/Release/AtomicPlayer.app/Contents/MacOS/AtomicPlayer"
  36. } else if (host == "win32") {
  37. var atomicToolBinary = windowsBuildFolder + "/Source/AtomicTool/Release/AtomicTool.exe"
  38. var atomicEditorBinary = windowsBuildFolder + "/Source/AtomicEditor/Release/AtomicEditor.exe"
  39. var atomicPlayerBinary = windowsBuildFolder + "/Source/AtomicPlayer/Application/Release/AtomicPlayer.exe"
  40. }
  41. // source files
  42. var androidPlayerBinary = androidBuildFolder + "/Source/AtomicPlayer/Application/libAtomicPlayer.so";
  43. var iosPlayerBinary = iosBuildFolder + "/Source/AtomicPlayer/Application/Release-iphoneos/AtomicPlayer.app/AtomicPlayer"
  44. var webPlayerBinary = webBuildFolder + "/Source/AtomicPlayer/Application/AtomicPlayer.js"
  45. var webPlayerMemFile = webBuildFolder + "/Source/AtomicPlayer/Application/AtomicPlayer.html.mem"
  46. var allBuildFolders = [
  47. windowsBuildFolder,
  48. macOSXBuildFolder,
  49. androidBuildFolder,
  50. iosBuildFolder,
  51. iosDeployBuildFolder,
  52. webBuildFolder,
  53. linuxBuildFolder,
  54. jsDocFolder
  55. ];
  56. // packaging
  57. var platformBinariesFolder = artifactsFolder + "/Platform_Binaries";
  58. var windowsPackageFolder = artifactsFolder + "/Windows_Package";
  59. var macOSXPackageFolder = artifactsFolder + "/MacOSX_Package";
  60. var distFolder = artifactsFolder + "/Dist";
  61. var allPackageFolders = [
  62. windowsPackageFolder,
  63. macOSXPackageFolder,
  64. platformBinariesFolder,
  65. distFolder
  66. ];
  67. function getAtomicDevBuildDefine() {
  68. return "-DATOMIC_DEV_BUILD=" + (cmakeDevBuild ? "1" : "0");
  69. }
  70. function testRemoveDir(path) {
  71. if (fs.existsSync(path)) {
  72. jake.rmRf(path);
  73. }
  74. if (fs.existsSync(path)) {
  75. throw "Unable to remove path: " + path;
  76. }
  77. }
  78. namespace('clean', function() {
  79. task('all', {
  80. async: true
  81. }, function() {
  82. for (var i in allBuildFolders) {
  83. testRemoveDir(allBuildFolders[i]);
  84. }
  85. for (var i in allPackageFolders) {
  86. testRemoveDir(allPackageFolders[i]);
  87. }
  88. complete();
  89. });
  90. });
  91. namespace('build', function() {
  92. task('macosx_atomictool', {
  93. async: true
  94. }, function() {
  95. if (!fs.existsSync(macOSXBuildFolder)) {
  96. jake.mkdirP(macOSXBuildFolder);
  97. }
  98. var cmds = [
  99. 'cmake ../../ -G Xcode ' + getAtomicDevBuildDefine(),
  100. 'xcodebuild -target AtomicTool -configuration Release'
  101. ]
  102. process.chdir(macOSXBuildFolder);
  103. jake.exec(cmds, function() {
  104. fs.copySync(atomicToolBinary, platformBinariesFolder + "/MacOSX/" + path.basename(atomicToolBinary));
  105. console.log("Built MacOSX AtomicTool");
  106. complete();
  107. }, {
  108. printStdout: true
  109. });
  110. }); // end build:macosx_atomictool
  111. var deps = [];
  112. if (includeDeployments) {
  113. if (host == 'darwin') {
  114. deps = ['macosx_atomictool'];
  115. if (deployments.ios)
  116. deps.push("build:ios");
  117. if (deployments.android)
  118. deps.push("build:android");
  119. if (deployments.web)
  120. deps.push("build:web");
  121. }
  122. }
  123. task('install_deployments', {
  124. async: true
  125. }, function() {
  126. console.log("Installing Deployments");
  127. // deployment root for local dev builds
  128. var deployRoot = jakeRoot + "/Data/AtomicEditor/Deployment";
  129. if (host == "darwin") {
  130. if (deployments.osx)
  131. fs.copySync(platformBinariesFolder + "/MacOSX/AtomicPlayer", deployRoot + "/MacOS/AtomicPlayer.app/Contents/MacOS/AtomicPlayer");
  132. if (deployments.android)
  133. fs.copySync(platformBinariesFolder + "/Android/libAtomicPlayer.so", deployRoot + "/Android/libs/armeabi-v7a/libAtomicPlayer.so");
  134. if (deployments.ios) {
  135. fs.copySync(artifactsFolder + "/ios-deploy/ios-deploy/ios-deploy", deployRoot + "/IOS/ios-deploy/ios-deploy");
  136. fs.copySync(platformBinariesFolder + "/IOS/AtomicPlayer", deployRoot + "/IOS/AtomicPlayer.app/AtomicPlayer");
  137. }
  138. if (deployments.web) {
  139. fs.copySync(platformBinariesFolder + "/Web/AtomicPlayer.js", deployRoot + "/Web/AtomicPlayer.js");
  140. fs.copySync(platformBinariesFolder + "/Web/AtomicPlayer.html.mem", deployRoot + "/Web/AtomicPlayer.html.mem");
  141. }
  142. } else if (host == "win32") {
  143. if (deployments.windows) {
  144. fs.copySync(platformBinariesFolder + "/Win32/AtomicPlayer.exe", deployRoot + "/Windows/x86/AtomicPlayer.exe");
  145. }
  146. }
  147. complete();
  148. });
  149. task('ios_deploy', {
  150. async: true
  151. }, function() {
  152. if (!fs.existsSync(iosDeployBuildFolder)) {
  153. jake.mkdirP(iosDeployBuildFolder);
  154. }
  155. process.chdir(iosDeployBuildFolder);
  156. if (!fs.existsSync(iosDeployBuildFolder + "/ios-deploy")) {
  157. jake.exec("git clone https://github.com/AtomicGameEngine/ios-deploy && cd ios-deploy && make ios-deploy");
  158. }
  159. complete();
  160. });
  161. task('macosx', deps, {
  162. async: true
  163. }, function() {
  164. if (!fs.existsSync(macOSXBuildFolder)) {
  165. jake.mkdirP(macOSXBuildFolder);
  166. }
  167. var cmds = [
  168. 'cmake ../../ -G Xcode ' + getAtomicDevBuildDefine(),
  169. 'xcodebuild -configuration Release'
  170. ]
  171. process.chdir(macOSXBuildFolder);
  172. jake.exec(cmds, function() {
  173. fs.copySync(atomicEditorBinary, platformBinariesFolder + "/MacOSX/" + path.basename(atomicEditorBinary));
  174. fs.copySync(atomicPlayerBinary, platformBinariesFolder + "/MacOSX/" + path.basename(atomicPlayerBinary));
  175. if (includeDeployments) {
  176. jake.Task['build:install_deployments'].invoke();
  177. }
  178. console.log("Built MacOSX");
  179. complete();
  180. }, {
  181. printStdout: true
  182. });
  183. }); // end build:macosx
  184. task('windows', {
  185. async: true
  186. }, function() {
  187. if (!fs.existsSync(windowsBuildFolder)) {
  188. jake.mkdirP(windowsBuildFolder);
  189. }
  190. process.chdir(windowsBuildFolder);
  191. jake.exec(jakeRoot + "/Build/Windows/Compile.bat", function() {
  192. fs.copySync(atomicEditorBinary, platformBinariesFolder + "/Win32/" + path.basename(atomicEditorBinary));
  193. fs.copySync(atomicPlayerBinary, platformBinariesFolder + "/Win32/" + path.basename(atomicPlayerBinary));
  194. if (includeDeployments) {
  195. jake.Task['build:install_deployments'].invoke();
  196. }
  197. complete();
  198. }, {
  199. printStdout: true
  200. });
  201. });
  202. task('android', ['macosx_atomictool'], {
  203. async: true
  204. }, function() {
  205. if (!fs.existsSync(androidBuildFolder)) {
  206. jake.mkdirP(androidBuildFolder);
  207. }
  208. process.chdir(androidBuildFolder);
  209. var cmds = [
  210. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/Atomic/ ANDROID",
  211. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/AtomicPlayer/ ANDROID",
  212. "cmake -DCMAKE_TOOLCHAIN_FILE=" + jakeRoot + "/CMake/Toolchains/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ../../",
  213. "make -j4"
  214. ]
  215. jake.exec(cmds, function() {
  216. fs.copySync(androidPlayerBinary, platformBinariesFolder + "/Android/" + path.basename(androidPlayerBinary));
  217. console.log("Built Android Player");
  218. complete();
  219. }, {
  220. printStdout: true
  221. });
  222. });
  223. task('ios', ['macosx_atomictool', 'ios_deploy'], {
  224. async: true
  225. }, function() {
  226. if (!fs.existsSync(iosBuildFolder)) {
  227. jake.mkdirP(iosBuildFolder);
  228. }
  229. process.chdir(iosBuildFolder);
  230. var cmds = [
  231. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/Atomic/ IOS",
  232. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/AtomicPlayer/ IOS",
  233. "cmake -DIOS=1 -G Xcode ../../"
  234. ]
  235. if (jenkinsBuild) {
  236. cmds.push("security -v list-keychains -d system -s /Users/jenkins/Library/Keychains/codesign.keychain");
  237. cmds.push("security -v unlock-keychain /Users/jenkins/Library/Keychains/codesign.keychain");
  238. }
  239. cmds.push("xcodebuild -configuration Release");
  240. jake.exec(cmds, function() {
  241. fs.copySync(iosPlayerBinary, platformBinariesFolder + "/IOS/" + path.basename(iosPlayerBinary));
  242. console.log("Built iOS Player");
  243. complete();
  244. }, {
  245. printStdout: true
  246. });
  247. });
  248. task('web', ['macosx_atomictool'], {
  249. async: true
  250. }, function() {
  251. if (!fs.existsSync(webBuildFolder)) {
  252. jake.mkdirP(webBuildFolder);
  253. }
  254. process.chdir(webBuildFolder);
  255. var cmds = [
  256. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/Atomic/ WEB",
  257. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/AtomicPlayer/ WEB",
  258. "cmake -DEMSCRIPTEN=1 -DATOMIC_BUILD_2D=1 -DCMAKE_TOOLCHAIN_FILE=" + jakeRoot + "/CMake/Toolchains/emscripten.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ../../",
  259. "make -j4",
  260. "cd ./Source/AtomicPlayer/Application && mv ./AtomicPlayer ./AtomicPlayer.bc && " +
  261. // -s ERROR_ON_UNDEFINED_SYMBOLS=1 (disabled for pthread errors currently on incoming)
  262. "emcc -O3 -s USE_PTHREADS=0 -s ASM_JS=1 -s VERBOSE=0 -s USE_SDL=2 -s TOTAL_MEMORY=134217728 -s AGGRESSIVE_VARIABLE_ELIMINATION=1 -s NO_EXIT_RUNTIME=1 ./AtomicPlayer.bc -o ./AtomicPlayer.html"
  263. ]
  264. jake.exec(cmds, function() {
  265. fs.copySync(webPlayerBinary, platformBinariesFolder + "/Web/" + path.basename(webPlayerBinary));
  266. fs.copySync(webPlayerMemFile, platformBinariesFolder + "/Web/" + path.basename(webPlayerMemFile));
  267. console.log("Built Web Player");
  268. complete();
  269. }, {
  270. printStdout: true
  271. });
  272. });
  273. }); // end build namespace
  274. namespace('package', function() {
  275. task('genjsdocs', {
  276. async: true
  277. }, function() {
  278. if (!jenkinsBuild || !generateJSDoc) {
  279. complete();
  280. return;
  281. }
  282. console.log("Generating JSDocs");
  283. fs.copySync(jakeRoot + "/Docs/Readme.md", jsDocFolder + "/Readme.md");
  284. fs.copySync(jakeRoot + "/Docs/jsdoc.conf", jsDocFolder + "/jsdoc.conf");
  285. cmds = ["cd " + jsDocFolder + " && npm install git+https://github.com/jsdoc3/jsdoc",
  286. "cd " + jsDocFolder + " && git clone https://github.com/AtomicGameEngine/jaguarjs-jsdoc && cd jaguarjs-jsdoc && git checkout atomic_master",
  287. "cd " + jsDocFolder + " && ./node_modules/.bin/jsdoc ./Atomic.js -t ./jaguarjs-jsdoc/ -c ./jsdoc.conf Readme.md",
  288. ];
  289. jake.exec(cmds, function() {
  290. complete();
  291. }, {
  292. printStdout: true
  293. });
  294. });
  295. task('macosx', ['clean:all', 'build:macosx', 'package:genjsdocs'], function() {
  296. if (!fs.existsSync(distFolder)) {
  297. jake.mkdirP(distFolder);
  298. }
  299. jake.mkdirP(macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/");
  300. var editorAppSourceFolder = macOSXBuildFolder + "/Source/AtomicEditor/Release/AtomicEditor.app";
  301. fs.copySync(editorAppSourceFolder, macOSXPackageFolder + "/AtomicEditor.app");
  302. // copy resources
  303. fs.copySync(jakeRoot + "/Resources/CoreData", macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/CoreData");
  304. fs.copySync(jakeRoot + "/Resources/EditorData", macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/EditorData");
  305. fs.copySync(jakeRoot + "/Resources/PlayerData", macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/PlayerData");
  306. var toolDataDir = macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/ToolData/";
  307. fs.copySync(jakeRoot + "/Data/AtomicEditor/", toolDataDir);
  308. if (jenkinsBuild) {
  309. console.log("Exporting AtomicExamples Repo (master) & Generating Dist");
  310. if (generateJSDoc) {
  311. fs.copySync(jsDocFolder + "/out", toolDataDir + "Docs/JSDocs");
  312. }
  313. cmds = ["git clone https://github.com/AtomicGameEngine/AtomicExamples " + toolDataDir + "AtomicExamples && rm -rf " + toolDataDir + "AtomicExamples/.git",
  314. "cd " + macOSXPackageFolder + " && zip -r -X " + distFolder + "/AtomicEditor_MacOSX.zip ./AtomicEditor.app"
  315. ];
  316. jake.exec(cmds, function() {});
  317. }
  318. });
  319. task('windows', ['clean:all', 'build:windows'], function() {
  320. if (!fs.existsSync(distFolder)) {
  321. jake.mkdirP(distFolder);
  322. }
  323. console.log("Packaging Windows Editor");
  324. jake.mkdirP(windowsPackageFolder + "/Resources");
  325. fs.copySync(windowsBuildFolder + "/Source/AtomicEditor/Release/AtomicEditor.exe", windowsPackageFolder + "/AtomicEditor.exe")
  326. // 32 bit build for packaging!
  327. fs.copySync(jakeRoot + "/Build/Windows/Binaries/x86/D3DCompiler_47.dll", windowsPackageFolder + "/D3DCompiler_47.dll")
  328. // copy resources
  329. fs.copySync(jakeRoot + "/Resources/CoreData", windowsPackageFolder + "/Resources/CoreData");
  330. fs.copySync(jakeRoot + "/Resources/EditorData", windowsPackageFolder + "/Resources/EditorData");
  331. fs.copySync(jakeRoot + "/Resources/PlayerData", windowsPackageFolder + "/Resources/PlayerData");
  332. fs.copySync(jakeRoot + "/Data/AtomicEditor/", windowsPackageFolder + "/Resources/ToolData");
  333. // 32 bit!
  334. fs.copySync(jakeRoot + "/Build/Windows/Binaries/x86/D3DCompiler_47.dll", windowsPackageFolder + "/Resources/ToolData/Deployment/Windows/x86/D3DCompiler_47.dll");
  335. if (jenkinsBuild) {
  336. cmds = [jakeRoot + "/Build/Windows/7z/7z.exe a -tzip " + distFolder + "/AtomicEditor_Windows.zip " + windowsPackageFolder]
  337. jake.exec(cmds, function() {});
  338. }
  339. });
  340. // We have the windows and mac editors builds, now we need to merge them
  341. task('merge_editor_data', [], function() {
  342. var mergeFolder = distFolder + "/EditorMerge";
  343. if (!fs.existsSync(mergeFolder)) {
  344. jake.mkdirP(mergeFolder);
  345. }
  346. if (!fs.existsSync(mergeFolder + "/snapshots")) {
  347. jake.mkdirP(mergeFolder + "/snapshots");
  348. }
  349. fs.copySync(distFolder + "/AtomicEditor_MacOSX.zip", mergeFolder + "/AtomicEditor_MacOSX.zip");
  350. fs.copySync(windowsPackageFolder + "/Artifacts/Dist/AtomicEditor_Windows.zip", mergeFolder + "/AtomicEditor_Windows.zip");
  351. process.chdir(mergeFolder);
  352. cmds = ["unzip ./AtomicEditor_MacOSX.zip && unzip ./AtomicEditor_Windows.zip"]
  353. jake.exec(cmds, function() {
  354. var winRoot = mergeFolder + "/Windows_Package/Resources";
  355. var macRoot = mergeFolder + "/AtomicEditor.app/Contents/Resources";
  356. var filenames = [
  357. "/ToolData/Deployment/Android/libs/armeabi-v7a/libAtomicPlayer.so",
  358. "/ToolData/Deployment/MacOS/AtomicPlayer.app",
  359. "/ToolData/Deployment/Web/AtomicPlayer.js",
  360. "/ToolData/Deployment/Web/AtomicPlayer.html.mem",
  361. "/ToolData/AtomicExamples",
  362. "/ToolData/Docs",
  363. ];
  364. // Mac Editor -> Windows Editor
  365. for (var i in filenames) {
  366. fs.copySync(macRoot + filenames[i], winRoot + filenames[i]);
  367. }
  368. // Windows Editor ->Mac Editor
  369. filenames = ["/ToolData/Deployment/Windows/x86/D3DCompiler_47.dll",
  370. "/ToolData/Deployment/Windows/x86/AtomicPlayer.exe",
  371. ];
  372. for (var i in filenames) {
  373. fs.copySync(winRoot + filenames[i], macRoot + filenames[i]);
  374. }
  375. zipcmds = [
  376. "rev=`git rev-parse HEAD` && zip -r -X ./snapshots/AtomicEditor_MacOSX_DevSnapshot_$rev.zip ./AtomicEditor.app",
  377. "rev=`git rev-parse HEAD` && zip -r -X ./snapshots/AtomicEditor_Win32_DevSnapshot_$rev.zip ./Windows_Package",
  378. "cp ./snapshots/*.zip /Users/jenge/Share/Temp/AtomicEditor_DevSnapshots/"
  379. ]
  380. jake.exec(zipcmds, function() {});
  381. });
  382. });
  383. });