[SOLVED] Development on Raspberry Pi 4

/home/pi/IdeaProjects/RPI4B/libbulletjme.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=a65fb57f30b28696d3242c9173698b122d2ba7db, not stripped

its 32bit shared object , so out of curiosity , i know that .so files are object files that have machine code(binary code) generated by the jvm during runtime interpreted to hexcode, but what’s the difference between a shared & executable object ?

1 Like

i know that .so files are object files that have machine code(binary code) generated by the jvm during runtime interpreted to hexcode, but what’s the difference between a shared & executable object ?

  1. The code in an .so file is generated by a compiler at build time, not by the JVM at run time.
  2. Generally, the code in an .so file is executed directly by the CPU, not interpreted. (That’s why it’s platform-specific.)
  3. A shared library contains native code that can be shared between multiple Linux processes, even if those processes are running different applications. I think library sharing was developed to conserve physical memory.

For JMonkeyEngine, the key benefit of a shared library is dynamic linkage: our Java apps can invoke its native methods even though they’re not statically linked into the Java Virtual Machine.

As for the UnsatisfiedLinkError, I need time to decide how to debug this remotely. I’m open to suggestions…

1 Like

The javadoc for System.load() says that “the filename argument is mapped to a native library image in an implementation-dependent manner”. In other words, the JVM might not actually be looking in “/home/pi/IdeaProjects/RPI4B” for the file.

Looking back at the “java -XshowSettings:all” output, I see that there’s a “java.library.path” property. Please copy the “libbulletjme.so” file to one of those directories, set the owner and permissions appropriately, and retest.

1 Like

I thought of this too , I must try it out :smile:

1 Like

When cd on this directory , it does not exist !!!?

1 Like

This too

pi@raspberrypi:~ $ sudo cp /home/pi/IdeaProjects/RPI4B/libbulletjme.so  /usr/java/packages/lib  /usr/lib/arm-linux-gnueabihf/jni   /lib/arm-linux-gnueabihf  /usr/lib/arm-linux-gnueabihf  /usr/lib/jni  /lib /usr/lib
cp: cannot stat '/usr/java/packages/lib': No such file or directory
cp: -r not specified; omitting directory '/usr/lib/arm-linux-gnueabihf/jni'
cp: -r not specified; omitting directory '/lib/arm-linux-gnueabihf'
cp: -r not specified; omitting directory '/usr/lib/arm-linux-gnueabihf'
cp: cannot stat '/usr/lib/jni': No such file or directory
cp: -r not specified; omitting directory '/lib'

I have copied the libbulletjme.so to /usr/lib/arm-linux-gnueabihf/jni & the operation is successful but it didnot work too giving the same Error

EDIT :
Someone says here that you could activate RPi4B 64bit kernal mode through :

The 32-bit kernel image for the RPi 4 is named kernel7l.img, the 64-bit kernel image kernel8.img, but 64-bit mode is not activated automatically like on the RPi 3. A config.txt file with this entry is needed:
Code: Select all

arm_64bit=1

It’s not activated by default
I donot know if this can help or not

https://www.raspberrypi.org/forums/viewtopic.php?t=244479&start=25

1 Like

It does say that this should be an absolute path/file name. (Which it is, given the above discussion). The JME system is generating the actual path, so moving the library around seems… unlikely to do anything.

That’s analogous to classpath, but for native libraries. The fact that the error is giving a full path to the .so indicates that JME platform is setting this automatically.

The Javadoc for System.load() also implies that there may be some virtual paths for libraries that are statically linked into the JVM.

That would be something to do on your end, setting your Pi to run 64 bit. You would then need to install 64 bit java, (and possibly change some parts of your OS) and JME would try to use the ARM64 version of libbulletjme.so

1 Like

@sgold:

Javadoc for System.load() and the UnsatisfiedLinkError also indicate that this error can mean that the library is there, but that the native methods are not compatible.

My current suspicion is an incompatibility with the compiler options. If you review post 60, I don’t think that the processor in question has hf (Note the references to VFP)

@Pavl_G can confirm this by running

readelf -A /proc/self/exe | grep Tag_ABI_VFP_args - If no response, the OS/chip is set to use hf, if response is Tag_ABI_VFP_args: VFP registers, it’s using Vector Floating Point. Source

1 Like
pi@raspberrypi:~ $ readelf -A /proc/self/exe | grep Tag_ABI_VFP_args
  Tag_ABI_VFP_args: VFP registers

so , i guess its an armhf now , & due to the in-availability of jvm backward compatibility we still have incompatible binaries , i think i would like to try enabling the 64-bit & do these kinda of java investigations again , may be we can get something , @sgold , @sailsman63 if i am getting something or understanding something wrong , please inform me !

Be aware that you will need to install a 64-bit OS if you do this. See Raspberry Pi OS (64 bit) beta test version - Raspberry Pi Forums for details, looks like they still consider 64 bit to be beta…

Also: I seem to have been wrong about the hf stuff - vfp is the hardware floating point support.

I still think that it’s probably a mismatch between what the processor supports, and the options that @sgold’s compiler defaults to. If he runs arm-linux-gnueabihf-gcc -E -v we’ll get a look at some of the default options (a lot of supporting libraries, but also flags regarding which architecture/features to target)

2 Likes

I also think that 64 bits is not the way to go. Specially since most users won’t have that enabled and if you want people to try out your game in the pi, then they won’t be able to unless they enable the 64 bits.

2 Likes

That’s not how the Linux “cp” command works. “cp” only allows you to specify a single destination directory. Select a single directory from the java.library.path (preferably “/usr/java/packages/lib”) and copy the native library there.

1 Like

Well, a 64-bit kernel would allow you to run a 64-bit JVM, which would give you a Linux_ARM64 platform. Minie already includes a native library for Linux_ARM64, and it’s well-tested, so it would probably work on your hardware.

My goal at the moment is to get Minie working on Linux_ARM32. If you don’t mind, I’d like to continue pursuing that goal.

2 Likes

I specifically tried not to compile for “hf”. That’s why I installed the g++-5-arm-linux-gnueabi cross-compiler package instead of g++-5-arm-linux-gnueabihf. The exact compiler version used was:

arm-linux-gnueabi-g++-5 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609

Also, wouldn’t an “hf” native binary be identified somehow in the output of the “file” command?

P.S.: I’ve submitted a job to collect the g++ -E -v output for analysis.

P.P.S: Here it is:

$ arm-linux-gnueabi-g++-5 -E -v

Using built-in specs.

COLLECT_GCC=arm-linux-gnueabi-g++-5

Target: arm-linux-gnueabi

Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-armel-cross/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-armel-cross --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-armel-cross --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libgcj --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv5t --with-float=soft --disable-werror --enable-multilib --enable-checking=release --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=arm-linux-gnueabi --program-prefix=arm-linux-gnueabi- --includedir=/usr/arm-linux-gnueabi/include

Thread model: posix

gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 

The command "arm-linux-gnueabi-g++-5 -E -v" exited with 0.
1 Like

Sorry, I had missed that. The output from your compiler shows that you succeeded at that.

I’m now totally out to lunch. Sorry…

1 Like

My goal is to build libraries for different PIs , & kiosk system apps as user end system only on my device but I will consider this , thanks for the alert :slightly_smiling_face::grin:

EDIT: I think , you are totally right , I would need something that’s compatible also with pi zero or all pi versions , because when I have a final kiosk project as an SD card with a system & my app , I will also need it to be compatible with any pi & not all PIs have 64-bit support on the metal bare cortex

1 Like

Yes , I am still sticking to our plan , donot worry :slightly_smiling_face::+1::+1:

1 Like

But its an armhf , it uses g++ or c compiler for armhf

pi@raspberrypi:~ $ arm-linux-gnueabihf-g++ -E -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-g++
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Raspbian 8.3.0-6+rpi1' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=arm-linux-gnueabihf- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 8.3.0 (Raspbian 8.3.0-6+rpi1) 

Available commands starting w/ arm :slightly_smiling_face:

