Skip to content

Commit

Permalink
add hotreload support for windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Markos-Th09 committed Feb 29, 2024
1 parent 9ddb4d2 commit fa92b42
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ nob
nob.old
nob.exe
nob.exe.old
nob.obj
38 changes: 38 additions & 0 deletions src/hotreload_windows.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#define NOUSER
#include <windows.h>

#include <raylib.h>
#include "hotreload.h"

static const char *libplug_file_name = "libplug.dll";
static void *libplug = NULL;

#define PLUG(name, ...) name##_t *name = NULL;
LIST_OF_PLUGS
#undef PLUG

bool reload_libplug(void)
{
if (libplug != NULL) FreeLibrary(libplug);

libplug = LoadLibrary(libplug_file_name);
if (libplug == NULL) {
TraceLog(LOG_ERROR, "HOTRELOAD: could not load %s: %s", libplug_file_name, GetLastError());
return false;
}

#define PLUG(name, ...) \
name = GetProcAddress(libplug, #name); \
if (name == NULL) { \
TraceLog(LOG_ERROR, "HOTRELOAD: could not find %s symbol in %s: %s", \
#name, libplug_file_name, GetLastError()); \
return false; \
}
LIST_OF_PLUGS
#undef PLUG

return true;
}
60 changes: 55 additions & 5 deletions src/nob_win64_mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ bool build_musializer(void)
Nob_Cmd cmd = {0};
Nob_Procs procs = {0};

#ifdef MUSIALIZER_HOTRELOAD
#error "TODO: hotreloading is not supported on TARGET_WIN64_MINGW yet"
#else
cmd.count = 0;
#ifdef _WIN32
// On windows, mingw doesn't have the `x86_64-w64-mingw32-` prefix for windres.
Expand All @@ -21,7 +18,47 @@ bool build_musializer(void)
nob_cmd_append(&cmd, "-O", "coff");
nob_cmd_append(&cmd, "-o", "./build/musializer.res");
if (!nob_cmd_run_sync(cmd)) nob_return_defer(false);
#ifdef MUSIALIZER_HOTRELOAD
procs.count = 0;
cmd.count = 0;
nob_cmd_append(&cmd, "x86_64-w64-mingw32-gcc");
nob_cmd_append(&cmd, "-mwindows", "-Wall", "-Wextra", "-ggdb");
nob_cmd_append(&cmd, "-I./build/");
nob_cmd_append(&cmd, "-I./raylib/raylib-"RAYLIB_VERSION"/src/");
nob_cmd_append(&cmd, "-fPIC", "-shared");
nob_cmd_append(&cmd, "-static-libgcc");
nob_cmd_append(&cmd, "-o", "./build/libplug.dll");
nob_cmd_append(&cmd,
"./src/plug.c",
"./src/ffmpeg_windows.c");
nob_cmd_append(&cmd,
"-L./build",
"-l:raylib.dll");
nob_cmd_append(&cmd, "-lwinmm", "-lgdi32");
nob_da_append(&procs, nob_cmd_run_async(cmd));

cmd.count = 0;
nob_cmd_append(&cmd, "x86_64-w64-mingw32-gcc");
nob_cmd_append(&cmd, "-mwindows", "-Wall", "-Wextra", "-ggdb");
nob_cmd_append(&cmd, "-I./build/");
nob_cmd_append(&cmd, "-I./raylib/raylib-"RAYLIB_VERSION"/src/");
nob_cmd_append(&cmd, "-o", "./build/musializer");
nob_cmd_append(&cmd,
"./src/musializer.c",
"./src/hotreload_windows.c");
nob_cmd_append(&cmd,
"-Wl,-rpath=./build/",
"-Wl,-rpath=./",
nob_temp_sprintf("-Wl,-rpath=./build/raylib/%s", MUSIALIZER_TARGET_NAME),
// NOTE: just in case somebody wants to run musializer from within the ./build/ folder
nob_temp_sprintf("-Wl,-rpath=./raylib/%s", MUSIALIZER_TARGET_NAME));
nob_cmd_append(&cmd,
"-L./build",
"-l:raylib.dll");
nob_cmd_append(&cmd, "-lwinmm", "-lgdi32");
nob_da_append(&procs, nob_cmd_run_async(cmd));
if (!nob_procs_wait(procs)) nob_return_defer(false);
#else
cmd.count = 0;
nob_cmd_append(&cmd, "x86_64-w64-mingw32-gcc");
nob_cmd_append(&cmd, "-mwindows", "-Wall", "-Wextra", "-ggdb");
Expand Down Expand Up @@ -95,15 +132,28 @@ bool build_raylib()
const char *libraylib_path = nob_temp_sprintf("%s/libraylib.a", build_path);

if (nob_needs_rebuild(libraylib_path, object_files.items, object_files.count)) {
nob_cmd_append(&cmd, "ar", "-crs", libraylib_path);
nob_cmd_append(&cmd, "x86_64-w64-mingw32-ar", "-crs", libraylib_path);
for (size_t i = 0; i < NOB_ARRAY_LEN(raylib_modules); ++i) {
const char *input_path = nob_temp_sprintf("%s/%s.o", build_path, raylib_modules[i]);
nob_cmd_append(&cmd, input_path);
}
if (!nob_cmd_run_sync(cmd)) nob_return_defer(false);
}
#else
#error "TODO: dynamic raylib is not supported for TARGET_WIN64_MINGW"
// it cannot load the raylib dll if it not in the same folder as the executable
const char *libraylib_path = "./build/raylib.dll";

if (nob_needs_rebuild(libraylib_path, object_files.items, object_files.count)) {
nob_cmd_append(&cmd, "x86_64-w64-mingw32-gcc");
nob_cmd_append(&cmd, "-shared");
nob_cmd_append(&cmd, "-o", libraylib_path);
for (size_t i = 0; i < NOB_ARRAY_LEN(raylib_modules); ++i) {
const char *input_path = nob_temp_sprintf("%s/%s.o", build_path, raylib_modules[i]);
nob_cmd_append(&cmd, input_path);
}
nob_cmd_append(&cmd, "-lwinmm", "-lgdi32");
if (!nob_cmd_run_sync(cmd)) nob_return_defer(false);
}
#endif // MUSIALIZER_HOTRELOAD

defer:
Expand Down
66 changes: 54 additions & 12 deletions src/nob_win64_msvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,49 @@ bool build_musializer(void)
Nob_Cmd cmd = {0};
Nob_Procs procs = {0};

#ifdef MUSIALIZER_HOTRELOAD
nob_log(NOB_ERROR, "TODO: hotreloading is not supported on %s yet", NOB_ARRAY_GET(target_names, config.target));
nob_return_defer(false);
#else
cmd.count = 0;
nob_cmd_append(&cmd, "rc");
nob_cmd_append(&cmd, "/fo", "./build/musializer.res");
nob_cmd_append(&cmd, "./src/musializer.rc");
// NOTE: Do not change the order of commandline arguments to rc. Their argparser is weird.
if (!nob_cmd_run_sync(cmd)) nob_return_defer(false);
#ifdef MUSIALIZER_HOTRELOAD
procs.count = 0;
cmd.count = 0;
nob_cmd_append(&cmd, "cl.exe");
nob_cmd_append(&cmd, "/LD");
nob_cmd_append(&cmd, "/Fobuild\\", "/Fe./build/libplug.dll");
nob_cmd_append(&cmd, "/I", "./build/");
nob_cmd_append(&cmd, "/I", "./raylib/raylib-"RAYLIB_VERSION"/src/");
nob_cmd_append(&cmd,
"src/plug.c",
"src/ffmpeg_windows.c");
nob_cmd_append(&cmd,
"/link",
nob_temp_sprintf("/LIBPATH:build/raylib/%s", MUSIALIZER_TARGET_NAME),
"raylib.lib");
nob_cmd_append(&cmd, "Winmm.lib", "gdi32.lib", "User32.lib", "Shell32.lib");
nob_da_append(&procs, nob_cmd_run_async(cmd));

cmd.count = 0;
nob_cmd_append(&cmd, "cl.exe");
nob_cmd_append(&cmd, "/I", "./build/");
nob_cmd_append(&cmd, "/I", "./raylib/raylib-"RAYLIB_VERSION"/src/");
nob_cmd_append(&cmd, "/Fobuild\\", "/Febuild\\musializer.exe");
nob_cmd_append(&cmd,
"./src/musializer.c",
"./src/hotreload_windows.c",
);
nob_cmd_append(&cmd,
"/link",
"/SUBSYSTEM:WINDOWS",
"/entry:mainCRTStartup",
nob_temp_sprintf("/LIBPATH:build/raylib/%s", MUSIALIZER_TARGET_NAME),
"raylib.lib");
nob_cmd_append(&cmd, "Winmm.lib", "gdi32.lib", "User32.lib", "Shell32.lib", "./build/musializer.res");
nob_da_append(&procs, nob_cmd_run_async(cmd));
if (!nob_procs_wait(procs)) nob_return_defer(false);
#else
cmd.count = 0;
nob_cmd_append(&cmd, "cl.exe");
nob_cmd_append(&cmd, "/I", "./build/");
Expand All @@ -25,9 +58,7 @@ bool build_musializer(void)
nob_cmd_append(&cmd,
"./src/musializer.c",
"./src/plug.c",
"./src/ffmpeg_windows.c"
// TODO: building resource file is not implemented for TARGET_WIN64_MSVC
);
"./src/ffmpeg_windows.c");
nob_cmd_append(&cmd,
"/link",
"/SUBSYSTEM:WINDOWS",
Expand Down Expand Up @@ -73,6 +104,9 @@ bool build_raylib(void)
if (nob_needs_rebuild(output_path, &input_path, 1)) {
cmd.count = 0;
nob_cmd_append(&cmd, "cl.exe", "/DPLATFORM_DESKTOP");
#ifdef MUSIALIZER_HOTRELOAD
nob_cmd_append(&cmd, "/DBUILD_LIBTYPE_SHARED");
#endif
nob_cmd_append(&cmd, "/I", "./raylib/raylib-"RAYLIB_VERSION"/src/external/glfw/include");
nob_cmd_append(&cmd, "/c", input_path);
nob_cmd_append(&cmd, nob_temp_sprintf("/Fo%s", output_path));
Expand All @@ -83,7 +117,6 @@ bool build_raylib(void)
cmd.count = 0;

if (!nob_procs_wait(procs)) nob_return_defer(false);

#ifndef MUSIALIZER_HOTRELOAD
const char *libraylib_path = nob_temp_sprintf("%s/raylib.lib", build_path);
if (nob_needs_rebuild(libraylib_path, object_files.items, object_files.count)) {
Expand All @@ -96,10 +129,19 @@ bool build_raylib(void)
if (!nob_cmd_run_sync(cmd)) nob_return_defer(false);
}
#else
nob_log(NOB_WARNING, "TODO: dynamic raylib for %s is not supported yet", NOB_ARRAY_GET(target_names, config.target));
nob_return_defer(false);
if (nob_needs_rebuild("./build/raylib.dll", object_files.items, object_files.count)) {
nob_cmd_append(&cmd, "link.exe", "/DLL");
for (size_t i = 0; i < NOB_ARRAY_LEN(raylib_modules); ++i) {
const char *input_path = nob_temp_sprintf("%s/%s.obj", build_path, raylib_modules[i]);
nob_cmd_append(&cmd, input_path);
}
nob_cmd_append(&cmd, "Winmm.lib", "gdi32.lib", "User32.lib", "Shell32.lib");
nob_cmd_append(&cmd, nob_temp_sprintf("/IMPLIB:%s/raylib.lib", build_path));
nob_cmd_append(&cmd, "/OUT:./build/raylib.dll");
if (!nob_cmd_run_sync(cmd)) nob_return_defer(false);
}
#endif // MUSIALIZER_HOTRELOAD

defer:
nob_cmd_free(cmd);
nob_da_free(object_files);
Expand All @@ -115,4 +157,4 @@ bool build_dist(void)
nob_log(NOB_ERROR, "TODO: Creating distro for MSVC build is not implemented yet");
return false;
#endif // MUSIALIZER_HOTRELOAD
}
}
14 changes: 10 additions & 4 deletions src/plug.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ void *plug_load_resource(const char *file_path, size_t *size)
# define subcc(a, b) ((a)-(b))
#endif

#ifdef _WIN32
#define MUSIALIZER_PLUG __declspec(dllexport)
#else
#define MUSIALIZER_PLUG
#endif

typedef struct {
char *file_path;
Music music;
Expand Down Expand Up @@ -1727,7 +1733,7 @@ static void rendering_screen(void)
}
}

void plug_init(void)
MUSIALIZER_PLUG void plug_init(void)
{
p = malloc(sizeof(*p));
assert(p != NULL && "Buy more RAM lol");
Expand Down Expand Up @@ -1763,7 +1769,7 @@ void plug_init(void)
SetMasterVolume(0.5);
}

Plug *plug_pre_reload(void)
MUSIALIZER_PLUG Plug *plug_pre_reload(void)
{
for (size_t i = 0; i < p->tracks.count; ++i) {
Track *it = &p->tracks.items[i];
Expand All @@ -1773,7 +1779,7 @@ Plug *plug_pre_reload(void)
return p;
}

void plug_post_reload(Plug *pp)
MUSIALIZER_PLUG void plug_post_reload(Plug *pp)
{
p = pp;
for (size_t i = 0; i < p->tracks.count; ++i) {
Expand All @@ -1790,7 +1796,7 @@ void plug_post_reload(Plug *pp)
p->circle_power_location = GetShaderLocation(p->circle, "power");
}

void plug_update(void)
MUSIALIZER_PLUG void plug_update(void)
{
BeginDrawing();
ClearBackground(COLOR_BACKGROUND);
Expand Down

0 comments on commit fa92b42

Please sign in to comment.