Jakefile 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  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('atomictool', {
  93. async: true
  94. }, function() {
  95. if (host == "darwin") {
  96. if (!fs.existsSync(macOSXBuildFolder)) {
  97. jake.mkdirP(macOSXBuildFolder);
  98. }
  99. var cmds = [
  100. 'cmake ../../ -G Xcode ' + getAtomicDevBuildDefine(),
  101. 'xcodebuild -target AtomicTool -configuration Release'
  102. ]
  103. process.chdir(macOSXBuildFolder);
  104. jake.exec(cmds, function() {
  105. fs.copySync(atomicToolBinary, platformBinariesFolder + "/MacOSX/" + path.basename(atomicToolBinary));
  106. console.log("Built MacOSX AtomicTool");
  107. complete();
  108. }, {
  109. printStdout: true
  110. });
  111. } else {
  112. if (!fs.existsSync(windowsBuildFolder)) {
  113. jake.mkdirP(windowsBuildFolder);
  114. }
  115. process.chdir(windowsBuildFolder);
  116. jake.exec(jakeRoot + "/Build/Windows/CompileAtomicTool.bat", function() {
  117. fs.copySync(atomicToolBinary, platformBinariesFolder + "/Win32/" + path.basename(atomicToolBinary));
  118. console.log("Built Windows AtomicTool");
  119. complete();
  120. }, {
  121. printStdout: true
  122. });
  123. }
  124. }); // end build:atomictool
  125. var deps = [];
  126. if (includeDeployments) {
  127. if (host == 'darwin') {
  128. deps = ['atomictool'];
  129. if (deployments.ios)
  130. deps.push("build:ios");
  131. if (deployments.android)
  132. deps.push("build:android");
  133. if (deployments.web)
  134. deps.push("build:web");
  135. }
  136. }
  137. task('install_deployments', {
  138. async: true
  139. }, function() {
  140. console.log("Installing Deployments");
  141. // deployment root for local dev builds
  142. var deployRoot = jakeRoot + "/Data/AtomicEditor/Deployment";
  143. if (host == "darwin") {
  144. if (deployments.osx)
  145. fs.copySync(platformBinariesFolder + "/MacOSX/AtomicPlayer", deployRoot + "/MacOS/AtomicPlayer.app/Contents/MacOS/AtomicPlayer");
  146. if (deployments.android)
  147. fs.copySync(platformBinariesFolder + "/Android/libAtomicPlayer.so", deployRoot + "/Android/libs/armeabi-v7a/libAtomicPlayer.so");
  148. if (deployments.ios) {
  149. fs.copySync(artifactsFolder + "/ios-deploy/ios-deploy/ios-deploy", deployRoot + "/IOS/ios-deploy/ios-deploy");
  150. fs.copySync(platformBinariesFolder + "/IOS/AtomicPlayer", deployRoot + "/IOS/AtomicPlayer.app/AtomicPlayer");
  151. }
  152. if (deployments.web) {
  153. fs.copySync(platformBinariesFolder + "/Web/AtomicPlayer.js", deployRoot + "/Web/AtomicPlayer.js");
  154. fs.copySync(platformBinariesFolder + "/Web/AtomicPlayer.html.mem", deployRoot + "/Web/AtomicPlayer.html.mem");
  155. }
  156. } else if (host == "win32") {
  157. if (deployments.windows) {
  158. fs.copySync(platformBinariesFolder + "/Win32/AtomicPlayer.exe", deployRoot + "/Windows/x86/AtomicPlayer.exe");
  159. }
  160. }
  161. complete();
  162. });
  163. task('ios_deploy', {
  164. async: true
  165. }, function() {
  166. if (!fs.existsSync(iosDeployBuildFolder)) {
  167. jake.mkdirP(iosDeployBuildFolder);
  168. }
  169. process.chdir(iosDeployBuildFolder);
  170. if (!fs.existsSync(iosDeployBuildFolder + "/ios-deploy")) {
  171. jake.exec("git clone https://github.com/AtomicGameEngine/ios-deploy && cd ios-deploy && make ios-deploy");
  172. }
  173. complete();
  174. });
  175. task('macosx', deps, {
  176. async: true
  177. }, function() {
  178. if (!fs.existsSync(macOSXBuildFolder)) {
  179. jake.mkdirP(macOSXBuildFolder);
  180. }
  181. var cmds = [
  182. 'cmake ../../ -G Xcode ' + getAtomicDevBuildDefine(),
  183. 'xcodebuild -configuration Release'
  184. ]
  185. process.chdir(macOSXBuildFolder);
  186. jake.exec(cmds, function() {
  187. fs.copySync(atomicEditorBinary, platformBinariesFolder + "/MacOSX/" + path.basename(atomicEditorBinary));
  188. fs.copySync(atomicPlayerBinary, platformBinariesFolder + "/MacOSX/" + path.basename(atomicPlayerBinary));
  189. if (includeDeployments) {
  190. jake.Task['build:install_deployments'].invoke();
  191. }
  192. console.log("Built MacOSX");
  193. complete();
  194. }, {
  195. printStdout: true
  196. });
  197. }); // end build:macosx
  198. task('windows', {
  199. async: true
  200. }, function() {
  201. if (!fs.existsSync(windowsBuildFolder)) {
  202. jake.mkdirP(windowsBuildFolder);
  203. }
  204. process.chdir(windowsBuildFolder);
  205. jake.exec(jakeRoot + "/Build/Windows/Compile.bat", function() {
  206. fs.copySync(atomicEditorBinary, platformBinariesFolder + "/Win32/" + path.basename(atomicEditorBinary));
  207. fs.copySync(atomicPlayerBinary, platformBinariesFolder + "/Win32/" + path.basename(atomicPlayerBinary));
  208. if (includeDeployments) {
  209. jake.Task['build:install_deployments'].invoke();
  210. }
  211. complete();
  212. }, {
  213. printStdout: true
  214. });
  215. });
  216. task('android', ['atomictool'], {
  217. async: true
  218. }, function() {
  219. if (!fs.existsSync(androidBuildFolder)) {
  220. jake.mkdirP(androidBuildFolder);
  221. }
  222. process.chdir(androidBuildFolder);
  223. var cmds = [
  224. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/Atomic/ ANDROID",
  225. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/AtomicPlayer/ ANDROID"
  226. ];
  227. if (host == "darwin") {
  228. cmds.push("cmake -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=" + jakeRoot + "/CMake/Toolchains/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ../../");
  229. cmds.push("make -j4");
  230. jake.exec(cmds, function() {
  231. fs.copySync(androidPlayerBinary, platformBinariesFolder + "/Android/" + path.basename(androidPlayerBinary));
  232. console.log("Built Android Player");
  233. complete();
  234. }, {
  235. printStdout: true
  236. });
  237. } else {
  238. cmds.push(jakeRoot + "/Build/Windows/CompileAndroid.bat");
  239. jake.exec(cmds, function() {
  240. fs.copySync(androidPlayerBinary, platformBinariesFolder + "/Android/" + path.basename(androidPlayerBinary));
  241. // sneak this in here, need to sort deployments for local dev builds
  242. var deployRoot = jakeRoot + "/Data/AtomicEditor/Deployment";
  243. fs.copySync(androidPlayerBinary, deployRoot + "/Android/libs/armeabi-v7a/libAtomicPlayer.so");
  244. console.log("Built Android Player");
  245. complete();
  246. }, {
  247. printStdout: true
  248. });
  249. }
  250. });
  251. task('ios', ['atomictool', 'ios_deploy'], {
  252. async: true
  253. }, function() {
  254. if (!fs.existsSync(iosBuildFolder)) {
  255. jake.mkdirP(iosBuildFolder);
  256. }
  257. process.chdir(iosBuildFolder);
  258. var cmds = [
  259. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/Atomic/ IOS",
  260. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/AtomicPlayer/ IOS",
  261. "cmake -DIOS=1 -G Xcode ../../"
  262. ]
  263. if (jenkinsBuild) {
  264. cmds.push("security -v list-keychains -d system -s /Users/jenkins/Library/Keychains/codesign.keychain");
  265. cmds.push("security -v unlock-keychain /Users/jenkins/Library/Keychains/codesign.keychain");
  266. }
  267. cmds.push("xcodebuild -configuration Release");
  268. jake.exec(cmds, function() {
  269. fs.copySync(iosPlayerBinary, platformBinariesFolder + "/IOS/" + path.basename(iosPlayerBinary));
  270. console.log("Built iOS Player");
  271. complete();
  272. }, {
  273. printStdout: true
  274. });
  275. });
  276. task('web', ['atomictool'], {
  277. async: true
  278. }, function() {
  279. if (!fs.existsSync(webBuildFolder)) {
  280. jake.mkdirP(webBuildFolder);
  281. }
  282. process.chdir(webBuildFolder);
  283. var cmds = [
  284. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/Atomic/ WEB",
  285. atomicToolBinary + " bind " + jakeRoot + " Script/Packages/AtomicPlayer/ WEB",
  286. "cmake -DEMSCRIPTEN=1 -DATOMIC_BUILD_2D=1 -DCMAKE_TOOLCHAIN_FILE=" + jakeRoot + "/CMake/Toolchains/emscripten.toolchain.cmake -DCMAKE_BUILD_TYPE=Release ../../",
  287. "make -j4",
  288. "cd ./Source/AtomicPlayer/Application && mv ./AtomicPlayer ./AtomicPlayer.bc && " +
  289. // -s ERROR_ON_UNDEFINED_SYMBOLS=1 (disabled for pthread errors currently on incoming)
  290. "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"
  291. ]
  292. jake.exec(cmds, function() {
  293. fs.copySync(webPlayerBinary, platformBinariesFolder + "/Web/" + path.basename(webPlayerBinary));
  294. fs.copySync(webPlayerMemFile, platformBinariesFolder + "/Web/" + path.basename(webPlayerMemFile));
  295. console.log("Built Web Player");
  296. complete();
  297. }, {
  298. printStdout: true
  299. });
  300. });
  301. }); // end build namespace
  302. namespace('package', function() {
  303. task('genjsdocs', {
  304. async: true
  305. }, function() {
  306. if (!jenkinsBuild || !generateJSDoc) {
  307. complete();
  308. return;
  309. }
  310. console.log("Generating JSDocs");
  311. fs.copySync(jakeRoot + "/Docs/Readme.md", jsDocFolder + "/Readme.md");
  312. fs.copySync(jakeRoot + "/Docs/jsdoc.conf", jsDocFolder + "/jsdoc.conf");
  313. cmds = ["cd " + jsDocFolder + " && npm install git+https://github.com/jsdoc3/jsdoc",
  314. "cd " + jsDocFolder + " && git clone https://github.com/AtomicGameEngine/jaguarjs-jsdoc && cd jaguarjs-jsdoc && git checkout atomic_master",
  315. "cd " + jsDocFolder + " && ./node_modules/.bin/jsdoc ./Atomic.js -t ./jaguarjs-jsdoc/ -c ./jsdoc.conf Readme.md",
  316. ];
  317. jake.exec(cmds, function() {
  318. complete();
  319. }, {
  320. printStdout: true
  321. });
  322. });
  323. task('macosx', ['clean:all', 'build:macosx', 'package:genjsdocs'], function() {
  324. if (!fs.existsSync(distFolder)) {
  325. jake.mkdirP(distFolder);
  326. }
  327. jake.mkdirP(macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/");
  328. var editorAppSourceFolder = macOSXBuildFolder + "/Source/AtomicEditor/Release/AtomicEditor.app";
  329. fs.copySync(editorAppSourceFolder, macOSXPackageFolder + "/AtomicEditor.app");
  330. // copy resources
  331. fs.copySync(jakeRoot + "/Resources/CoreData", macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/CoreData");
  332. fs.copySync(jakeRoot + "/Resources/EditorData", macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/EditorData");
  333. fs.copySync(jakeRoot + "/Resources/PlayerData", macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/PlayerData");
  334. var toolDataDir = macOSXPackageFolder + "/AtomicEditor.app/Contents/Resources/ToolData/";
  335. fs.copySync(jakeRoot + "/Data/AtomicEditor/", toolDataDir);
  336. if (jenkinsBuild) {
  337. console.log("Exporting AtomicExamples Repo (master) & Generating Dist");
  338. if (generateJSDoc) {
  339. fs.copySync(jsDocFolder + "/out", toolDataDir + "Docs/JSDocs");
  340. }
  341. cmds = ["git clone https://github.com/AtomicGameEngine/AtomicExamples " + toolDataDir + "AtomicExamples && rm -rf " + toolDataDir + "AtomicExamples/.git",
  342. "cd " + macOSXPackageFolder + " && zip -r -X " + distFolder + "/AtomicEditor_MacOSX.zip ./AtomicEditor.app"
  343. ];
  344. jake.exec(cmds, function() {});
  345. }
  346. });
  347. task('windows', ['clean:all', 'build:windows'], function() {
  348. if (!fs.existsSync(distFolder)) {
  349. jake.mkdirP(distFolder);
  350. }
  351. console.log("Packaging Windows Editor");
  352. jake.mkdirP(windowsPackageFolder + "/Resources");
  353. fs.copySync(windowsBuildFolder + "/Source/AtomicEditor/Release/AtomicEditor.exe", windowsPackageFolder + "/AtomicEditor.exe")
  354. // 32 bit build for packaging!
  355. fs.copySync(jakeRoot + "/Build/Windows/Binaries/x86/D3DCompiler_47.dll", windowsPackageFolder + "/D3DCompiler_47.dll")
  356. // copy resources
  357. fs.copySync(jakeRoot + "/Resources/CoreData", windowsPackageFolder + "/Resources/CoreData");
  358. fs.copySync(jakeRoot + "/Resources/EditorData", windowsPackageFolder + "/Resources/EditorData");
  359. fs.copySync(jakeRoot + "/Resources/PlayerData", windowsPackageFolder + "/Resources/PlayerData");
  360. fs.copySync(jakeRoot + "/Data/AtomicEditor/", windowsPackageFolder + "/Resources/ToolData");
  361. // 32 bit!
  362. fs.copySync(jakeRoot + "/Build/Windows/Binaries/x86/D3DCompiler_47.dll", windowsPackageFolder + "/Resources/ToolData/Deployment/Windows/x86/D3DCompiler_47.dll");
  363. if (jenkinsBuild) {
  364. cmds = [jakeRoot + "/Build/Windows/7z/7z.exe a -tzip " + distFolder + "/AtomicEditor_Windows.zip " + windowsPackageFolder]
  365. jake.exec(cmds, function() {});
  366. }
  367. });
  368. // We have the windows and mac editors builds, now we need to merge them
  369. task('merge_editor_data', [], function() {
  370. var mergeFolder = distFolder + "/EditorMerge";
  371. if (!fs.existsSync(mergeFolder)) {
  372. jake.mkdirP(mergeFolder);
  373. }
  374. if (!fs.existsSync(mergeFolder + "/snapshots")) {
  375. jake.mkdirP(mergeFolder + "/snapshots");
  376. }
  377. fs.copySync(distFolder + "/AtomicEditor_MacOSX.zip", mergeFolder + "/AtomicEditor_MacOSX.zip");
  378. fs.copySync(windowsPackageFolder + "/Artifacts/Dist/AtomicEditor_Windows.zip", mergeFolder + "/AtomicEditor_Windows.zip");
  379. process.chdir(mergeFolder);
  380. cmds = ["unzip ./AtomicEditor_MacOSX.zip && unzip ./AtomicEditor_Windows.zip"]
  381. jake.exec(cmds, function() {
  382. var winRoot = mergeFolder + "/Windows_Package/Resources";
  383. var macRoot = mergeFolder + "/AtomicEditor.app/Contents/Resources";
  384. var filenames = [
  385. "/ToolData/Deployment/Android/libs/armeabi-v7a/libAtomicPlayer.so",
  386. "/ToolData/Deployment/MacOS/AtomicPlayer.app",
  387. "/ToolData/Deployment/Web/AtomicPlayer.js",
  388. "/ToolData/Deployment/Web/AtomicPlayer.html.mem",
  389. "/ToolData/AtomicExamples",
  390. "/ToolData/Docs",
  391. ];
  392. // Mac Editor -> Windows Editor
  393. for (var i in filenames) {
  394. fs.copySync(macRoot + filenames[i], winRoot + filenames[i]);
  395. }
  396. // Windows Editor ->Mac Editor
  397. filenames = ["/ToolData/Deployment/Windows/x86/D3DCompiler_47.dll",
  398. "/ToolData/Deployment/Windows/x86/AtomicPlayer.exe",
  399. ];
  400. for (var i in filenames) {
  401. fs.copySync(winRoot + filenames[i], macRoot + filenames[i]);
  402. }
  403. zipcmds = [
  404. "rev=`git rev-parse HEAD` && zip -r -X ./snapshots/AtomicEditor_MacOSX_DevSnapshot_$rev.zip ./AtomicEditor.app",
  405. "rev=`git rev-parse HEAD` && zip -r -X ./snapshots/AtomicEditor_Win32_DevSnapshot_$rev.zip ./Windows_Package",
  406. "cp ./snapshots/*.zip /Users/jenge/Share/Temp/AtomicEditor_DevSnapshots/"
  407. ]
  408. jake.exec(zipcmds, function() {});
  409. });
  410. });
  411. });