pi@raspberrypi:~ $ ar
ar                                      arm-linux-gnueabihf-elfedit             arm-linux-gnueabihf-gcov-8              arm-linux-gnueabihf-objdump             arm-linux-gnueabihf-size
arandr                                  arm-linux-gnueabihf-g++                 arm-linux-gnueabihf-gcov-dump           arm-linux-gnueabihf-pkg-config          arm-linux-gnueabihf-strings
arch                                    arm-linux-gnueabihf-g++-8               arm-linux-gnueabihf-gcov-dump-8         arm-linux-gnueabihf-python2.7-config    arm-linux-gnueabihf-strip
arecord                                 arm-linux-gnueabihf-gcc                 arm-linux-gnueabihf-gcov-tool           arm-linux-gnueabihf-python2-config      arm-unknown-linux-gnueabihf-pkg-config
arecordmidi                             arm-linux-gnueabihf-gcc-8               arm-linux-gnueabihf-gcov-tool-8         arm-linux-gnueabihf-python3.7-config    arp
arm-linux-gnueabihf-addr2line           arm-linux-gnueabihf-gcc-ar              arm-linux-gnueabihf-gold                arm-linux-gnueabihf-python3.7m-config   arpd
arm-linux-gnueabihf-ar                  arm-linux-gnueabihf-gcc-ar-8            arm-linux-gnueabihf-gprof               arm-linux-gnueabihf-python3-config      arptables
arm-linux-gnueabihf-as                  arm-linux-gnueabihf-gcc-nm              arm-linux-gnueabihf-ld                  arm-linux-gnueabihf-python3m-config     arptables-nft
arm-linux-gnueabihf-c++filt             arm-linux-gnueabihf-gcc-nm-8            arm-linux-gnueabihf-ld.bfd              arm-linux-gnueabihf-python-config       arptables-nft-restore
arm-linux-gnueabihf-cpp                 arm-linux-gnueabihf-gcc-ranlib          arm-linux-gnueabihf-ld.gold             arm-linux-gnueabihf-ranlib              arptables-nft-save
arm-linux-gnueabihf-cpp-8               arm-linux-gnueabihf-gcc-ranlib-8        arm-linux-gnueabihf-nm                  arm-linux-gnueabihf-readelf             arptables-restore
arm-linux-gnueabihf-dwp 

Additional Info :

pi@raspberrypi:~ $ gcc -dumpspecs
*asm:
%{mbig-endian:-EB} %{mlittle-endian:-EL} %(asm_cpu_spec) %{mapcs-*:-mapcs-%*} %(subtarget_asm_float_spec) %{mthumb-interwork:-mthumb-interwork} %{mfloat-abi=*} %{!mfpu=auto: %{mfpu=*}} %(subtarget_extra_asm_spec)

*asm_debug:
%{%:debug-level-gt(0):%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}} %{fdebug-prefix-map=*:--debug-prefix-map %*}

*asm_final:
%{gsplit-dwarf: 
       objcopy --extract-dwo 	 %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O} 	 %{c:%{o*:%:replace-extension(%{o*:%*} .dwo)}%{!o*:%b.dwo}}%{!c:%b.dwo} 
       objcopy --strip-dwo 	 %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O}     }

*asm_options:
%{-target-help:%:print-asm-header()} %{v} %{w:-W} %{I*}  %{gz|gz=zlib:--compress-debug-sections=zlib} %{gz=none:--compress-debug-sections=none} %{gz=zlib-gnu:--compress-debug-sections=zlib-gnu} %a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}

*invoke_as:
%{!fwpa*:   %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}   %{!S:-o %|.s |
 as %(asm_options) %m.s %A }  }

*cpp:
%(subtarget_cpp_spec)					%{mfloat-abi=soft:%{mfloat-abi=hard:						%e-mfloat-abi=soft and -mfloat-abi=hard may not be used together}} %{mbig-endian:%{mlittle-endian:	%e-mbig-endian and -mlittle-endian may not be used together}}

*cpp_options:
%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{%:debug-level-gt(0):%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps*:-fpch-preprocess}

*cpp_debug_options:
%{d*}

*cpp_unique_options:
%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}} %{remap} %{g3|ggdb3|gstabs3|gxcoff3|gvms3:-dD} %{!iplugindir*:%{fplugin*:%:find-plugindir()}} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{E|M|MM:%W{o*}}

*trad_capable_cpp:
cc1 -E %{traditional|traditional-cpp:-traditional-cpp}

*cc1:
%{!mandroid|tno-android-cc:%{profile:-p} %{%:sanitize(address):-funwind-tables};:%{profile:-p} %{%:sanitize(address):-funwind-tables} %{!mglibc:%{!muclibc:%{!mbionic: -mbionic}}} %{!fno-pic:%{!fno-PIC:%{!fpic:%{!fPIC: -fPIC}}}}}

*cc1_options:
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %{!iplugindir*:%{fplugin*:%:find-plugindir()}} %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*} %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)}  %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}}  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{Qy:} %{-help:--help} %{-target-help:--target-help} %{-version:--version} %{-help=*:--help=%*} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{coverage:-fprofile-arcs -ftest-coverage} %{fprofile-arcs|fprofile-generate*|coverage:   %{!fprofile-update=single:     %{pthread:-fprofile-update=prefer-atomic}}}

