mruby-zest / mruby-zest-build

Root repo for mruby-zest containing links to all submodules
GNU Lesser General Public License v2.1
19 stars 24 forks source link

Allow to build static libzest.a #19

Open falkTX opened 5 years ago

falkTX commented 5 years ago

The target is to have zynaddsubfx ui object file to be self-contained, not relying on finding libzest as shared library. I have been trying to do this recently, but failing always at some point.

I am able to build the test-libversion statically, the issue right now is how to reliably create a libzest.a. Some files created by mruby have the same base filename, which messes up things when creating an "ar" file. I tried creating a all-in-one object (using ld -r) but that lead to missing symbols somehow.

So I am leaving the request here for a static build.

falkTX commented 5 years ago

For reference, this is what I have so far.

--- mruby-zest-build-3.0.5.orig/Makefile
+++ mruby-zest-build-3.0.5/Makefile
@@ -1,22 +1,23 @@
 UV_DIR    = libuv-v1.9.1
 UV_FILE   = $(UV_DIR).tar.gz
 UV_URL    = http://dist.libuv.org/dist/v1.9.1/$(UV_FILE)
-    
+
+CFLAGS += -I ../../deps/$(UV_DIR)/include

 all:
-   ruby ./rebuild-fcache.rb
-   cd deps/nanovg/src   && $(CC) nanovg.c -c -fPIC
+   ruby ./rebuild-fcache.rb
+   cd deps/nanovg/src   && $(CC) $(CFLAGS) nanovg.c -c -fPIC
    $(AR) rc deps/libnanovg.a deps/nanovg/src/*.o
-#  cd deps/pugl         && python2 ./waf configure --no-cairo --static
-   cd deps/pugl         && python2 ./waf configure --no-cairo --static --debug
+   cd deps/pugl         && python2 ./waf configure --no-cairo --static
    cd deps/pugl         && python2 ./waf
-   cd src/osc-bridge    && CFLAGS="-I ../../deps/$(UV_DIR)/include " make lib
+   cd src/osc-bridge    && make lib
    cd mruby             && MRUBY_CONFIG=../build_config.rb rake
-   $(CC) -shared -o libzest.so `find mruby/build/host -type f | grep -e "\.o$$" | grep -v bin` ./deps/libnanovg.a \
+   $(CC) test-libversion.c `find mruby/build/host -type f | grep -e "\.o$$" | grep -v bin` ./deps/libnanovg.a \
        ./deps/libnanovg.a \
        src/osc-bridge/libosc-bridge.a \
-       ./deps/$(UV_DIR)/.libs/libuv.a  -lm -lX11 -lGL -lpthread
-   $(CC) test-libversion.c deps/pugl/build/libpugl-0.a -ldl -o zest -lX11 -lGL -lpthread -I deps/pugl -std=gnu99
+       ./deps/$(UV_DIR)/.libs/libuv.a \
+        ./deps/pugl/build/libpugl-0.a \
+       -I deps/pugl -std=gnu99 -o zest -lm -lX11 -lGL -lpthread $(CFLAGS) $(LDFLAGS) -o zest

 osx:
    ruby ./rebuild-fcache.rb
@@ -163,11 +164,9 @@ pack:
    cp src/mruby-zest/example/*         package/qml/
    cp src/osc-bridge/schema/test.json  package/schema/
    cp deps/nanovg/example/*.ttf        package/font/
-   cp mruby/bin/mruby                  package/
-   cp libzest.so                       package/
-   cp zest                             package/
+   cp zest                             package/zyn-fusion
    cp completions/zyn-fusion           package/completions
-   echo 'Version 3.0.0-pre '       >>  package/VERSION
+   echo 'Version $(VERSON) '       >>  package/VERSION
    echo 'built on: '               >>  package/VERSION
    echo `date`                     >>  package/VERSION

--- mruby-zest-build-3.0.5.orig/src/mruby-widget-lib/src/api.c
+++ mruby-zest-build-3.0.5/src/mruby-widget-lib/src/api.c
@@ -6,17 +6,13 @@
 #include "../../../deps/pugl/pugl/pugl.h"
 #include <locale.h>
 #ifndef WIN32
-#define __USE_GNU
-#include <dlfcn.h>

 const char *zest_search_path = 0;
 static void
 check_error(mrb_state *mrb);

 char *get_search_path(void) {
-    Dl_info dl_info;
-    dladdr((void*)check_error, &dl_info);
-    return strdup(dl_info.dli_fname);
+    return 0;
 }
 #define EXPORT __attribute__ ((visibility ("default")))
 #else
@@ -99,10 +95,8 @@ zest_open(char *address)

     //Verify that the search path is usable
-    char *path = get_search_path();
+    const char *path = "/usr/lib/zynaddsubfx/";
     if(!dev_mode) {
-        if(strstr(path, "libzest"))
-            strstr(path, "libzest")[0] = 0;
         char path2[256];
         snprintf(path2, sizeof(path2), "%s%s", path, "./qml/MainWindow.qml");
         FILE *f = fopen(path2, "r");
@@ -121,7 +115,7 @@ zest_open(char *address)
     printf("[INFO:Zyn] Starting Zyn-Fusion Demo...\n");
 #else
     printf("[INFO:Zyn] Starting Zyn-Fusion\n");
-    printf("[INFO:Zyn] Thanks for supporting the developement of this project\n");
+    printf("[INFO:Zyn] This is a free, pre-compiled package from KXStudio; please consider supporting the developement of Zyn-Fusion\n");
 #endif

     //Create mruby interpreter
--- mruby-zest-build-3.0.5.orig/test-libversion.c
+++ mruby-zest-build-3.0.5/test-libversion.c
@@ -16,26 +16,25 @@
 #include "deps/pugl/pugl/pugl.h"

 typedef void *zest_t;
-struct zest_handles {
-    zest_t *(*zest_open)(const char *);
-    void (*zest_close)(zest_t*);
-    void (*zest_setup)(zest_t*);
-    void (*zest_draw)(zest_t*);
-    void (*zest_motion)(zest_t*, int x, int y, int mod);
-    void (*zest_scroll)(zest_t*, int x, int y, int dx, int dy, int mod);
-    void (*zest_mouse)(zest_t *z, int button, int action, int x, int y, int mod);
-    void (*zest_key)(zest_t *, const char *key, int press);
-    void (*zest_special)(zest_t *, int key, int press);
-    void (*zest_resize)(zest_t *, int w, int h);
-    int  (*zest_tick)(zest_t*);
-    int  (*zest_exit)(zest_t*);
-    void (*zest_set_option)(zest_t*, const char *key, const char *value);
-    void (*zest_dnd_drop)(zest_t*, const char*);
-    const char* (*zest_dnd_pick)(zest_t*);
-    const char* (*zest_get_remote_url)(zest_t*);
-
-    void (*zest_script)(zest_t *, const char *str);
+extern zest_t* zest_open(const char *);
+extern void zest_close(zest_t*);
+extern void zest_setup(zest_t*);
+extern void zest_draw(zest_t*);
+extern void zest_motion(zest_t*, int x, int y, int mod);
+extern void zest_scroll(zest_t*, int x, int y, int dx, int dy, int mod);
+extern void zest_mouse(zest_t*, int button, int press, int x, int y, int mod);
+extern void zest_key(zest_t *, const char *key, int press);
+extern void zest_special(zest_t *, int key, int press);
+extern void zest_resize(zest_t *, int w, int h);
+extern int  zest_tick(zest_t*);
+extern int  zest_exit(zest_t*);
+extern void zest_set_option(zest_t*, const char *key, const char *value);
+extern void zest_dnd_drop(zest_t*, const char*);
+extern const char* zest_dnd_pick(zest_t*);
+extern const char* zest_get_remote_url(zest_t*);
+extern void zest_script(zest_t *, const char *str);

+struct zest_handles {
     zest_t *zest;
     int do_exit;

@@ -75,7 +74,7 @@ onSpecial(PuglView* view, bool press, Pu
     if(!z || !z->zest)
         return;

-    z->zest_special(z->zest, key, press);
+    zest_special(z->zest, key, press);
 }

 static void
@@ -85,7 +84,7 @@ onMotion(PuglView* view, int x, int y, i
     if(!z || !z->zest)
         return;

-    z->zest_motion(z->zest, x, y, mod);
+    zest_motion(z->zest, x, y, mod);
 }

 static void
@@ -97,7 +96,7 @@ onMouse(PuglView* view, int button, bool

     if(z->dnd_source_status == PuglNotDndSource &&
        z->dnd_target_status == PuglNotDndTarget) {
-        z->zest_mouse(z->zest, button, press, x, y, mod);
+        zest_mouse(z->zest, button, press, x, y, mod);
     }
 }

@@ -108,7 +107,7 @@ onScroll(PuglView* view, int x, int y, f
     if(!z || !z->zest)
         return;

-    z->zest_scroll(z->zest, x, y, dx, dy, mod);
+    zest_scroll(z->zest, x, y, dx, dy, mod);
 }

 static void
@@ -128,7 +127,7 @@ onReshape(PuglView* view, int width, int
     if(!z || !z->zest)
         return;

-    z->zest_resize(z->zest, width, height);
+    zest_resize(z->zest, width, height);
 }

 float target_animation_fps = 30.0f;
@@ -143,27 +142,27 @@ onDisplay(PuglView* view)
         return;
     if(!z->zest) {
         printf("[INFO:Zyn] zest_open()\n");
-        z->zest = z->zest_open(osc_path ? osc_path : "osc.udp://127.0.0.1:1337");
+        z->zest = zest_open(osc_path ? osc_path : "osc.udp://127.0.0.1:1337");
         printf("[INFO:Zyn] zest_setup()\n");
-        z->zest_setup(z->zest);
+        zest_setup(z->zest);

         printf("[DEBUG:Zyn] setting up animation fps\n");
         char fps[128] = {0};
         snprintf(fps, sizeof(fps)-1, "%f", target_animation_fps);
-        z->zest_set_option(z->zest, "animation_fps", fps);
+        zest_set_option(z->zest, "animation_fps", fps);

         if(script_data)
-            z->zest_script(z->zest, script_data);
+            zest_script(z->zest, script_data);
     }

-    z->zest_draw(z->zest);
+    zest_draw(z->zest);
 }

 static void
 onUtf8KeyEvent(PuglView* view, char* utf8, bool press)
 {
     struct zest_handles *z = puglGetHandle(view);
-    z->zest_key(z->zest, utf8, press);
+    zest_key(z->zest, utf8, press);
 }

 // convert pugl-new-style event structs to pugl-old-style event callbacks
@@ -302,7 +301,7 @@ onDndSourceDrag(PuglView* view, int x, i
     struct zest_handles *z = puglGetHandle(view);
     if(!z || !z->zest)
         return 0;
-    const char* widget_path = z->zest_dnd_pick(z->zest);
+    const char* widget_path = zest_dnd_pick(z->zest);
     if(widget_path && *widget_path) {
         *z->dnd_source_widget_path = 0;
         strncat(z->dnd_source_widget_path, widget_path,
@@ -350,7 +349,7 @@ onDndSourceProvideData(PuglView* view, i
     *offered_property = 0;
     // e.g. osc.udp://127.0.0.1:17070/path/to/port
     int res = snprintf(offered_property, sz-1, "automatable_model:%s%s",
-             z->zest_get_remote_url(z->zest), z->dnd_source_widget_path);
+             zest_get_remote_url(z->zest), z->dnd_source_widget_path);
     assert(res < sz);

     int len = 1 + strlen(offered_property);
@@ -519,7 +518,7 @@ onDndTargetReceiveData(PuglView* view, i
             struct zest_handles *z = puglGetHandle(view);
             if(!z || !z->zest)
                 return;
-            z->zest_dnd_drop(z->zest, filename);
+            zest_dnd_drop(z->zest, filename);
         }
         else
             fprintf(stderr, "Unable to read file \"%s\"\n", filename);
@@ -648,69 +647,12 @@ int main(int argc, char **argv)
     }

-#ifdef WIN32
-    void *handle = LoadLibrary("./libzest.dll");
-#else
-    void *handle = dlopen("./libzest.so", RTLD_LAZY);
-    if(!handle)
-        handle = dlopen("libzest.so", RTLD_LAZY);
-    if(!handle)
-        handle = dlopen("/opt/zyn-fusion/libzest.so", RTLD_LAZY);
-#endif
-    if(!handle) {
-        printf("[ERROR] Cannot Open libzest.so\n");
-        return 1;
-        //printf("[ERROR] '%s'\n", dlerror());
-    }
     struct zest_handles z = {0};
-#ifdef WIN32
-#define get(x) z.zest_##x = (void*) GetProcAddress(handle, "zest_" #x)
-#else
-#define get(x) z.zest_##x = (void*) dlsym(handle, "zest_" #x)
-#endif
-
-    get(open);
-    get(setup);
-    get(close);
-    get(draw);
-    get(tick);
-    get(motion);
-    get(scroll);
-    get(mouse);
-    get(key);
-    get(special);
-    get(resize);
-    get(exit);
-    get(set_option);
-    get(dnd_drop);
-    get(dnd_pick);
-    get(script);
-    get(get_remote_url);
-
     z.do_exit       = 0;
     z.dnd_target_best_slot = -1;
     z.dnd_target_best_mimetype = -1;
     *z.dnd_source_widget_path = 0;

-#define check(x) if(!z.zest_##x) {printf("z.zest_" #x " = %p\n", z.zest_##x);}
-    check(open);
-    check(setup);
-    check(close);
-    check(draw);
-    check(tick);
-    check(motion);
-    check(scroll);
-    check(mouse);
-    check(key);
-    check(special);
-    check(resize);
-    check(exit);
-    check(set_option);
-    check(dnd_drop);
-    check(dnd_pick);
-    check(script);
-    check(get_remote_url);
-
     printf("[INFO:Zyn] setup_pugl()\n");
     void *view = setup_pugl(&z);
     printf("[INFO:Zyn] zest_tick()\n");
@@ -729,7 +671,7 @@ int main(int argc, char **argv)

         puglEnterContext(view);
         if(z.zest)
-            needs_redraw = z.zest_tick(z.zest);
+            needs_redraw = zest_tick(z.zest);
         puglLeaveContext(view, 0);
         monotonic_clock_gettime(&post_tick);

@@ -762,11 +704,11 @@ int main(int argc, char **argv)
             putchar('\n');
             fflush(stdout);
         }
-        if(z.zest && z.zest_exit(z.zest))
+        if(z.zest && zest_exit(z.zest))
             break;
     }
     printf("[INFO:Zyn] zest_close()\n");
-    z.zest_close(z.zest);
+    zest_close(z.zest);
     printf("[INFO:Zyn] Destroying pugl view\n");
     puglDestroy(view);
     return 0;
fundamental commented 5 years ago

I know this used to be somewhat of a headache, though it seems to be supported more formally within mruby via https://github.com/mruby/mruby/blob/master/tasks/libmruby.rake (see the libmruby_static bit). I'd expect updating the build_config.rb will be the best path forward to avoid linker pains.