From 025f9e632153c095cb24505c4163722d823a87ad Mon Sep 17 00:00:00 2001 From: Devyn Challman Date: Sat, 28 Mar 2026 18:35:03 -0700 Subject: add cross platform compatability --- Makefile | 40 ++++++++++++++++++++++++++++++----- client/net/net.c | 8 +++---- server/main.c | 15 +++++++------ shared/net_compat.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 shared/net_compat.h diff --git a/Makefile b/Makefile index 65ffe9d..e3d8520 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,25 @@ -CC = gcc-15 -CFLAGS = -MMD -MP -Wall -Wextra -pthread -LDFLAGS = -pthread +# Detect OS +UNAME_S := $(shell uname -s) +CFLAGS_COMMON = -MMD -MP -Wall -Wextra -I./shared + +# Compiler +ifeq ($(UNAME_S),Darwin) + CC = gcc-15 + CFLAGS = $(CFLAGS_COMMON) -pthread + LDFLAGS = -pthread +else ifeq ($(UNAME_S),Linux) + CC = gcc + CFLAGS = $(CFLAGS_COMMON) -pthread + LDFLAGS = -pthread +else + # Windows (MSYS2 MinGW) + CC = gcc + CFLAGS = $(CFLAGS_COMMON) + LDFLAGS = -lws2_32 +endif + +# Directories SERVER_BUILD = build/server SERVER_TARGET = bin/server SERVER_SRC = $(shell find server -name "*.c") @@ -11,9 +29,17 @@ CLIENT_BUILD = build/client CLIENT_TARGET = bin/client CLIENT_SRC = $(shell find client -name "*.c") CLIENT_OBJ = $(CLIENT_SRC:client/%.c=$(CLIENT_BUILD)/%.o) + +# Raylib via pkg-config (works on macOS, Linux, MSYS2) CLIENT_CFLAGS = $(CFLAGS) $(shell pkg-config --cflags raylib) CLIENT_LDFLAGS = $(LDFLAGS) $(shell pkg-config --libs raylib) +# Windows needs extra libs sometimes +ifeq ($(OS),Windows_NT) + CLIENT_LDFLAGS += -lopengl32 -lgdi32 -lwinmm +endif + +# Dependency files -include $(SERVER_OBJ:.o=.d) -include $(CLIENT_OBJ:.o=.d) @@ -24,15 +50,18 @@ all: $(SERVER_TARGET) $(CLIENT_TARGET) server: $(SERVER_TARGET) client: $(CLIENT_TARGET) +# Create bin directory bin: mkdir -p bin +# Link targets $(SERVER_TARGET): $(SERVER_OBJ) | bin - $(CC) $(LDFLAGS) $(SERVER_OBJ) -o $(SERVER_TARGET) + $(CC) $(SERVER_OBJ) -o $(SERVER_TARGET) $(LDFLAGS) $(CLIENT_TARGET): $(CLIENT_OBJ) | bin - $(CC) $(CLIENT_LDFLAGS) $(CLIENT_OBJ) -o $(CLIENT_TARGET) + $(CC) $(CLIENT_OBJ) -o $(CLIENT_TARGET) $(CLIENT_LDFLAGS) +# Compile rules $(SERVER_BUILD)/%.o: server/%.c mkdir -p $(dir $@) $(CC) $(CFLAGS) -c $< -o $@ @@ -41,5 +70,6 @@ $(CLIENT_BUILD)/%.o: client/%.c mkdir -p $(dir $@) $(CC) $(CLIENT_CFLAGS) -c $< -o $@ +# Clean clean: rm -rf build bin diff --git a/client/net/net.c b/client/net/net.c index be61104..7f6332e 100644 --- a/client/net/net.c +++ b/client/net/net.c @@ -1,13 +1,12 @@ #include #include -#include -#include -#include -#include #include #include "net.h" +#include "net_compat.h" void ServerConnect() { + net_init(); + int fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) @@ -23,4 +22,5 @@ void ServerConnect() { sendto(fd, buff, sizeof(buff), 0, (struct sockaddr *)&server, sizeof(server)); close(fd); + net_cleanup(); } diff --git a/server/main.c b/server/main.c index 789d392..6a5e5ba 100644 --- a/server/main.c +++ b/server/main.c @@ -1,12 +1,11 @@ #include #include -#include -#include -#include -#include #include +#include "net_compat.h" int main() { + net_init(); + int fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) @@ -22,6 +21,8 @@ int main() { err(EXIT_FAILURE, "bind failed"); } + set_nonblocking(fd); + time_t startTime = time(NULL); while (time(NULL) < startTime + 60) { @@ -29,13 +30,15 @@ int main() { socklen_t connectionLen = sizeof(connection); char buff[64]; - int size = recvfrom(fd, buff, sizeof(buff), MSG_DONTWAIT, + int size = recvfrom(fd, buff, sizeof(buff), 0, (struct sockaddr *)&connection, &connectionLen); if (size != -1) - printf("got a message\n"); + printf("message recievd\n"); } close(fd); + net_cleanup(); + return 0; } diff --git a/shared/net_compat.h b/shared/net_compat.h new file mode 100644 index 0000000..5e63e04 --- /dev/null +++ b/shared/net_compat.h @@ -0,0 +1,61 @@ +// net_compat.h +#pragma once + +#ifdef _WIN32 + #include + #include + #pragma comment(lib, "ws2_32.lib") + + // Map POSIX names to Winsock equivalents + #define close(s) closesocket(s) + #define MSG_DONTWAIT 0 // no direct equivalent, use non-blocking mode instead + + static inline int net_errno(void) { return WSAGetLastError(); } + #define NET_EAGAIN WSAEWOULDBLOCK + #define NET_EINTR WSAEINTR + + typedef int socklen_t; + + // err.h doesn't exist on Windows — provide a minimal shim + #include + #include + static inline void err(int code, const char *msg) { + fprintf(stderr, "%s: WSA error %d\n", msg, WSAGetLastError()); + exit(code); + } + + // Winsock requires explicit init/cleanup + static inline void net_init(void) { + WSADATA wsa; + if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) { + fprintf(stderr, "WSAStartup failed\n"); + exit(EXIT_FAILURE); + } + } + static inline void net_cleanup(void) { WSACleanup(); } + + // Non-blocking: Winsock uses ioctlsocket instead of MSG_DONTWAIT + #include + static inline void set_nonblocking(SOCKET s) { + u_long mode = 1; + ioctlsocket(s, FIONBIO, &mode); + } + +#else + #include + #include + #include + #include + #include + #include + + static inline void net_init(void) {} // no-op on POSIX + static inline void net_cleanup(void) {} // no-op on POSIX + static inline void set_nonblocking(int s) { + fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK); + } + + static inline int net_errno(void) { return errno; } + #define NET_EAGAIN EAGAIN + #define NET_EINTR EINTR +#endif -- cgit v1.2.3