*cc1plus:
%{!mandroid|tno-android-cc:;:%{!fexceptions:%{!fno-exceptions: -fno-exceptions}} %{!frtti:%{!fno-rtti: -fno-rtti}}}

*link_gcc_c_sequence:
%{static|static-pie:--start-group} %G %L    %{static|static-pie:--end-group}%{!static:%{!static-pie:%G}}

*link_ssp:
%{fstack-protector|fstack-protector-all|fstack-protector-strong|fstack-protector-explicit:}

*endfile:
%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} %{!mandroid|tno-android-ld:%{fvtable-verify=none:%s;      fvtable-verify=preinit:vtv_end_preinit.o%s;      fvtable-verify=std:vtv_end.o%s}    %{static:crtend.o%s;      shared|static-pie|pie:crtendS.o%s;      :crtend.o%s}    crtn.o%s    ;:%{shared: crtend_so%O%s;: crtend_android%O%s}}

*link:
%{!r:--build-id} %{!static|static-pie:--eh-frame-hdr}  %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*|march=armv4|mcpu=fa526|mcpu=fa626:--fix-v4bx}%{!r:%{!mbe32:%:be8_linkopt(%{mlittle-endian:little}			       %{mbig-endian:big}			       %{mbe8:be8}			       %{march=*:arch %*})}}%{!mandroid|tno-android-ld:%{h*}    %{static:-Bstatic}    %{shared:-shared}    %{symbolic:-Bsymbolic}    %{!static:      %{rdynamic:-export-dynamic}      %{!shared:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:%{mmusl:/lib/ld-musl-arm%{mbig-endian:eb}%{mfloat-abi=hard:hf}.so.1;:%{mfloat-abi=hard:/lib/ld-linux-armhf.so.3}     %{mfloat-abi=soft*:/lib/ld-linux.so.3}     %{!mfloat-abi=*:/lib/ld-linux.so.3}}}}}}    -X    --hash-style=gnu    %{mbig-endian:-EB} %{mlittle-endian:-EL} -m armelf_linux_eabi;:%{h*}    %{static:-Bstatic}    %{shared:-shared}    %{symbolic:-Bsymbolic}    %{!static:      %{rdynamic:-export-dynamic}      %{!shared:-dynamic-linker %{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:%{mmusl:/lib/ld-musl-arm%{mbig-endian:eb}%{mfloat-abi=hard:hf}.so.1;:%{mfloat-abi=hard:/lib/ld-linux-armhf.so.3}     %{mfloat-abi=soft*:/lib/ld-linux.so.3}     %{!mfloat-abi=*:/lib/ld-linux.so.3}}}}}}    -X    --hash-style=gnu    %{mbig-endian:-EB} %{mlittle-endian:-EL} -m armelf_linux_eabi %{shared: -Bsymbolic}}

*lib:
%{!mandroid|tno-android-ld:%{pthread:-lpthread} %{shared:-lc}    %{!shared:%{profile:-lc_p}%{!profile:-lc}};:%{shared:-lc}    %{!shared:%{profile:-lc_p}%{!profile:-lc}} %{!static: -ldl}}

*link_gomp:


*libgcc:
%{static|static-libgcc|static-pie:-lgcc -lgcc_eh}%{!static:%{!static-libgcc:%{!static-pie:%{!shared-libgcc:-lgcc --push-state --as-needed -lgcc_s --pop-state}%{shared-libgcc:-lgcc_s%{!shared: -lgcc}}}}}

*startfile:
%{!mandroid|tno-android-ld:%{shared:;      pg|p|profile:%{static-pie:grcrt1.o%s;:gcrt1.o%s};      static:crt1.o%s;      static-pie:rcrt1.o%s;      pie:Scrt1.o%s;      :crt1.o%s}    crti.o%s    %{static:crtbeginT.o%s;      shared|static-pie|pie:crtbeginS.o%s;      :crtbegin.o%s}    %{fvtable-verify=none:%s;      fvtable-verify=preinit:vtv_start_preinit.o%s;      fvtable-verify=std:vtv_start.o%s}    ;:%{shared: crtbegin_so%O%s;:  %{static: crtbegin_static%O%s;: crtbegin_dynamic%O%s}}}

*cross_compile:
0

*version:
8.3.0

*multilib:
.::arm-linux-gnueabihf ;

*multilib_defaults:
marm mlittle-endian mfloat-abi=hard mno-thumb-interwork

*multilib_extra:


*multilib_matches:


*multilib_exclusions:


*multilib_options:


*multilib_reuse:


*linker:
collect2

*linker_plugin_file:


