fusesource / jansi

Jansi is a small java library that allows you to use ANSI escape sequences to format your console output which works even on windows.
http://fusesource.github.io/jansi/
Apache License 2.0
1.11k stars 140 forks source link

Support for os.name=Linux, os.arch=armv6 #201

Closed mattjlewis closed 2 years ago

mattjlewis commented 3 years ago

I get this error on Raspberry Pi Zero (armv6):

Exception in thread "main" java.lang.ExceptionInInitializerError
    at org.fusesource.jansi.AnsiConsole.ansiStream(AnsiConsole.java:239)
    at org.fusesource.jansi.AnsiConsole.initStreams(AnsiConsole.java:542)
    at org.fusesource.jansi.AnsiConsole.systemInstall(AnsiConsole.java:496)
    at com.diozero.sampleapps.SystemInformation.main(SystemInformation.java:52)
Caused by: java.lang.RuntimeException: Unable to load jansi native library
    at org.fusesource.jansi.internal.JansiLoader.initialize(JansiLoader.java:62)
    at org.fusesource.jansi.internal.CLibrary.<clinit>(CLibrary.java:30)
    ... 4 more
Caused by: java.lang.Exception: No native library found for os.name=Linux, os.arch=armv6, paths=[/usr/java/packages/lib/arm:/usr/lib/arm-linux-gnueabihf/jni:/lib/arm-linux-gnueabihf:/usr/lib/arm-linux-gnueabihf:/usr/lib/jni:/lib:/usr/lib]
    at org.fusesource.jansi.internal.JansiLoader.loadJansiNativeLibrary(JansiLoader.java:333)
    at org.fusesource.jansi.internal.JansiLoader.initialize(JansiLoader.java:60)
    ... 5 more

Would it be possible to compile the native library for armv6?

gnodet commented 3 years ago

The libraries are most probably the same. Could you try to put the native library https://github.com/fusesource/jansi/blob/master/src/main/resources/org/fusesource/jansi/internal/native/Linux/armv7/libjansi.so into one of the tried location /usr/java/packages/lib/arm:/usr/lib/arm-linux-gnueabihf/jni:/lib/arm-linux-gnueabihf:/usr/lib/arm-linux-gnueabihf:/usr/lib/jni:/lib:/usr/lib ?

mattjlewis commented 3 years ago

No, they aren't the same unfortunately - jansi works perfectly fine on ARM v7 Pis. I've encountered this issue when compiling my own native library for any diozero library. I cross-compile in an Ubuntu VM, spent quite a while getting the various flags correct to work with a broad range of SBCs - arm v6, v7 and aarch64.

mattjlewis commented 3 years ago

I use this for v6 & 7:

PATH=/home/vagrant/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH
make clean && make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=armv6 CC_CFLAGS="-mfpu=vfp -mfloat-abi=hard"

and this for aarch64:

PATH=/home/vagrant/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH
make clean && make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=armv8-a CC_CFLAGS="-mfpu=vfp -mfloat-abi=hard"
c
gnodet commented 3 years ago

@mattjlewis I've tried using OS_ARCH=armv6 or using CC_CFLAGS="-mfpu=vfp -mfloat-abi=hard in the Makefile but the resulting library is exactly the same (binary comparison). I suppose that's because they don't include any kind of floating point operation maybe ? Jansi already has different library support for armv7 / arm64 and has no specific support for armv6 atm, but if the libraries are the same, it may just be a matter of loading the armv7 library ?

mattjlewis commented 3 years ago

Ah, I see, you resolve armv6 but you don't have an "armv6" native library folder, just "armv7". I will try put the native library on the lib path. Would it be possible for you to translate armv6 and armv7 to load the same library?

gnodet commented 3 years ago

Yes, if the library actually works for you, I can translate armv6 to armv7 when loading the library.

mattjlewis commented 3 years ago

Unfortunately I get this error:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGILL (0x4) at pc=0xab1b0ed0, pid=680, tid=0xb5143460
#
# JRE version: OpenJDK Runtime Environment (8.0_212-b01) (build 1.8.0_212-8u212-b01-1+rpi1-b01)
# Java VM: OpenJDK Client VM (25.212-b01 mixed mode linux-aarch32 )
# Problematic frame:
# C  [libjansi.so+0xed0]
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/pi/diozero/diozero-distribution-1.1.5/hs_err_pid680.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Snippet from the error report file:

