Skip to content

Commit

Permalink
Windows build compatiblity
Browse files Browse the repository at this point in the history
  • Loading branch information
cbdevnet committed Aug 3, 2019
1 parent bbeade8 commit 20a6882
Show file tree
Hide file tree
Showing 20 changed files with 326 additions and 77 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
midimonster
midimonster.exe
libmmapi.a
*.swp
*.o
*.so
*.dll
23 changes: 21 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
.PHONY: all clean run sanitize backends full backends-full
.PHONY: all clean run sanitize backends windows full backends-full
OBJS = config.o backend.o plugin.o
PLUGINDIR = "\"./backends/\""
PLUGINDIR_W32 = "\"backends\\\\\""

SYSTEM := $(shell uname -s)

CFLAGS ?= -g -Wall
CFLAGS ?= -g -Wall -Wpedantic
# Hide all non-API symbols for export
CFLAGS += -fvisibility=hidden

#CFLAGS += -DDEBUG
midimonster: LDLIBS = -ldl
midimonster: CFLAGS += -DPLUGINS=$(PLUGINDIR)
Expand All @@ -21,6 +25,8 @@ all: midimonster backends

full: midimonster backends-full

windows: midimonster.exe

backends:
$(MAKE) -C backends

Expand All @@ -31,8 +37,21 @@ backends-full:
midimonster: midimonster.c portability.h $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $< $(OBJS) $(LDLIBS) -o $@

midimonster.exe: export CC = x86_64-w64-mingw32-gcc
#midimonster.exe: CFLAGS += -Wno-format
midimonster.exe: CFLAGS += -DPLUGINS=$(PLUGINDIR_W32) -Wno-format
midimonster.exe: LDLIBS = -lws2_32
midimonster.exe: LDFLAGS += -Wl,--out-implib,libmmapi.a
midimonster.exe: midimonster.c portability.h $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $< $(OBJS) $(LDLIBS) -o $@
# The windows build for backends requires the import library generated with the build,
# so the backends can't be a prerequisite for the executable...
$(MAKE) -C backends windows

clean:
$(RM) midimonster
$(RM) midimonster.exe
$(RM) libmmapi.a
$(RM) $(OBJS)
$(MAKE) -C backends clean

Expand Down
31 changes: 18 additions & 13 deletions backend.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#include <string.h>
#ifndef _WIN32
#define MM_API __attribute__((visibility ("default")))
#else
#define MM_API __attribute__((dllexport))
#endif
#include "midimonster.h"
#include "backend.h"

Expand Down Expand Up @@ -26,7 +31,7 @@ int backends_handle(size_t nfds, managed_fd* fds){
}
}

DBGPF("Notifying backend %s of %zu waiting FDs\n", backends[u].name, n);
DBGPF("Notifying backend %s of %lu waiting FDs\n", backends[u].name, n);
rv |= backends[u].process(n, fds);
if(rv){
fprintf(stderr, "Backend %s failed to handle input\n", backends[u].name);
Expand Down Expand Up @@ -59,28 +64,28 @@ int backends_notify(size_t nev, channel** c, channel_value* v){
}
}

DBGPF("Calling handler for instance %s with %zu events\n", instances[u]->name, n);
DBGPF("Calling handler for instance %s with %lu events\n", instances[u]->name, n);
rv |= instances[u]->backend->handle(instances[u], n, c, v);
}

return 0;
}

