Open michal-cab opened 1 year ago
great, thnx for makefile! i tried it and i can confirm, that it produces libpdstream.so :)
but when i tried it inside godot (i opened example from godot-audiostream) i got these errors:
ERROR: Can't resolve symbol godot_gdnative_init. Error: /home/tao/godot/godot_pd/addons/audiostreampd/lib/linux/libpdstream.so: undefined symbol: godot_gdnative_init.
at: get_dynamic_library_symbol_handle (drivers/unix/os_unix.cpp:437)
ERROR: Failed to obtain godot_gdnative_init symbol
at: initialize (modules/gdnative/gdnative.cpp:372)
ERROR: No valid library handle, can't get symbol from GDNative object
at: get_symbol (modules/gdnative/gdnative.cpp:510)
ERROR: No nativescript_init in "res://addons/audiostreampd/lib/linux/libpdstream.so" found
at: init_library (modules/gdnative/nativescript/nativescript.cpp:1503)
ERROR: Can't resolve symbol godot_gdnative_init. Error: /home/tao/godot/godot_pd/addons/audiostreampd/lib/linux/libpdstream.so: undefined symbol: godot_gdnative_init.
at: get_dynamic_library_symbol_handle (drivers/unix/os_unix.cpp:437)
ERROR: Failed to obtain godot_gdnative_init symbol
at: initialize (modules/gdnative/gdnative.cpp:372)
after make i got pdstream.o file inside src dir and when i do command " nm pdstream" i got:
U add_float
U add_symbol
U bang
0000000000000020 B core_api
U create
U destroy
0000000000000000 B dir_prefix
0000000000000200 T error
U finish_message
U flot
...
...
0000000000001130 T godot_gdnative_init
00000000000011f0 T godot_gdnative_terminate
0000000000000cc0 T godot_nativescript_init
...
...
0000000000000018 B nativescript_api
0000000000000010 B nativescript_ext_api
U open
U pd_init
0000000000000080 T pdstream_add_float
0000000000000920 T pdstream_add_symbol
0000000000000760 T pdstream_bang
0000000000000000 T pdstream_constructor
0000000000000310 T pdstream_create
0000000000000020 T pdstream_destructor
0000000000000960 T pdstream_finish_message
00000000000006e0 T pdstream_float
0000000000000aa0 T pdstream_open
0000000000000c00 T pdstream_open_args
0000000000000440 T pdstream_perform
00000000000000c0 T pdstream_start_message
00000000000008a0 T pdstream_symbol
U perform
0000000000000008 B res_prefix
U __stack_chk_fail
U start_dsp
U start_message
U stop_dsp
00000000000009e0 T string_to_chars
U strncpy
U symbol
0000000000000600 T variant_to_chars
but when i proceed "nm libpdstream.so" i got only:
0000000000004020 b completed.0
w cxa_finalize
0000000000001040 t deregister_tm_clones
00000000000010b0 t __do_global_dtors_aux
0000000000003e88 d do_global_dtors_aux_fini_array_entry
0000000000004018 d dso_handle
0000000000003e90 d _DYNAMIC
00000000000010fc t _fini
00000000000010f0 t frame_dummy
0000000000003e80 d frame_dummy_init_array_entry
0000000000002000 r FRAME_END
0000000000004000 d _GLOBAL_OFFSETTABLE
w gmon_start
0000000000001000 t _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000001070 t register_tm_clones
0000000000004020 d __TMC_END__
so my guess there must be something wrong in linking?
Hello, sorry - I deleted the previous Makefile, as it was clearly wrong. I'm getting closer, I guess. Here's my latest one:
SRC = ./src/pdstream.c \
./src/instance.c
OUT = bin
INCLUDES = -I./godot-headers \
-I./libpd/libpd_wrapper \
-I./libpd/pure-data/src
LIBS = -L./libpd/libs -lpd
CFLAGS = $(INCLUDES)
ifeq ($(shell uname),Darwin)
SOLIB_PREFIX = lib
SOLIB_EXT = dylib
else
ifeq ($(OS), Windows_NT) # Windows, use Mingw
SOLIB_PREFIX =
SOLIB_EXT = dll
LDFLAGS += -Wl,--export-all-symbols \
-static-libgcc
else # assume Linux
SOLIB_PREFIX = lib
SOLIB_EXT = so
endif
endif
LDFLAGS += -shared\
$(LIBS)
ifeq ($(shell uname),Linux)
CFLAGS += -fPIC
endif
PDSTREAM = $(OUT)/$(SOLIB_PREFIX)pdstream.$(SOLIB_EXT)
LIBPD_DIR = libpd
LIBPD_FLAGS = MULTI=true
LIBPD = $(LIBPD_DIR)/libs/$(SOLIB_PREFIX)pd.$(SOLIB_EXT)
LIBPD_LOCAL = $(OUT)/$(SOLIB_PREFIX)pd.$(SOLIB_EXT)
ifeq ($(OS),Windows_NT)
LIBPD_FLAGS += ADDITIONAL_CFLAGS='-DPD_LONGINTTYPE="long long"'
endif
$(PDSTREAM): ${SRC:.c=.o} $(LIBPD_LOCAL)
$(CC) -o $@ $(CFLAGS) ${SRC:.c=.o} $(LDFLAGS)
$(LIBPD_LOCAL): Makefile.patch $(OUT)
ifeq ($(OS),Windows_NT)
patch -u $(LIBPD_DIR)/Makefile $<
endif
$(MAKE) -C $(LIBPD_DIR) $(LIBPD_FLAGS)
cp $(LIBPD) $@
$(OUT):
mkdir $@
clean:
rm ${SRC:.c=.o}
rm $(PDSTREAM)
But there are still linking issues.
Inside Godot:
E 0:00:00.384 open_dynamic_library: Can't open dynamic library: /home/opyate/the-game/addons/audiostreampd/lib/linux/libpdstream.so. Error: libpd.so: cannot open shared object file: No such file or directory
Here's nm
using my latest Makefile:
nm bin/libpdstream.so
0000000000003ee7 T add_float
0000000000003f1a T add_symbol
0000000000004017 T bang
0000000000003dc7 T close
0000000000007148 b completed.0
0000000000007150 B core_api
0000000000003c53 T create
w __cxa_finalize@GLIBC_2.2.5
00000000000024e0 t deregister_tm_clones
0000000000003d0b T destroy
0000000000007170 B dir_prefix
0000000000002550 t __do_global_dtors_aux
0000000000006d80 d __do_global_dtors_aux_fini_array_entry
0000000000007140 d __dso_handle
0000000000006d88 d _DYNAMIC
0000000000002599 T error
0000000000004148 t _fini
0000000000003f4c T finish_list
0000000000003fcb T finish_message
0000000000004058 T flot
0000000000002590 t frame_dummy
0000000000006d78 d __frame_dummy_init_array_entry
00000000000058a0 r __FRAME_END__
0000000000005260 r __func__.0
0000000000005240 r __func__.1
0000000000005220 r __func__.2
0000000000005210 r __func__.3
00000000000051f8 r __func__.4
00000000000051e0 r __func__.5
00000000000051d0 r __func__.6
00000000000051c0 r __func__.7
0000000000007000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
000000000000528c r __GNU_EH_FRAME_HDR
0000000000003af3 T godot_gdnative_init
0000000000003c0b T godot_gdnative_terminate
0000000000003533 T godot_nativescript_init
0000000000002000 t _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U libpd_add_float
U libpd_add_symbol
U libpd_bang
U libpd_closefile
U libpd_finish_list
U libpd_finish_message
U libpd_float
U libpd_free_instance
U libpd_init
U libpd_init_audio
U libpd_new_instance
U libpd_openfile
U libpd_process_float
U libpd_set_instance
U libpd_start_message
U libpd_symbol
0000000000007158 B nativescript_api
0000000000007160 B nativescript_ext_api
0000000000003d48 T open
0000000000003c44 T pd_init
0000000000003318 T pdstream_add_float
0000000000003384 T pdstream_add_symbol
00000000000031cd T pdstream_bang
000000000000297c T pdstream_constructor
0000000000002a69 T pdstream_create
00000000000029b2 T pdstream_destructor
0000000000003473 T pdstream_finish_message
0000000000003111 T pdstream_float
0000000000002bf3 T pdstream_open
0000000000002dc3 T pdstream_open_args
0000000000002ebd T pdstream_perform
00000000000033f7 T pdstream_start_message
0000000000003258 T pdstream_symbol
00000000000040f1 T perform
0000000000002510 t register_tm_clones
0000000000007168 B res_prefix
U __stack_chk_fail@GLIBC_2.4
0000000000003e0b T start_dsp
0000000000003f8d T start_message
0000000000003e79 T stop_dsp
0000000000002885 T string_to_chars
U strncpy@GLIBC_2.2.5
00000000000040a5 T symbol
0000000000007148 d __TMC_END__
0000000000002756 T variant_to_chars
More information: I'm using more recent versions of libpd and puredata:
cd libpd/pure-data
git checkout 0.53-1
And
cd libpd
git checkout 0.13.2
yep i can just confirm that error concerning loading libpd :-o: (ofcourse i added it to deps inside PdStream.tres)
ERROR: Can't open dynamic library: /home/tao/godot/godot_pd/addons/audiostreampd/lib/linux/libpdstream.so. Error: libpd.so: cannot open shared object file: No such file or directory
at: open_dynamic_library (drivers/unix/os_unix.cpp:418)
ERROR: No valid library handle, can't get symbol from GDNative object
at: get_symbol (modules/gdnative/gdnative.cpp:510)
ERROR: No nativescript_init in "res://addons/audiostreampd/lib/linux/libpdstream.so" found
at: init_library (modules/gdnative/nativescript/nativescript.cpp:1503)
ERROR: No valid library handle, can't get symbol from GDNative object
at: get_symbol (modules/gdnative/gdnative.cpp:510)
ERROR: No valid library handle, can't terminate GDNative object
at: terminate (modules/gdnative/gdnative.cpp:417)
ERROR: Can't open dynamic library: /home/tao/godot/godot_pd/addons/audiostreampd/lib/linux/libpdstream.so. Error: libpd.so: cannot open shared object file: No such file or directory
at: open_dynamic_library (drivers/unix/os_unix.cpp:418)
huh thats strange :/
~I'll try and compile a combined .so file for both.~
Wait, before I go down a rabbit hole...
It's linked properly:
$ ls
libpd.so libpdstream.so
$ LD_LIBRARY_PATH=. ldd libpdstream.so
linux-vdso.so.1 (0x00007ffc770fa000)
libpd.so => ./libpd.so (0x00007fcdc4e58000) // <---- here it is!
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcdc4c15000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fcdc4b2e000)
libmvec.so.1 => /lib/x86_64-linux-gnu/libmvec.so.1 (0x00007fcdc4a31000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcdc4fe9000)
I'll try this rpath
trick: https://github.com/godotengine/godot/issues/20765
OK, no more errors from Godot, but running GUI.tscn just exits the scene 🤔
Here's the latest Makefile:
SOLIB_PREFIX = lib
SOLIB_EXT = dylib
else
- SOLIB_PREFIX =
- SOLIB_EXT = dll
- LDFLAGS += -Wl,--export-all-symbols \
- -static-libgcc
+ ifeq ($(OS), Windows_NT) # Windows, use Mingw
+ SOLIB_PREFIX =
+ SOLIB_EXT = dll
+ LDFLAGS += -Wl,--export-all-symbols \
+ -static-libgcc
+ else # assume Linux
+ SOLIB_PREFIX = lib
+ SOLIB_EXT = so
+ endif
endif
LDFLAGS += -shared\
$(LIBS)
+ifeq ($(shell uname),Linux)
+ CFLAGS += -fPIC
+ LDFLAGS += '-Wl,-rpath,addons/audiostreampd/lib/linux'
+endif
+
PDSTREAM = $(OUT)/$(SOLIB_PREFIX)pdstream.$(SOLIB_EXT)
LIBPD_DIR = libpd
@@ -36,7 +46,7 @@ ifeq ($(OS),Windows_NT)
endif
$(PDSTREAM): ${SRC:.c=.o} $(LIBPD_LOCAL)
- $(CC) -o $@ ${SRC:.c=.o} $(LDFLAGS)
+ $(CC) -o $@ $(CFLAGS) ${SRC:.c=.o} $(LDFLAGS)
$(LIBPD_LOCAL): Makefile.patch $(OUT)
ifeq ($(OS),Windows_NT)
OK, I got it to work when I remove the error handler, i.e.
// error(pd_init(), __func__, __LINE__);
pd_init(); // just call this
I'm trying to figure out if anything broke when going to tag 0.13.2
in libpd, as I'd like to keep the error handler and not let rogue PD crash the game.
It seems as through this repo points to a libpd from 2021-11-19, but:
So it's somewhere in-between these two stable tags.
Looking at the changelog now...
Thank you all so much for your work. I apologise that a Linux build wasn't included to begin with; I lost access to a Linux machine last year and never got around to testing anything on Linux after moving to a Mac. My guess would have been, having dealt with build issues when creating the Windows and Mac Makefiles, that either the library or some of its dependencies are not being located correctly or are a mismatched architecture.
From the looks of things, though, @opyate has a working Make recipe. I don't believe libpd has introduced any breaking API changes, as I used libpd in some other projects with similar code to this repo. @opyate, if you could confirm your fix and submit a pull request with your Makefile and submodule changes, I'll merge it in.
Again, thank you all for your work and sorry for the radio silence.
@magogware no worries :)
Found the reason why the TSCN (the game) just exits. The error handler is clashing with some other function called error
(it's quite a generic function name, which might work better from behind a namespace), so this works:
s/ error\(/ error_reporter\(/g
I'll open a PR for this.
Brilliant sleuthing! Out of curiosity, any indication what function is clashing? I took a brief look through z_libpd.c
and m_pd.c
and couldn't find anything, but it could be something within string.h
.
When I rename this error
function to anything else, like error_reporter
, then the plugin runs without exiting:
https://github.com/magogware/godot-pdstream/blob/master/src/pdstream.c#L12
EDIT: ok, it just occurs to me that you're asking about what function not written by yourself might be clashing :) No idea - all I know is that the rename fixes things, so I just presume there's an error()
function elsewhere in maybe godot-headers or libpd.
slowly getting there but something strange is also happening... :/
i did:
git clone https://github.com/opyate/godot-pdstream.git
git checkout fixes-for-linux
git submodule update --init --recursive
make went just fine producing libpd.so and libpdstream.so.
i created new project in godot 3.5.1 copied addons dir from godot-audiostream into it, also copied compiled libpd.so and libpdstream.so into ../lib/linux dir and set paths in PdStream.tres . saved that project and when i try to open and run it from godot editor it spills warnings (which are not essential i guess):
WARNING: Error setting locale modifiers
i guess libpd was opened also just fine as in terminal i can see:
at: initialize (platform/x11/os_x11.cpp:166)
WARNING: XOpenIM failed
at: initialize (platform/x11/os_x11.cpp:213)
WARNING: XCreateIC couldn't create xic
at: initialize (platform/x11/os_x11.cpp:510)
[~]$ pd 0.53.1
bonk version 1.5
fiddle version 1.1 TEST4
pd~ version 0.54
pique 0.1 for PD version 23
sigmund~ version 0.07
pd 0.53.1
bonk version 1.5
fiddle version 1.1 TEST4
pd~ version 0.54
pique 0.1 for PD version 23
sigmund~ version 0.07
pd 0.53.1
bonk version 1.5
fiddle version 1.1 TEST4
pd~ version 0.54
pique 0.1 for PD version 23
sigmund~ version 0.07
pd 0.53.1
bonk version 1.5
fiddle version 1.1 TEST4
pd~ version 0.54
pique 0.1 for PD version 23
it even creates window without those four buttons and spills errors like:
SCRIPT ERROR: Invalid call. Nonexistent function 'open' in base 'Reference (PdStream.gdns)'.
at: AudioStreamPd.setup (res://addons/audiostreampd/AudioStreamPd.gd:15)
SCRIPT ERROR: Invalid call. Nonexistent function 'flot' in base 'Reference (PdStream.gdns)'.
at: AudioStreamPd.flot (res://addons/audiostreampd/AudioStreamPd.gd:45)
SCRIPT ERROR: Invalid call. Nonexistent function 'connect' in base 'Nil'.
at: _ready (res://addons/audiostreampd/example/GUI.gd:10)
ERROR: Parameter "p_child" is null.
at: add_child (scene/main/node.cpp:1280)
in Pdstream.gdns is just this:
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://addons/audiostreampd/PdStream.tres" type="GDNativeLibrary" id=1]
[resource]
class_name = "PdStream"
library = ExtResource( 1 )
script_class_name = "PdStream"
on line 15 in AudioStreamPd.gd is pdstream.open(patch)
so it has a problem to open source pd file? but when i tried to print var patch it just points to: res://addons/audiostreampd/example/sawtooth.pd
maybe i am doing some stupid error but have no idea what i am doing wrong :/. ev. will be thankful for advice. just to add that i am on ubuntu 22.04.1 LTS
@michal-cab
I see this error too, but can make it go away if I set a breakpoint on PdStream.new()
in the gdscript:
SCRIPT ERROR: Invalid call. Nonexistent function 'open' in base 'Reference (PdStream.gdns)'.
at: AudioStreamPd.setup (res://addons/audiostreampd/AudioStreamPd.gd:15)
Then I just step over the next to lines manually.
func setup(player_node: Node):
pdstream = PdStream.new() # <--- set break point here
pdstream.create() # <--- step
pdstream.open(patch) # <--- step
It looks like a race condition. I'm looking at a way to slow the initialisation down.
As for the second error:
SCRIPT ERROR: Invalid call. Nonexistent function 'flot' in base 'Reference (PdStream.gdns)'.
at: AudioStreamPd.flot (res://addons/audiostreampd/AudioStreamPd.gd:45)
I'm also seeing this, and working on it now. I suppose both of these are a new issue, as the original issue has now been answered (builds on Linux)?
I got it to work. Perhaps crucially because I renamed open
to something else to prevent name clashes.
https://github.com/opyate/godot-pdstream/commit/a771d1afe88e162f56443a35d0231911f18d0df9
There was an open
in src/instance.(c|h)
and also defined as godot_instance_method open
inside godot_nativescript_init
which might have clobbered the definition in src/instance.(c|h)
Screencast: https://youtu.be/fIjNBv-tS5Q (HD should be ready 30 minutes from time of writing this)
¯\_(ツ)_/¯
PS I just stumbled upon this solution thanks to gdb
. I wanted to set a breakpoint on open
to see what happens, but if you do that, it stops almost everywhere in the stack, as a LOT of methods are called open
. So, I gave it a unique name, and the thing started working magically 🤣
(yep it looks like progress, thnx! :) can confirm that with breakpoints it works, but without them nope...)
hallo, any chance to merge opyate tribute, or to make it work under godot4? as we have stable version already...
hello, in Makefile there is no option for build linux version - i guess this shlould not be problem. I tried to fiddle with Makefile but I ended at error like this:
make -C libpd MULTI=true make[1]: Entering directory '/home/tao/source/godot-pdstream/libpd' make[1]: Nothing to be done for 'libpd'. make[1]: Leaving directory '/home/tao/source/godot-pdstream/libpd' cp libpd/libs/libpd.so bin/libpd.so cc -o bin/libpdstream.so ./src/pdstream.o ./src/instance.o -fPIC -shared -L./libpd/libs -lpd /usr/bin/ld: ./src/pdstream.o: warning: relocation against
res_prefix' in read-only section
.text' /usr/bin/ld: ./src/pdstream.o: relocation R_X86_64_PC32 against symbol `core_api' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: bad value collect2: error: ld returned 1 exit status make: *** [Makefile:38: bin/libpdstream.so] Error 1and git submodule update --init --recursive dont work, so i add libpd and pd sources manually
it would be really great to have pdlib api accessible in godot. good work :)