Stack: [0xb50f4000,0xb5144000],  sp=0xb51413d0,  free space=308k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libjansi.so+0xed0]
C  [libc.so.6+0x115508]  _dl_catch_exception+0x7c
V  [libjvm.so+0x33bc28]  JVM_LoadLibrary+0xb4
C  [libjava.so+0xaba0]  Java_java_lang_ClassLoader_00024NativeLibrary_load+0x13c
j  java.lang.ClassLoader$NativeLibrary.load(Ljava/lang/String;Z)V+0
j  java.lang.ClassLoader.loadLibrary0(Ljava/lang/Class;Ljava/io/File;)Z+328
j  java.lang.ClassLoader.loadLibrary(Ljava/lang/Class;Ljava/lang/String;Z)V+48
j  java.lang.Runtime.load0(Ljava/lang/Class;Ljava/lang/String;)V+57
j  java.lang.System.load(Ljava/lang/String;)V+7
j  org.fusesource.jansi.internal.JansiLoader.loadNativeLibrary(Ljava/io/File;)Z+13
j  org.fusesource.jansi.internal.JansiLoader.loadJansiNativeLibrary()V+321
j  org.fusesource.jansi.internal.JansiLoader.initialize()Z+9
j  org.fusesource.jansi.internal.CLibrary.<clinit>()V+0
v  ~StubRoutines::call_stub
V  [libjvm.so+0x2e54b8]
V  [libjvm.so+0x2e4c14]
V  [libjvm.so+0x2aa1f4]
V  [libjvm.so+0x2aa6c4]
V  [libjvm.so+0x2aa970]
V  [libjvm.so+0x3abf40]
V  [libjvm.so+0x3ac1c4]
V  [libjvm.so+0x2d6e8c]
j  org.fusesource.jansi.AnsiConsole.ansiStream(Z)Lorg/fusesource/jansi/AnsiPrintStream;+49
j  org.fusesource.jansi.AnsiConsole.initStreams()V+7
j  org.fusesource.jansi.AnsiConsole.systemInstall()V+15
j  com.diozero.sampleapps.SystemInformation.main([Ljava/lang/String;)V+0
mattjlewis commented 3 years ago

I've compiled it locally on my Pi Zero (armv6) and can confirm that it works. I used the attached Makefile and compiled with:

make ARCH=armv6

Makefile:

RM = rm -f
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar

# To check CFLAGS: arm-linux-gnueabihf-gcc -Q --help=target
# Alternative for 64 bit: aarch64-linux-gnu-gcc
#CFLAGS = -Wall -fPIC -O3 -march=armv6+fp -mfpu=vfp -mfloat-abi=hard
CFLAGS = -Wall -fPIC -O3 -march=$(ARCH) $(CC_CFLAGS)
# BeagleBone Black:
#CFLAGS = -Wall -fPIC -O3 -march=armv7-a+fp -mfpu=vfpv3-d16 -mfloat-abi=hard -mhard-float -mabi=aapcs-linux

INCLUDES = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -I$(JAVA_HOME)/include/darwin
LFLAGS = -L/home/vagrant/libs/$(CROSS_COMPILE)lib
SO_FILE_EXT = so

LIBS = -Wl,-Bstatic -li2c -Wl,-Bdynamic

SRCS = jansi.c \
        jansi_isatty.c \
        jansi_structs.c \
        jansi_ttyname.c

OBJS = $(SRCS:.c=.o)

LIB_TARGET = libjansi.$(SO_FILE_EXT)

all: $(LIB_TARGET)

$(LIB_TARGET): $(OBJS)
        @echo [LINK] $(LIB_TARGET)
        @$(CC) -shared -o $(LIB_TARGET) $(OBJS) $(LFLAGS) $(LIBS)

$(MAIN): $(OBJS)
        @echo [LINK] $(MAIN)
        $(CC) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)

.c.o:
        @echo [COMPILE] $(CFLAGS) $<
        @$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

clean:
        $(RM) $(OBJS) $(LIB_TARGET) *~

depend: $(SRCS)
        makedepend $(INCLUDES) $^
gnodet commented 3 years ago

Do you think you could provide a PR that would modify the current makefile to add an armv6 native target ?

