Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linux builds #1

Open
michal-cab opened this issue Dec 8, 2022 · 17 comments · May be fixed by #2
Open

linux builds #1

michal-cab opened this issue Dec 8, 2022 · 17 comments · May be fixed by #2

Comments

@michal-cab
Copy link

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 1

and 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 :)

@michal-cab
Copy link
Author

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_OFFSET_TABLE
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?

@opyate
Copy link

opyate commented Jan 6, 2023

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.

image

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

@opyate
Copy link

opyate commented Jan 6, 2023

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

@opyate
Copy link

opyate commented Jan 6, 2023

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

@michal-cab
Copy link
Author

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 :/

@opyate
Copy link

opyate commented Jan 6, 2023

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: godotengine/godot#20765

@opyate
Copy link

opyate commented Jan 6, 2023

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)

@opyate
Copy link

opyate commented Jan 9, 2023

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:

  • 0.12.3 -> 2021-06-11
  • 0.13.0 -> 2022-11-04

So it's somewhere in-between these two stable tags.

Looking at the changelog now...

@magogware
Copy link
Owner

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.

@opyate
Copy link

opyate commented Jan 9, 2023

@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.

@magogware
Copy link
Owner

magogware commented Jan 9, 2023

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.

@opyate
Copy link

opyate commented Jan 9, 2023

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.

@opyate opyate linked a pull request Jan 9, 2023 that will close this issue
@michal-cab
Copy link
Author

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
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)

i guess libpd was opened also just fine as in terminal i can see:

[]$ 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

@opyate
Copy link

opyate commented Jan 9, 2023

@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)?

@opyate
Copy link

opyate commented Jan 10, 2023

I got it to work. Perhaps crucially because I renamed open to something else to prevent name clashes.

opyate@a771d1a

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 🤣

@michal-cab
Copy link
Author

(yep it looks like progress, thnx! :) can confirm that with breakpoints it works, but without them nope...)

@michal-cab
Copy link
Author

hallo, any chance to merge opyate tribute, or to make it work under godot4? as we have stable version already...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants