nob.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #include <stdarg.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #define NOB_IMPLEMENTATION
  9. #include "./src/nob.h"
  10. #define CONFIG_PATH "./build/config.h"
  11. #ifdef CONFIGURED
  12. #include "./src/targets.h"
  13. #include CONFIG_PATH
  14. #define RAYLIB_VERSION "5.0"
  15. static const char *raylib_modules[] = {
  16. "rcore",
  17. "raudio",
  18. "rglfw",
  19. "rmodels",
  20. "rshapes",
  21. "rtext",
  22. "rtextures",
  23. "utils",
  24. };
  25. #if MUSIALIZER_TARGET == TARGET_LINUX
  26. #include "src/nob_linux.c"
  27. #elif MUSIALIZER_TARGET == TARGET_MACOS
  28. #include "src/nob_macos.c"
  29. #elif MUSIALIZER_TARGET == TARGET_WIN64_MINGW
  30. #include "src/nob_win64_mingw.c"
  31. #elif MUSIALIZER_TARGET == TARGET_WIN64_MSVC
  32. #include "src/nob_win64_msvc.c"
  33. #endif // MUSIALIZER_TARGET
  34. void log_available_subcommands(const char *program, Nob_Log_Level level)
  35. {
  36. nob_log(level, "Usage: %s [subcommand]", program);
  37. nob_log(level, "Subcommands:");
  38. nob_log(level, " build (default)");
  39. nob_log(level, " dist");
  40. nob_log(level, " svg");
  41. nob_log(level, " help");
  42. }
  43. void log_config(Nob_Log_Level level)
  44. {
  45. nob_log(level, "Target: %s", MUSIALIZER_TARGET_NAME);
  46. #ifdef MUSIALIZER_HOTRELOAD
  47. nob_log(level, "Hotreload: ENABLED");
  48. #else
  49. nob_log(level, "Hotreload: DISABLED");
  50. #endif // MUSIALIZER_HOTRELOAD
  51. #ifdef MUSIALIZER_MICROPHONE
  52. nob_log(level, "Microphone: ENABLED");
  53. #else
  54. nob_log(level, "Microphone: DISABLED");
  55. #endif // MUSIALIZER_MICROPHONE
  56. }
  57. int main(int argc, char **argv)
  58. {
  59. nob_log(NOB_INFO, "--- STAGE 2 ---");
  60. log_config(NOB_INFO);
  61. nob_log(NOB_INFO, "---");
  62. const char *program = nob_shift_args(&argc, &argv);
  63. const char *subcommand = NULL;
  64. if (argc <= 0) {
  65. subcommand = "build";
  66. } else {
  67. subcommand = nob_shift_args(&argc, &argv);
  68. }
  69. if (strcmp(subcommand, "build") == 0) {
  70. if (!build_raylib()) return 1;
  71. if (!build_musializer()) return 1;
  72. if (!nob_copy_directory_recursively("./resources/", "./build/resources/")) return 1;
  73. } else if (strcmp(subcommand, "dist") == 0) {
  74. if (!build_dist()) return 1;
  75. } else if (strcmp(subcommand, "config") == 0) {
  76. nob_log(NOB_ERROR, "The `config` command does not exist anymore!");
  77. nob_log(NOB_ERROR, "Edit %s to configure the build!", CONFIG_PATH);
  78. return 1;
  79. } else if (strcmp(subcommand, "svg") == 0) {
  80. Nob_Procs procs = {0};
  81. Nob_Cmd cmd = {0};
  82. if (nob_needs_rebuild1("./resources/logo/logo-256.ico", "./resources/logo/logo.svg")) {
  83. cmd.count = 0;
  84. nob_cmd_append(&cmd, "convert");
  85. nob_cmd_append(&cmd, "-background", "None");
  86. nob_cmd_append(&cmd, "./resources/logo/logo.svg");
  87. nob_cmd_append(&cmd, "-resize", "256");
  88. nob_cmd_append(&cmd, "./resources/logo/logo-256.ico");
  89. nob_da_append(&procs, nob_cmd_run_async(cmd));
  90. } else {
  91. nob_log(NOB_INFO, "./resources/logo/logo-256.ico is up to date");
  92. }
  93. if (nob_needs_rebuild1("./resources/logo/logo-256.png", "./resources/logo/logo.svg")) {
  94. cmd.count = 0;
  95. nob_cmd_append(&cmd, "convert");
  96. nob_cmd_append(&cmd, "-background", "None");
  97. nob_cmd_append(&cmd, "./resources/logo/logo.svg");
  98. nob_cmd_append(&cmd, "-resize", "256");
  99. nob_cmd_append(&cmd, "./resources/logo/logo-256.png");
  100. nob_da_append(&procs, nob_cmd_run_async(cmd));
  101. } else {
  102. nob_log(NOB_INFO, "./resources/logo/logo-256.png is up to date");
  103. }
  104. if (nob_needs_rebuild1("./resources/icons/fullscreen.png", "./resources/icons/fullscreen.svg")) {
  105. cmd.count = 0;
  106. nob_cmd_append(&cmd, "convert");
  107. nob_cmd_append(&cmd, "-background", "None");
  108. nob_cmd_append(&cmd, "./resources/icons/fullscreen.svg");
  109. nob_cmd_append(&cmd, "./resources/icons/fullscreen.png");
  110. nob_da_append(&procs, nob_cmd_run_async(cmd));
  111. } else {
  112. nob_log(NOB_INFO, "./resources/icons/fullscreen.png is up to date");
  113. }
  114. if (nob_needs_rebuild1("./resources/icons/volume.png", "./resources/icons/volume.svg")) {
  115. cmd.count = 0;
  116. nob_cmd_append(&cmd, "convert");
  117. nob_cmd_append(&cmd, "-background", "None");
  118. nob_cmd_append(&cmd, "./resources/icons/volume.svg");
  119. nob_cmd_append(&cmd, "./resources/icons/volume.png");
  120. nob_da_append(&procs, nob_cmd_run_async(cmd));
  121. } else {
  122. nob_log(NOB_INFO, "./resources/icons/volume.png is up to date");
  123. }
  124. if (nob_needs_rebuild1("./resources/icons/play.png", "./resources/icons/play.svg")) {
  125. cmd.count = 0;
  126. nob_cmd_append(&cmd, "convert");
  127. nob_cmd_append(&cmd, "-background", "None");
  128. nob_cmd_append(&cmd, "./resources/icons/play.svg");
  129. nob_cmd_append(&cmd, "./resources/icons/play.png");
  130. nob_da_append(&procs, nob_cmd_run_async(cmd));
  131. } else {
  132. nob_log(NOB_INFO, "./resources/icons/play.png is up to date");
  133. }
  134. if (nob_needs_rebuild1("./resources/icons/render.png", "./resources/icons/render.svg")) {
  135. cmd.count = 0;
  136. nob_cmd_append(&cmd, "convert");
  137. nob_cmd_append(&cmd, "-background", "None");
  138. nob_cmd_append(&cmd, "./resources/icons/render.svg");
  139. nob_cmd_append(&cmd, "./resources/icons/render.png");
  140. nob_da_append(&procs, nob_cmd_run_async(cmd));
  141. } else {
  142. nob_log(NOB_INFO, "./resources/icons/render.png is up to date");
  143. }
  144. if (!nob_procs_wait(procs)) return 1;
  145. } else if (strcmp(subcommand, "help") == 0){
  146. log_available_subcommands(program, NOB_INFO);
  147. } else {
  148. nob_log(NOB_ERROR, "Unknown subcommand %s", subcommand);
  149. log_available_subcommands(program, NOB_ERROR);
  150. }
  151. // TODO: it would be nice to check for situations like building TARGET_WIN64_MSVC on Linux and report that it's not possible.
  152. return 0;
  153. }
  154. #else
  155. void generate_default_config(Nob_String_Builder *content)
  156. {
  157. nob_sb_append_cstr(content, "//// Build target. Pick only one!\n");
  158. #ifdef _WIN32
  159. # if defined(_MSC_VER)
  160. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_LINUX\n");
  161. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_WIN64_MINGW\n");
  162. nob_sb_append_cstr(content, "#define MUSIALIZER_TARGET TARGET_WIN64_MSVC\n");
  163. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_MACOS\n");
  164. # else
  165. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_LINUX\n");
  166. nob_sb_append_cstr(content, "#define MUSIALIZER_TARGET TARGET_WIN64_MINGW\n");
  167. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_WIN64_MSVC\n");
  168. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_MACOS\n");
  169. # endif
  170. #else
  171. # if defined (__APPLE__) || defined (__MACH__)
  172. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_LINUX\n");
  173. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_WIN64_MINGW\n");
  174. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_WIN64_MSVC\n");
  175. nob_sb_append_cstr(content, "#define MUSIALIZER_TARGET TARGET_MACOS\n");
  176. # else
  177. nob_sb_append_cstr(content, "#define MUSIALIZER_TARGET TARGET_LINUX\n");
  178. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_WIN64_MINGW\n");
  179. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_WIN64_MSVC\n");
  180. nob_sb_append_cstr(content, "// #define MUSIALIZER_TARGET TARGET_MACOS\n");
  181. # endif
  182. #endif
  183. nob_sb_append_cstr(content, "\n");
  184. nob_sb_append_cstr(content, "//// Moves everything in src/plub.c to a separate \"DLL\" so it can be hotreloaded. Works only for Linux right now\n");
  185. nob_sb_append_cstr(content, "// #define MUSIALIZER_HOTRELOAD\n");
  186. nob_sb_append_cstr(content, "\n");
  187. nob_sb_append_cstr(content, "//// Unfinished feature that enables capturing sound from the mic.\n");
  188. nob_sb_append_cstr(content, "// #define MUSIALIZER_MICROPHONE\n");
  189. }
  190. int main(int argc, char **argv)
  191. {
  192. NOB_GO_REBUILD_URSELF(argc, argv);
  193. const char *program = nob_shift_args(&argc, &argv);
  194. const char *build_conf_path = "./build/build.conf";
  195. int build_conf_exists = nob_file_exists(build_conf_path);
  196. if (build_conf_exists < 0) return 1;
  197. if (build_conf_exists) {
  198. nob_log(NOB_ERROR, "We found %s. That means your build folder has an old schema.", build_conf_path);
  199. nob_log(NOB_ERROR, "Instead of %s you are suppose to use %s to configure the build now.", build_conf_path, CONFIG_PATH);
  200. nob_log(NOB_ERROR, "Remove your ./build/ folder and run %s again to regenerate the folder with the new schema.", program);
  201. return 1;
  202. }
  203. nob_log(NOB_INFO, "--- STAGE 1 ---");
  204. if (!nob_mkdir_if_not_exists("build")) return 1;
  205. int config_exists = nob_file_exists(CONFIG_PATH);
  206. if (config_exists < 0) return 1;
  207. if (config_exists == 0) {
  208. nob_log(NOB_INFO, "Generating %s", CONFIG_PATH);
  209. Nob_String_Builder content = {0};
  210. generate_default_config(&content);
  211. if (!nob_write_entire_file(CONFIG_PATH, content.items, content.count)) return 1;
  212. } else {
  213. nob_log(NOB_INFO, "file `%s` already exists", CONFIG_PATH);
  214. }
  215. Nob_Cmd cmd = {0};
  216. const char *configured_binary = "build/nob.configured";
  217. nob_cmd_append(&cmd, NOB_REBUILD_URSELF(configured_binary, "nob.c"), "-DCONFIGURED");
  218. if (!nob_cmd_run_sync(cmd)) return 1;
  219. cmd.count = 0;
  220. nob_cmd_append(&cmd, configured_binary);
  221. nob_da_append_many(&cmd, argv, argc);
  222. if (!nob_cmd_run_sync(cmd)) return 1;
  223. return 0;
  224. }
  225. #endif // CONFIGURED