Le mar. 16 mars 2021 à 11:44, Matthew Lewis @.***> a écrit :

I've compiled it locally on my Pi Zero (armv6) and can confirm that it works. I used the attached Makefile and compiled with:

make ARCH=armv6

Makefile:

RM = rm -f CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar

To check CFLAGS: arm-linux-gnueabihf-gcc -Q --help=target

Alternative for 64 bit: aarch64-linux-gnu-gcc

CFLAGS = -Wall -fPIC -O3 -march=armv6+fp -mfpu=vfp -mfloat-abi=hard

CFLAGS = -Wall -fPIC -O3 -march=$(ARCH) $(CC_CFLAGS)

BeagleBone Black:

CFLAGS = -Wall -fPIC -O3 -march=armv7-a+fp -mfpu=vfpv3-d16 -mfloat-abi=hard -mhard-float -mabi=aapcs-linux

INCLUDES = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -I$(JAVA_HOME)/include/darwin LFLAGS = -L/home/vagrant/libs/$(CROSS_COMPILE)lib SO_FILE_EXT = so

LIBS = -Wl,-Bstatic -li2c -Wl,-Bdynamic

SRCS = jansi.c \ jansi_isatty.c \ jansi_structs.c \ jansi_ttyname.c

OBJS = $(SRCS:.c=.o)

LIB_TARGET = libjansi.$(SO_FILE_EXT)

all: $(LIB_TARGET)

$(LIB_TARGET): $(OBJS) @echo [LINK] $(LIB_TARGET) @$(CC) -shared -o $(LIB_TARGET) $(OBJS) $(LFLAGS) $(LIBS)

$(MAIN): $(OBJS) @echo [LINK] $(MAIN) $(CC) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)

.c.o: @echo [COMPILE] $(CFLAGS) $< @$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

clean: $(RM) $(OBJS) $(LIB_TARGET) *~

depend: $(SRCS) makedepend $(INCLUDES) $^

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/fusesource/jansi/issues/201#issuecomment-800151154, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAUQNWFSXWNKZHA7MCQBQ3TD4ZBFANCNFSM4ZACXZ3A .

--

Guillaume Nodet

Red Hat, Open Source Integration

Email: @.*** Web: http://fusesource.com Blog: http://gnodet.blogspot.com/

mattjlewis commented 3 years ago

It seems that multiarch/crossbuild doesn't support armv6 - https://raspberrypi.stackexchange.com/questions/98142/is-there-a-way-to-cross-compile-for-armv6-using-gcc-7 Attempting to build with -march=armv6 gives this error:

make linux-armv6                                                                                                                                                             master
docker run -it --rm -v $PWD:/workdir -e CROSS_TRIPLE=arm-linux-gnueabihf multiarch/crossbuild make clean-native native OS_NAME=Linux OS_ARCH=armv6
rm -rf target/native-Linux-armv6
running: gcc -Itarget/native-Linux-armv6 -I/include -Isrc/main/lib/inc_linux -Os -mfloat-abi=hard -mfpu=vfp -fPIC -fvisibility=hidden  -march=armv6 -c src/main/native/jansi.c -o target/native-Linux-armv6/jansi.o
gcc -Itarget/native-Linux-armv6 -I/include -Isrc/main/lib/inc_linux -Os -mfloat-abi=hard -mfpu=vfp -fPIC -fvisibility=hidden  -march=armv6 -c src/main/native/jansi.c -o target/native-Linux-armv6/jansi.o
In file included from /usr/include/endian.h:60:0,
                 from /usr/include/arm-linux-gnueabihf/bits/waitstatus.h:64,
                 from /usr/include/stdlib.h:42,
                 from src/main/native/jansi.h:32,
                 from src/main/native/jansi.c:16:
/usr/include/arm-linux-gnueabihf/bits/byteswap.h: In function '__bswap_32':
/usr/include/arm-linux-gnueabihf/bits/byteswap.h:45:1: sorry, unimplemented: Thumb-1 hard-float VFP ABI
 {
 ^
Makefile:17: recipe for target 'target/native-Linux-armv6/jansi.o' failed
make: *** [target/native-Linux-armv6/jansi.o] Error 1
make: *** [linux-armv6] Error 2
gnodet commented 2 years ago

@mattjlewis I've pushed a PR #221, could you have a look as I can't really test it ?