nob_stage2.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #include <stdbool.h>
  2. #define NOB_IMPLEMENTATION
  3. #include "../nob.h"
  4. #include "../build/config.h"
  5. #include "./configurer.c"
  6. static const char *raylib_modules[] = {
  7. "rcore",
  8. "raudio",
  9. "rglfw",
  10. "rmodels",
  11. "rshapes",
  12. "rtext",
  13. "rtextures",
  14. "utils",
  15. };
  16. // @backcomp
  17. #if defined(MUSIALIZER_TARGET)
  18. #error "We recently replaced a single MUSIALIZER_TARGET macro with a bunch of MUSIALIZER_TARGET_<TARGET> macros instead. Since MUSIALIZER_TARGET is still defined your ./build/ is probably old. Please remove it so ./build/config.h gets regenerated."
  19. #endif // MUSIALIZER_TARGET
  20. #if defined(MUSIALIZER_TARGET_LINUX)
  21. #include "nob_linux.c"
  22. #elif defined(MUSIALIZER_TARGET_MACOS)
  23. #include "nob_macos.c"
  24. #elif defined(MUSIALIZER_TARGET_WIN64_MINGW)
  25. #include "nob_win64_mingw.c"
  26. #elif defined(MUSIALIZER_TARGET_WIN64_MSVC)
  27. #include "nob_win64_msvc.c"
  28. #elif defined(MUSIALIZER_TARGET_OPENBSD)
  29. #include "nob_openbsd.c"
  30. #else
  31. #error "No Musializer Target is defined. Check your ./build/config.h."
  32. #endif // MUSIALIZER_TARGET
  33. #include "../build/config_logger.c"
  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. typedef struct {
  44. const char *file_path;
  45. size_t offset;
  46. size_t size;
  47. } Resource;
  48. Resource resources[] = {
  49. { .file_path = "./resources/logo/logo-256.png" },
  50. { .file_path = "./resources/shaders/glsl330/circle.fs" },
  51. { .file_path = "./resources/shaders/glsl120/circle.fs" },
  52. { .file_path = "./resources/icons/volume.png" },
  53. { .file_path = "./resources/icons/play.png" },
  54. { .file_path = "./resources/icons/render.png" },
  55. { .file_path = "./resources/icons/fullscreen.png" },
  56. { .file_path = "./resources/icons/microphone.png" },
  57. { .file_path = "./resources/fonts/Alegreya-Regular.ttf" },
  58. };
  59. bool generate_resource_bundle(void)
  60. {
  61. bool result = true;
  62. Nob_String_Builder bundle = {0};
  63. Nob_String_Builder content = {0};
  64. FILE *out = NULL;
  65. // bundle = [aaaaaaaaabbbbb]
  66. // ^ ^
  67. // content = []
  68. // 0, 9
  69. for (size_t i = 0; i < NOB_ARRAY_LEN(resources); ++i) {
  70. content.count = 0;
  71. if (!nob_read_entire_file(resources[i].file_path, &content)) nob_return_defer(false);
  72. resources[i].offset = bundle.count;
  73. resources[i].size = content.count;
  74. nob_da_append_many(&bundle, content.items, content.count);
  75. nob_da_append(&bundle, 0);
  76. }
  77. const char *bundle_h_path = "./build/bundle.h";
  78. out = fopen(bundle_h_path, "wb");
  79. if (out == NULL) {
  80. nob_log(NOB_ERROR, "Could not open file %s for writing: %s", bundle_h_path, strerror(errno));
  81. nob_return_defer(false);
  82. }
  83. genf(out, "#ifndef BUNDLE_H_");
  84. genf(out, "#define BUNDLE_H_");
  85. genf(out, "typedef struct {");
  86. genf(out, " const char *file_path;");
  87. genf(out, " size_t offset;");
  88. genf(out, " size_t size;");
  89. genf(out, "} Resource;");
  90. genf(out, "size_t resources_count = %zu;", NOB_ARRAY_LEN(resources));
  91. genf(out, "Resource resources[] = {");
  92. for (size_t i = 0; i < NOB_ARRAY_LEN(resources); ++i) {
  93. genf(out, " {.file_path = \"%s\", .offset = %zu, .size = %zu},",
  94. resources[i].file_path, resources[i].offset, resources[i].size);
  95. }
  96. genf(out, "};");
  97. genf(out, "unsigned char bundle[] = {");
  98. size_t row_size = 20;
  99. for (size_t i = 0; i < bundle.count; ) {
  100. fprintf(out, " ");
  101. for (size_t col = 0; col < row_size && i < bundle.count; ++col, ++i) {
  102. fprintf(out, "0x%02X, ", (unsigned char)bundle.items[i]);
  103. }
  104. genf(out, "");
  105. }
  106. genf(out, "};");
  107. genf(out, "#endif // BUNDLE_H_");
  108. nob_log(NOB_INFO, "Generated %s", bundle_h_path);
  109. defer:
  110. if (out) fclose(out);
  111. free(content.items);
  112. free(bundle.items);
  113. return result;
  114. }
  115. int main(int argc, char **argv)
  116. {
  117. nob_log(NOB_INFO, "--- STAGE 2 ---");
  118. log_config(NOB_INFO);
  119. nob_log(NOB_INFO, "---");
  120. const char *program = nob_shift_args(&argc, &argv);
  121. const char *subcommand = NULL;
  122. if (argc <= 0) {
  123. subcommand = "build";
  124. } else {
  125. subcommand = nob_shift_args(&argc, &argv);
  126. }
  127. if (strcmp(subcommand, "build") == 0) {
  128. if (!build_raylib()) return 1;
  129. #ifndef MUSIALIZER_UNBUNDLE
  130. if (!generate_resource_bundle()) return 1;
  131. #endif // MUSIALIZER_UNBUNDLE
  132. if (!build_musializer()) return 1;
  133. } else if (strcmp(subcommand, "dist") == 0) {
  134. if (!build_dist()) return 1;
  135. } else if (strcmp(subcommand, "config") == 0) {
  136. nob_log(NOB_ERROR, "The `config` command does not exist anymore!");
  137. nob_log(NOB_ERROR, "Edit %s to configure the build!", CONFIG_PATH);
  138. return 1;
  139. } else if (strcmp(subcommand, "svg") == 0) {
  140. Nob_Procs procs = {0};
  141. Nob_Cmd cmd = {0};
  142. typedef struct {
  143. const char *in_path;
  144. const char *out_path;
  145. int resize;
  146. } Svg;
  147. Svg svgs[] = {
  148. {.out_path = "./resources/logo/logo-256.ico", .in_path = "./resources/logo/logo.svg", .resize = 256, },
  149. {.out_path = "./resources/logo/logo-256.png", .in_path = "./resources/logo/logo.svg", .resize = 256, },
  150. {.out_path = "./resources/icons/fullscreen.png", .in_path = "./resources/icons/fullscreen.svg" },
  151. {.out_path = "./resources/icons/volume.png", .in_path = "./resources/icons/volume.svg" },
  152. {.out_path = "./resources/icons/play.png", .in_path = "./resources/icons/play.svg" },
  153. {.out_path = "./resources/icons/render.png", .in_path = "./resources/icons/render.svg" },
  154. {.out_path = "./resources/icons/microphone.png", .in_path = "./resources/icons/microphone.svg" },
  155. };
  156. for (size_t i = 0; i < NOB_ARRAY_LEN(svgs); ++i) {
  157. if (nob_needs_rebuild1(svgs[i].out_path, svgs[i].in_path)) {
  158. cmd.count = 0;
  159. nob_cmd_append(&cmd, "convert");
  160. nob_cmd_append(&cmd, "-background", "None");
  161. nob_cmd_append(&cmd, svgs[i].in_path);
  162. if (svgs[i].resize) {
  163. nob_cmd_append(&cmd, "-resize", nob_temp_sprintf("%d", svgs[i].resize));
  164. }
  165. nob_cmd_append(&cmd, svgs[i].out_path);
  166. nob_da_append(&procs, nob_cmd_run_async(cmd));
  167. } else {
  168. nob_log(NOB_INFO, "%s is up to date", svgs[i].out_path);
  169. }
  170. }
  171. if (!nob_procs_wait(procs)) return 1;
  172. } else if (strcmp(subcommand, "help") == 0) {
  173. log_available_subcommands(program, NOB_INFO);
  174. } else {
  175. nob_log(NOB_ERROR, "Unknown subcommand %s", subcommand);
  176. log_available_subcommands(program, NOB_ERROR);
  177. }
  178. // TODO: it would be nice to check for situations like building TARGET_WIN64_MSVC on Linux and report that it's not possible.
  179. return 0;
  180. }