aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2019-11-07 18:44:19 +0100
committercbdev <cb@cbcdn.com>2019-11-07 18:44:19 +0100
commit350f0d2d2eaff5f0d57b09857102e2df1e96d733 (patch)
treefe81a48535d700195034e9173018c9a9a63d02d0
parent6c75f07260639fd2bc6d328d5f00c72ab4382fa8 (diff)
downloadmidimonster-350f0d2d2eaff5f0d57b09857102e2df1e96d733.tar.gz
midimonster-350f0d2d2eaff5f0d57b09857102e2df1e96d733.tar.bz2
midimonster-350f0d2d2eaff5f0d57b09857102e2df1e96d733.zip
Makefile install target and packaging instructions (Fixes #28)
-rw-r--r--Makefile22
-rw-r--r--README.md23
-rw-r--r--backends/lua.md5
-rw-r--r--backends/maweb.c2
-rw-r--r--backends/winmidi.c2
-rw-r--r--config.c38
-rw-r--r--configs/flying-faders.cfg2
-rw-r--r--configs/lua.cfg2
-rw-r--r--midimonster.h13
-rw-r--r--plugin.c12
10 files changed, 102 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index 2d88c49..5a83a2d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,7 @@
-.PHONY: all clean run sanitize backends windows full backends-full
+.PHONY: all clean run sanitize backends windows full backends-full install
OBJS = config.o backend.o plugin.o
-PLUGINDIR = "\"./backends/\""
-PLUGINDIR_W32 = "\"backends\\\\\""
+PREFIX ?= /usr
SYSTEM := $(shell uname -s)
CFLAGS ?= -g -Wall -Wpedantic
@@ -11,7 +10,6 @@ CFLAGS += -fvisibility=hidden
#CFLAGS += -DDEBUG
midimonster: LDLIBS = -ldl
-midimonster: CFLAGS += -DPLUGINS=$(PLUGINDIR)
# Work around strange linker passing convention differences in Linux and OSX
ifeq ($(SYSTEM),Linux)
@@ -21,6 +19,14 @@ ifeq ($(SYSTEM),Darwin)
midimonster: LDFLAGS += -Wl,-export_dynamic
endif
+# Allow overriding the locations for backend plugins and default configuration
+ifdef DEFAULT_CFG
+midimonster: CFLAGS += -DDEFAULT_CFG=\"$(DEFAULT_CFG)\"
+endif
+ifdef PLUGINS
+midimonster: CFLAGS += -DPLUGINS=\"$(PLUGINS)\"
+endif
+
all: midimonster backends
full: midimonster backends-full
@@ -39,7 +45,7 @@ midimonster: midimonster.c portability.h $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $< $(OBJS) $(LDLIBS) -o $@
midimonster.exe: export CC = x86_64-w64-mingw32-gcc
-midimonster.exe: CFLAGS += -DPLUGINS=$(PLUGINDIR_W32) -Wno-format
+midimonster.exe: CFLAGS += -Wno-format
midimonster.exe: LDLIBS = -lws2_32
midimonster.exe: LDFLAGS += -Wl,--out-implib,libmmapi.a
midimonster.exe: midimonster.c portability.h $(OBJS)
@@ -55,6 +61,12 @@ clean:
run:
valgrind --leak-check=full --show-leak-kinds=all ./midimonster
+install:
+ install -d "$(DESTDIR)$(PREFIX)/bin"
+ install -d "$(DESTDIR)$(PREFIX)/lib/midimonster"
+ install -m 0755 midimonster "$(DESTDIR)$(PREFIX)/bin"
+ install -m 0755 backends/*.so "$(DESTDIR)$(PREFIX)/lib/midimonster"
+
sanitize: export CC = clang
sanitize: export CFLAGS += -g -Wall -Wpedantic -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer
sanitize: midimonster backends
diff --git a/README.md b/README.md
index 130945a..c31f16c 100644
--- a/README.md
+++ b/README.md
@@ -156,6 +156,16 @@ be used to build a subset of the backends as well as the core.
For Linux and OSX, just running `make` in the source directory should do the trick.
+The build process accepts the following parameters, either from the environment or
+as arguments to the `make` invocation:
+
+| Target | Parameter | Default value | Description |
+|---------------|-----------------------|-------------------------------|-------------------------------|
+| build targets | `DEFAULT_CFG` | `monster.cfg` | Default configuration file |
+| build targets | `PLUGINS` | Linux/OSX: `./backends/`, Windows: `backends\` | Backend plugin library path |
+| `install` | `DESTDIR` | empty | Destination directory for packaging builds |
+| `install` | `PREFIX` | `/usr` | Install prefix for binaries |
+
Some backends have been marked as optional as they require rather large additional software to be installed,
for example the `ola` backend. To create a build including these, run `make full`.
@@ -163,6 +173,19 @@ To build for Windows, you still need to compile on a Linux machine.
Install the crosscompiler package listed above and run `make windows`.
This will build `midimonster.exe` as well as a set of backends as DLL files.
+For system-wide install or packaging builds, the following steps are recommended:
+
+```
+export PREFIX=/usr
+export PLUGINS=$PREFIX/lib/midimonster
+export DEFAULT_CFG=/etc/midimonster.cfg
+make
+make install
+```
+
+Depending on your configuration of `DESTDIR`, the `make install` step may require root privileges to
+install the binaries to the appropriate destinations.
+
## Development
The architecture is split into the `midimonster` core, handling mapping
diff --git a/backends/lua.md b/backends/lua.md
index 6ad5c2a..f38e189 100644
--- a/backends/lua.md
+++ b/backends/lua.md
@@ -43,7 +43,7 @@ The `lua` backend does not take any global configuration.
| Option | Example value | Default value | Description |
|---------------|-----------------------|-----------------------|-----------------------|
-| `script` | `script.lua` | none | Lua source file |
+| `script` | `script.lua` | none | Lua source file (relative to configuration file)|
A single instance may have multiple `source` options specified, which will all be read cumulatively.
@@ -64,6 +64,3 @@ Using these names as arguments to the output and value interface functions works
Output values will not trigger corresponding input event handlers unless the channel is mapped
back in the MIDIMonster configuration.
-
-The path to the Lua source files is relative to the current working directory. This may lead
-to problems when copying configuration between installations.
diff --git a/backends/maweb.c b/backends/maweb.c
index c98d04b..57d04ae 100644
--- a/backends/maweb.c
+++ b/backends/maweb.c
@@ -470,7 +470,7 @@ static int maweb_request_playbacks(instance* inst){
offsets[0] = offsets[1] = offsets[2] = 1;
page_index = data->channel[channel].page;
//poll logic differs between the consoles because reasons
- //dont quote me on this section
+ //don't quote me on this section
if(data->peer_type == peer_dot2){
//blocks 0, 100 & 200 have 21 execs and need to be queried from fader view
view = (data->channel[channel].index >= 300) ? 3 : 2;
diff --git a/backends/winmidi.c b/backends/winmidi.c
index de7d867..d6bc0bc 100644
--- a/backends/winmidi.c
+++ b/backends/winmidi.c
@@ -84,7 +84,7 @@ static int winmidi_configure_instance(instance* inst, char* option, char* value)
}
if(!strcmp(option, "write")){
if(data->write){
- fprintf(stderr, "winmidi instance %s already connected to an otput device\n", inst->name);
+ fprintf(stderr, "winmidi instance %s already connected to an output device\n", inst->name);
return 1;
}
data->write = strdup(value);
diff --git a/config.c b/config.c
index f4d928e..ddee720 100644
--- a/config.c
+++ b/config.c
@@ -1,5 +1,7 @@
#include <string.h>
#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
#include "midimonster.h"
#include "config.h"
#include "backend.h"
@@ -310,16 +312,45 @@ done:
return rv;
}
-int config_read(char* cfg_file){
+int config_read(char* cfg_filepath){
int rv = 1;
size_t line_alloc = 0;
ssize_t status;
map_type mapping_type = map_rtl;
char* line_raw = NULL, *line, *separator;
- FILE* source = fopen(cfg_file, "r");
+
+ //create heap copy of file name because original might be in readonly memory
+ char* source_dir = strdup(cfg_filepath), *source_file = NULL;
+ #ifdef _WIN32
+ char path_separator = '\\';
+ #else
+ char path_separator = '/';
+ #endif
+
+ if(!source_dir){
+ fprintf(stderr, "Failed to allocate memory\n");
+ return 1;
+ }
+
+ //change working directory to the one containing the configuration file so relative paths work as expected
+ source_file = strrchr(source_dir, path_separator);
+ if(source_file){
+ *source_file = 0;
+ source_file++;
+ if(chdir(source_dir)){
+ fprintf(stderr, "Failed to change to configuration file directory %s: %s\n", source_dir, strerror(errno));
+ goto bail;
+ }
+ }
+ else{
+ source_file = source_dir;
+ }
+
+ FILE* source = fopen(source_file, "r");
+
if(!source){
fprintf(stderr, "Failed to open configuration file for reading\n");
- return 1;
+ goto bail;
}
for(status = getline(&line_raw, &line_alloc, source); status >= 0; status = getline(&line_raw, &line_alloc, source)){
@@ -459,6 +490,7 @@ int config_read(char* cfg_file){
rv = 0;
bail:
+ free(source_dir);
fclose(source);
free(line_raw);
return rv;
diff --git a/configs/flying-faders.cfg b/configs/flying-faders.cfg
index 4197581..d331f38 100644
--- a/configs/flying-faders.cfg
+++ b/configs/flying-faders.cfg
@@ -13,7 +13,7 @@ dest = learn@9000
/1/xy = ff 0.0 1.0 0.0 1.0
[lua generator]
-script = configs/flying-faders.lua
+script = flying-faders.lua
[map]
diff --git a/configs/lua.cfg b/configs/lua.cfg
index af17496..098c0f1 100644
--- a/configs/lua.cfg
+++ b/configs/lua.cfg
@@ -13,7 +13,7 @@ axis.ABS_X = 34300 0 65535 255 4095
axis.ABS_Y = 34300 0 65535 255 4095
[lua lua]
-script = configs/demo.lua
+script = demo.lua
[artnet art]
universe = 0
diff --git a/midimonster.h b/midimonster.h
index 491cc11..b05326c 100644
--- a/midimonster.h
+++ b/midimonster.h
@@ -33,7 +33,18 @@
#include "portability.h"
/* Default configuration file name to read when no other is specified */
-#define DEFAULT_CFG "monster.cfg"
+#ifndef DEFAULT_CFG
+ #define DEFAULT_CFG "monster.cfg"
+#endif
+
+/* Default backend plugin location */
+#ifndef PLUGINS
+ #ifndef _WIN32
+ #define PLUGINS "./backends/"
+ #else
+ #define PLUGINS "backends\\"
+ #endif
+#endif
/* Forward declare some of the structs so we can use them in each other */
struct _channel_value;
diff --git a/plugin.c b/plugin.c
index dd99041..a14baff 100644
--- a/plugin.c
+++ b/plugin.c
@@ -24,13 +24,21 @@ static int plugin_attach(char* path, char* file){
plugin_init init = NULL;
void* handle = NULL;
char* lib = NULL;
+ #ifdef _WIN32
+ char* path_separator = "\\";
+ #else
+ char* path_separator = "/";
+ #endif
- lib = calloc(strlen(path) + strlen(file) + 1, sizeof(char));
+ lib = calloc(strlen(path) + strlen(file) + 2, sizeof(char));
if(!lib){
fprintf(stderr, "Failed to allocate memory\n");
return 1;
}
- snprintf(lib, strlen(path) + strlen(file) + 1, "%s%s", path, file);
+ snprintf(lib, strlen(path) + strlen(file) + 2, "%s%s%s",
+ path,
+ (path[strlen(path)] == path_separator[0]) ? "" : path_separator,
+ file);
handle = dlopen(lib, RTLD_NOW);
if(!handle){