Jakefile 18 KB

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