*lto_wrapper:


*lto_gcc:


*post_link:


*link_libgcc:
%D

*md_exec_prefix:


*md_startfile_prefix:


*md_startfile_prefix_1:


*startfile_prefix_spec:


*sysroot_spec:
--sysroot=%R

*sysroot_suffix_spec:


*sysroot_hdrs_suffix_spec:


*self_spec:


*subtarget_cpp_spec:
%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}

*asm_cpu_spec:
 %{mfpu=auto:%<mfpu=auto %:asm_auto_mfpu(%{march=*: arch %*})} %{mcpu=generic-*:-march=%:rewrite_march(%{mcpu=generic-*:%*});   march=*:-march=%:rewrite_march(%{march=*:%*});   mcpu=*:-mcpu=%:rewrite_mcpu(%{mcpu=*:%*}) }

*subtarget_extra_asm_spec:
%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=5} %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*|march=armv4|mcpu=fa526|mcpu=fa626:--fix-v4bx}

*subtarget_asm_float_spec:
%{mapcs-float:-mfloat}

*link_command:
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:    %(linker) %{!fno-use-linker-plugin:%{!fno-lto:     -plugin %(linker_plugin_file)     -plugin-opt=%(lto_wrapper)     -plugin-opt=-fresolution=%u.res     %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}}     }}%{flto|flto=*:%<fcompare-debug*}     %{flto} %{fno-lto} %{flto=*} %l %{static|shared|r:;pie:-pie} %{fuse-ld=*:-fuse-ld=%*}  %{gz|gz=zlib:--compress-debug-sections=zlib} %{gz=none:--compress-debug-sections=none} %{gz=zlib-gnu:--compress-debug-sections=zlib-gnu} %X %{o*} %{e*} %{N} %{n} %{r}    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}     %{static|no-pie|static-pie:} %{L*} %(mfwrap) %(link_libgcc) %{fvtable-verify=none:} %{fvtable-verify=std:   %e-fvtable-verify=std is not supported in this configuration} %{fvtable-verify=preinit:   %e-fvtable-verify=preinit is not supported in this configuration} %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):%{!shared:libasan_preinit%O%s} %{static-libasan:%{!shared:-Bstatic --whole-archive -lasan --no-whole-archive -Bdynamic}}%{!static-libasan:-lasan}}     %{%:sanitize(thread):%{!shared:libtsan_preinit%O%s} %{static-libtsan:%{!shared:-Bstatic --whole-archive -ltsan --no-whole-archive -Bdynamic}}%{!static-libtsan:-ltsan}}     %{%:sanitize(leak):%{!shared:liblsan_preinit%O%s} %{static-liblsan:%{!shared:-Bstatic --whole-archive -llsan --no-whole-archive -Bdynamic}}%{!static-liblsan:-llsan}}}} %o      %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):	%:include(libgomp.spec)%(link_gomp)}    %{fgnu-tm:%:include(libitm.spec)%(link_itm)}    %(mflib)  %{fsplit-stack: --wrap=pthread_create}    %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address): %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}    %{static:%ecannot specify -static with -fsanitize=address}}    %{%:sanitize(thread): %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}    %{static:%ecannot specify -static with -fsanitize=thread}}    %{%:sanitize(undefined):%{static-libubsan:-Bstatic} -lubsan %{static-libubsan:-Bdynamic} %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}}    %{%:sanitize(leak): %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}}}}     %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}    %{!nostdlib:%{!nostartfiles:%E}} %{T*}  
%(post_link) }}}}}}
1 Like

I had hoped that non-hf binaries would run on gnueabihf systems, specifically yours.

If that’s not the case, then JMonkeyEngine needs to distinguish between hf and non-hf platforms—which it doesn’t, yet.

To test this hypothesis, I’ll build gnueabihf native libraries. While I’m doing that, I’d like you to please run the following console app and report the output:

import com.jme3.system.NativeLibraryLoader;
import java.io.File;

public class Main {