channel* mm_channel(instance* i, uint64_t ident, uint8_t create){
channel* MM_API mm_channel(instance* inst, uint64_t ident, uint8_t create){
size_t u;
for(u = 0; u < nchannels; u++){
if(channels[u]->instance == i && channels[u]->ident == ident){
DBGPF("Requested channel %zu on instance %s already exists, reusing\n", ident, i->name);
if(channels[u]->instance == inst && channels[u]->ident == ident){
DBGPF("Requested channel %lu on instance %s already exists, reusing\n", ident, inst->name);
return channels[u];
}
}

if(!create){
DBGPF("Requested unknown channel %zu on instance %s\n", ident, i->name);
DBGPF("Requested unknown channel %lu on instance %s\n", ident, inst->name);
return NULL;
}

DBGPF("Creating previously unknown channel %zu on instance %s\n", ident, i->name);
DBGPF("Creating previously unknown channel %lu on instance %s\n", ident, inst->name);
channel** new_chan = realloc(channels, (nchannels + 1) * sizeof(channel*));
if(!new_chan){
fprintf(stderr, "Failed to allocate memory\n");
Expand All @@ -95,12 +100,12 @@ channel* mm_channel(instance* i, uint64_t ident, uint8_t create){
return NULL;
}

channels[nchannels]->instance = i;
channels[nchannels]->instance = inst;
channels[nchannels]->ident = ident;
return channels[nchannels++];
}

instance* mm_instance(){
instance* MM_API mm_instance(){
instance** new_inst = realloc(instances, (ninstances + 1) * sizeof(instance*));
if(!new_inst){
//TODO free
Expand All @@ -118,7 +123,7 @@ instance* mm_instance(){
return instances[ninstances++];
}

instance* mm_instance_find(char* name, uint64_t ident){
instance* MM_API mm_instance_find(char* name, uint64_t ident){
size_t u;
backend* b = backend_match(name);
if(!b){
Expand All @@ -134,7 +139,7 @@ instance* mm_instance_find(char* name, uint64_t ident){
return NULL;
}

int mm_backend_instances(char* name, size_t* ninst, instance*** inst){
int MM_API mm_backend_instances(char* name, size_t* ninst, instance*** inst){
backend* b = backend_match(name);
size_t n = 0, u;
//count number of affected instances
Expand Down Expand Up @@ -177,7 +182,7 @@ void instances_free(){
void channels_free(){
size_t u;
for(u = 0; u < nchannels; u++){
DBGPF("Destroying channel %zu on instance %s\n", channels[u]->ident, channels[u]->instance->name);
DBGPF("Destroying channel %lu on instance %s\n", channels[u]->ident, channels[u]->instance->name);
if(channels[u]->impl){
channels[u]->instance->backend->channel_free(channels[u]);
}
Expand Down Expand Up @@ -232,7 +237,7 @@ struct timeval backend_timeout(){
return tv;
}

int mm_backend_register(backend b){
int MM_API mm_backend_register(backend b){
if(!backend_match(b.name)){
backends = realloc(backends, (nbackends + 1) * sizeof(backend));
if(!backends){
Expand Down
9 changes: 8 additions & 1 deletion backend.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
#include <sys/types.h>

/* Internal API */
int backends_handle(size_t nfds, managed_fd* fds);
int backends_notify(size_t nev, channel** c, channel_value* v);

backend* backend_match(char* name);
instance* instance_match(char* name);
struct timeval backend_timeout();
int backends_start();
int backends_stop();
void instances_free();
void channels_free();

/* Backend API */
channel* MM_API mm_channel(instance* inst, uint64_t ident, uint8_t create);
instance* MM_API mm_instance();
instance* MM_API mm_instance_find(char* name, uint64_t ident);
int MM_API mm_backend_instances(char* name, size_t* ninst, instance*** inst);
int MM_API mm_backend_register(backend b);
26 changes: 24 additions & 2 deletions backends/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
.PHONY: all clean full
OPTIONAL_BACKENDS = ola.so
WINDOWS_BACKENDS = loopback.dll artnet.dll osc.dll sacn.dll
LINUX_BACKENDS = midi.so evdev.so
BACKENDS = artnet.so osc.so loopback.so sacn.so lua.so
BACKEND_LIB = libmmbackend.o

SYSTEM := $(shell uname -s)

CFLAGS += -g -fPIC -I../
CFLAGS += -g -fPIC -I../ -Wall -Wpedantic
CPPFLAGS += -g -fPIC -I../
LDFLAGS += -shared

Expand All @@ -20,8 +21,17 @@ LDFLAGS += -undefined dynamic_lookup
endif

artnet.so: ADDITIONAL_OBJS += $(BACKEND_LIB)
artnet.dll: ADDITIONAL_OBJS += $(BACKEND_LIB)
artnet.dll: LDLIBS += -lws2_32

osc.so: ADDITIONAL_OBJS += $(BACKEND_LIB)
osc.dll: ADDITIONAL_OBJS += $(BACKEND_LIB)
osc.dll: LDLIBS += -lws2_32

sacn.so: ADDITIONAL_OBJS += $(BACKEND_LIB)
sacn.dll: ADDITIONAL_OBJS += $(BACKEND_LIB)
sacn.dll: LDLIBS += -lws2_32

midi.so: LDLIBS = -lasound
evdev.so: CFLAGS += $(shell pkg-config --cflags libevdev)
evdev.so: LDLIBS = $(shell pkg-config --libs libevdev)
Expand All @@ -33,12 +43,24 @@ lua.so: LDLIBS += $(shell pkg-config --libs lua5.3)
%.so :: %.c %.h $(BACKEND_LIB)
$(CC) $(CFLAGS) $(LDLIBS) $< $(ADDITIONAL_OBJS) -o $@ $(LDFLAGS)

%.dll :: %.c %.h $(BACKEND_LIB)
$(CC) $(CFLAGS) $< $(ADDITIONAL_OBJS) -o $@ $(LDFLAGS) $(LDLIBS)

%.so :: %.cpp %.h
$(CXX) $(CPPFLAGS) $(LDLIBS) $< $(ADDITIONAL_OBJS) -o $@ $(LDFLAGS)

all: $(BACKEND_LIB) $(BACKENDS)

../libmmapi.a:
$(MAKE) -C ../ midimonster.exe

windows: export CC = x86_64-w64-mingw32-gcc
windows: LDLIBS += -lmmapi
windows: LDFLAGS += -L../
windows: CFLAGS += -Wno-format -Wno-pointer-sign
windows: ../libmmapi.a $(BACKEND_LIB) $(WINDOWS_BACKENDS)

full: $(BACKEND_LIB) $(BACKENDS) $(OPTIONAL_BACKENDS)

clean:
$(RM) $(BACKEND_LIB) $(BACKENDS) $(OPTIONAL_BACKENDS)
$(RM) $(BACKEND_LIB) $(BACKENDS) $(OPTIONAL_BACKENDS) $(WINDOWS_BACKENDS)
16 changes: 10 additions & 6 deletions backends/artnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <errno.h>

#include "libmmbackend.h"

#include "artnet.h"

#define MAX_FDS 255
#define BACKEND_NAME "artnet"

Expand Down Expand Up @@ -32,7 +32,7 @@ static int artnet_listener(char* host, char* port){
return -1;
}

fprintf(stderr, "ArtNet backend interface %zu bound to %s port %s\n", artnet_fds, host, port);
fprintf(stderr, "ArtNet backend interface %lu bound to %s port %s\n", artnet_fds, host, port);
artnet_fd[artnet_fds].fd = fd;
artnet_fd[artnet_fds].output_instances = 0;
artnet_fd[artnet_fds].output_instance = NULL;
Expand Down Expand Up @@ -212,7 +212,7 @@ static int artnet_transmit(instance* inst){
};
memcpy(frame.data, data->data.out, 512);

if(sendto(artnet_fd[data->fd_index].fd, &frame, sizeof(frame), 0, (struct sockaddr*) &data->dest_addr, data->dest_len) < 0){
if(sendto(artnet_fd[data->fd_index].fd, (uint8_t*) &frame, sizeof(frame), 0, (struct sockaddr*) &data->dest_addr, data->dest_len) < 0){
fprintf(stderr, "Failed to output ArtNet frame for instance %s: %s\n", inst->name, strerror(errno));
}

Expand All @@ -230,7 +230,7 @@ static int artnet_set(instance* inst, size_t num, channel** c, channel_value* v)
artnet_instance_data* data = (artnet_instance_data*) inst->impl;

if(!data->dest_len){
fprintf(stderr, "ArtNet instance %s not enabled for output (%zu channel events)\n", inst->name, num);
fprintf(stderr, "ArtNet instance %s not enabled for output (%lu channel events)\n", inst->name, num);
return 0;
}

Expand Down Expand Up @@ -295,7 +295,7 @@ static inline int artnet_process_frame(instance* inst, artnet_pkt* frame){
}

if(!chan){
fprintf(stderr, "Active channel %zu on %s not known to core\n", p, inst->name);
fprintf(stderr, "Active channel %lu on %s not known to core\n", p, inst->name);
return 1;
}

Expand Down Expand Up @@ -367,7 +367,11 @@ static int artnet_handle(size_t num, managed_fd* fds){
}
} while(bytes_read > 0);

#ifdef _WIN32
if(bytes_read < 0 && WSAGetLastError() != WSAEWOULDBLOCK){
#else
if(bytes_read < 0 && errno != EAGAIN){
#endif
fprintf(stderr, "ArtNet failed to receive data: %s\n", strerror(errno));
}

Expand Down Expand Up @@ -438,7 +442,7 @@ static int artnet_start(){
}
}

fprintf(stderr, "ArtNet backend registering %zu descriptors to core\n", artnet_fds);
fprintf(stderr, "ArtNet backend registering %lu descriptors to core\n", artnet_fds);
for(u = 0; u < artnet_fds; u++){
if(mm_manage_fd(artnet_fd[u].fd, BACKEND_NAME, 1, (void*) u)){
goto bail;
Expand Down
2 changes: 2 additions & 0 deletions backends/artnet.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#ifndef _WIN32
#include <sys/socket.h>
#endif
#include "midimonster.h"

int init();
Expand Down
12 changes: 10 additions & 2 deletions backends/libmmbackend.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ int mmbackend_parse_sockaddr(char* host, char* port, struct sockaddr_storage* ad
}

int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener){
int fd = -1, status, yes = 1, flags;
int fd = -1, status, yes = 1;
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = socktype,
Expand Down Expand Up @@ -106,12 +106,20 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener){
}

//set nonblocking
flags = fcntl(fd, F_GETFL, 0);
#ifdef _WIN32
u_long mode = 1;
if(ioctlsocket(fd, FIONBIO, &mode) != NO_ERROR){
closesocket(fd);
return 1;
}
#else
int flags = fcntl(fd, F_GETFL, 0);
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0){
fprintf(stderr, "Failed to set socket nonblocking\n");
close(fd);
return -1;
}
#endif

return fd;
}
6 changes: 6 additions & 0 deletions backends/libmmbackend.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#ifdef _WIN32
#include <ws2tcpip.h>
//#define close closesocket
#else
#include <sys/socket.h>
#include <netdb.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "../portability.h"

/* Parse spec as host specification in the form
* host port
Expand Down
4 changes: 0 additions & 4 deletions backends/lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ static int lua_callback_output(lua_State* interpreter){

static int lua_callback_interval(lua_State* interpreter){
size_t n = 0;
instance* inst = NULL;
lua_instance_data* data = NULL;
uint64_t interval = 0;
int reference = LUA_NOREF;

Expand All @@ -174,8 +172,6 @@ static int lua_callback_interval(lua_State* interpreter){
//get instance pointer from registry
lua_pushstring(interpreter, LUA_REGISTRY_KEY);
lua_gettable(interpreter, LUA_REGISTRYINDEX);
inst = (instance*) lua_touserdata(interpreter, -1);
data = (lua_instance_data*) inst->impl;

//fetch and round the interval
interval = luaL_checkinteger(interpreter, 2);
Expand Down
Loading

0 comments on commit 20a6882

Please sign in to comment.