    public static void main(String[] arguments) {
        System.out.println("os.arch = " + System.getProperty("os.arch"));
        System.out.println("os.name = " + System.getProperty("os.name"));
        System.out.println("user.dir = " + System.getProperty("user.dir"));
        System.out.println();

        String libraryPath = System.getProperty("java.library.path");
        System.out.println("original java.library.path = " + libraryPath);

        System.setProperty("java.library.path", ".:" + libraryPath);
        libraryPath = System.getProperty("java.library.path");
        System.out.println("modified java.library.path = " + libraryPath);
        System.out.println();

        String[] directoryNames = libraryPath.split(":");
        for (String directoryName : directoryNames) {
            testDirectory(directoryName);
        }
        System.out.println();

        File file = new File("./libbulletjme.so");
        if (file.exists()) {
            boolean success = file.delete();
            if (success) {
                System.out.println("Deleted a stale image.");
                System.out.println();
            }
        }

        try {
            NativeLibraryLoader.loadNativeLibrary("bulletjme", true);
            System.out.println("Success!");

        } catch (Throwable throwable) {
            System.out.println("Failed to load the native library.");
            testDirectory(".");
            throw new RuntimeException(throwable);
        }
    }

    static void testDirectory(String directoryName) {
        File file = new File(directoryName, "libbulletjme.so");
        String path = file.getAbsolutePath();
        if (file.exists()) {
            System.out.println(path + " exists:");
            if (file.isFile()) {
                long length = file.length();
                System.out.println("  " + path + " is a normal file of " + length + " bytes.");
            }
            if (file.canRead()) {
                System.out.println("  " + path + " is readable.");
            }
            if (file.canExecute()) {
                System.out.println("  " + path + " is executable.");
            }
        } else {
            System.out.println(path + " doesn't exist.");
        }
    }
}
1 Like

Report :

os.arch = arm
os.name = Linux
user.dir = /home/pi/IdeaProjects/RPI4B

original java.library.path = /usr/java/packages/lib:/usr/lib/arm-linux-gnueabihf/jni:/lib/arm-linux-gnueabihf:/usr/lib/arm-linux-gnueabihf:/usr/lib/jni:/lib:/usr/lib
modified java.library.path = .:/usr/java/packages/lib:/usr/lib/arm-linux-gnueabihf/jni:/lib/arm-linux-gnueabihf:/usr/lib/arm-linux-gnueabihf:/usr/lib/jni:/lib:/usr/lib

/home/pi/IdeaProjects/RPI4B/./libbulletjme.so exists:
  /home/pi/IdeaProjects/RPI4B/./libbulletjme.so is a normal file of 3670564 bytes.
  /home/pi/IdeaProjects/RPI4B/./libbulletjme.so is readable.
/usr/java/packages/lib/libbulletjme.so doesn't exist.
/usr/lib/arm-linux-gnueabihf/jni/libbulletjme.so exists:
  /usr/lib/arm-linux-gnueabihf/jni/libbulletjme.so is a normal file of 3670564 bytes.
  /usr/lib/arm-linux-gnueabihf/jni/libbulletjme.so is readable.
/lib/arm-linux-gnueabihf/libbulletjme.so doesn't exist.
/usr/lib/arm-linux-gnueabihf/libbulletjme.so doesn't exist.
/usr/lib/jni/libbulletjme.so doesn't exist.
/lib/libbulletjme.so exists:
  /lib/libbulletjme.so is a normal file of 3670564 bytes.
  /lib/libbulletjme.so is readable.
/usr/lib/libbulletjme.so exists:
  /usr/lib/libbulletjme.so is a normal file of 3670564 bytes.
  /usr/lib/libbulletjme.so is readable.

Deleted a stale image.

Failed to load the native library.
/home/pi/IdeaProjects/RPI4B/./libbulletjme.so exists:
Exception in thread "main"   /home/pi/IdeaProjects/RPI4B/./libbulletjme.so is a normal file of 3670564 bytes.
java.lang.RuntimeException: java.lang.UnsatisfiedLinkError: /home/pi/IdeaProjects/RPI4B/libbulletjme.so: /home/pi/IdeaProjects/RPI4B/libbulletjme.so: cannot open shared object file: No such file or directory
  /home/pi/IdeaProjects/RPI4B/./libbulletjme.so is readable.
	at JmETest.commandLineTest(JmETest.java:52)
	at JmETest.main(JmETest.java:13)
Caused by: java.lang.UnsatisfiedLinkError: /home/pi/IdeaProjects/RPI4B/libbulletjme.so: /home/pi/IdeaProjects/RPI4B/libbulletjme.so: cannot open shared object file: No such file or directory
	at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
	at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)
	at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)
	at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2627)
	at java.base/java.lang.Runtime.load0(Runtime.java:768)
	at java.base/java.lang.System.load(System.java:1837)
	at com.jme3.system.NativeLibraryLoader.loadNativeLibrary(NativeLibraryLoader.java:685)
	at JmETest.commandLineTest(JmETest.java:46)
	... 1 more
1 Like