can't link double-float modules with soft-float modules riscv compiler - linux

I am building a program with the riscv compiler and, when the linking process start, I have the following problem:
/home/luna/noelv-buildroot/output/images/riscv64-buildroot-linux-musl_sdk-buildroot/bin/../lib/gcc/riscv64-buildroot-linux-musl/8.3.0/../../../../riscv64-buildroot-linux-musl/bin/ld: /home/luna/noelv-buildroot/output/images/riscv64-buildroot-linux-musl_sdk-buildroot/bin/../lib/gcc/riscv64-buildroot-linux-musl/8.3.0/libgcc.a(_clzsi2.o): can't link double-float modules with soft-float modules
I am using the compiler to compile and linker my code. This is my compiler:
$ riscv64-linux-gcc --verbose
COLLECT_GCC=/home/luna/noelv-buildroot/output/images/riscv64-buildroot-linux-musl_sdk-buildroot/bin/riscv64-linux-gcc.br_real
COLLECT_LTO_WRAPPER=/home/luna/noelv-buildroot/output/images/riscv64-buildroot-linux-musl_sdk-buildroot/bin/../libexec/gcc/riscv64-buildroot-linux-musl/8.3.0/lto-wrapper
Configured with ./configure --prefix=/home/luna/noelv-buildroot/output/host --sysconfdir=/home/luna/noelv-buildroot/output/host/etc --enable-static --target=riscv64-buildroot-linux-musl --with-sysroot=/home/luna/noelv-buildroot/output/host/riscv64-buildroot-linux-musl/sysroot --enable-__cxa_atexit --with-gnu-ld --disable-libssp --disable-multilib --disable-decimal-float --with-gmp=/home/luna/noelv-buildroot/output/host --with-mpc=/home/luna/noelv-buildroot/output/host --with-mpfr=/home/luna/noelv-buildroot/output/host --with-pkgversion='Buildroot 2020.02' --with-bugurl=http://bugs.buildroot.net/ --disable-libmpx --disable-libquadmath --disable-libsanitizer --enable-tls --enable-threads --without-isl --without-cloog --with-arch=rv64imafd --with-abi=lp64d --enable-languages=c,c++ --with-build-time-tools=/home/luna/noelv-buildroot/output/host/riscv64-buildroot-linux-musl/bin --enable-shared --disable-libgomp
Modelo de hilos: posix
gcc version 8.3.0 (Buildroot 2020.02)

Your compiler was build with disable-multilib and for rv64imafd arch. So basically all the libraries provided with the compiler are compiled for this arch.
If you try to compile some code with an other arch , you will not be able to link against it by default. Also, if you provide a library, you will need to be sure it was compiled for this arch to use it in the same time with the libraries provided by the tool chain.
You can see the exact arch and abi of your library with readelf -h.

Can't comment since too low rep,
but have you tried adding the -msoft-float flag
also where are you running that command/program, like hardware specs?
depending on your hardware specs it may be the complete opposite and therefore you should try to avoid the double keyword
Could you also share some code?

Related

unable to compile thrift with mingw and libevent

I'm trying to compile the thrift cpp library from a debian and mingw toolset. I manage to compile zlib, openssl, and libevent with mingw.
But when I'm trying to configure thrift, it does not detect libevent (but it detects openssl and zlib).
below is my configure command :
./configure --host=x86_64-w64-mingw32 --enable-static --disable-shared LDFLAGS=”-L/home/ioan/devTools/openssl-OpenSSL_1_1_1-stable -L/home/ioan/devTools/libevent-2.1.11-stable/ -L/home/ioan/devTools/zlib-1.2.11/ -L/usr/x86_64-w64-mingw32/lib -lgdi32 -lws2_32 -lmincore -lole32 -lwindowsapp” CPPFLAGS=”-I/home/ioan/devTools/zlib-1.2.11/ -I/home/ioan/devTools/openssl-OpenSSL_1_1_1-stable/include -I/home/ioan/devTools/libevent-2.1.11-stable/include --with-libevent=/home/ioan/devTools/libevent-2.1.11-stable” --with-boost=/home/ioan/devTools/boostLibs --with-zlib=/home/ioan/devTools/zlib-1.2.11
I set the LDFLAGS environment variable, the CPPFLAGS environment variable and the --with-libevent tag.
But the configure result is always the same : not detected!!!
The build is ok, but i'm missing the libthriftnb.a library (I got only libthrift.a and libthriftz.a)
Did I miss something?
regards, Ioan

Linux kernel on ARM Cortex-M: how to build proper executables

I need to build a complete linux development framework for a Cortex-M MCU, specifically a STM32F7 Cortex-M7. First I've to explain some background info so please bear with me.
I've downloaded and built a gcc toolchain with croostool-ng 1.24 specifying an armv7e-m architecture with thumb-only instructions and linux 4.20 as the OS and that I want the output to be FLAT executables (I assumed it will mean bFLT).
Then I proceeded to compile the linux kernel (version 4.20) using configs/stm32_defconf, and then a statically compiled busybox rootfs, all using my new toolchain.
Kernel booted just fine but throw me an error and kernel painc with the following message:
Starting init: /sbin/init exists but couldn't execute it (error -8)
and
request_module: modprobe binfmt-464c cannot be processed, kmod busy with 50 threads
The interesting part is the last message. My busybox excutable turned out to be an .ELF! Cortex-M has no MMU, so it's imposible to build a linux kernel on a MMU-less architecture with .ELF support, that's why an (464c)"LF" binary loader can't be found, there is none.
So at last, my question is:
how could I build bFLT executables to run on MMU-less Linux architectures? My toolchain has elf2flt, but in crosstool-ng I've already specified a MMU-less architecture and FLAT binary and I was expecting direct bFLT output, not a "useless" executable. Is that even possible?
Or better: is there anywhere a documented standard procedure to build a complete, working Linux system based on Cortex-M?
Follow-up:
I gave up on building FLAT binaries and tried FDPIC executables. Another dead end. AFAIK:
Linux has long been supporting ELF FDPIC, but the ABI for ARM is pretty new.
It seems that still at this day and age, GCC has not a standard way to enable FDPIC. On some architectures you can use -mfdpic. Not on arm, don't know why. I even don't know if ARM FDPIC is supported at all by mainline GCC. Info is extremely scarce if inexistent.
It seems crosstool-ng 1.24 is BROKEN at building ARM ELF FDPIC support. Resulting gcc has not -mfdpic, and -fPIC generates ARM executables, not ARM FDPIC.
Any insight will be very appreciated.
you can generate FDPIC ELF files just with a prebuilt arm-linux-gnueabi-gcc compiler.
Specifications of an FDPIC ELF file:
Position independent executable/code (i.e. -fPIE and fPIC)
Should be compiled as a shared executable (ET_DYN ELF) to be position independent
use these flags to compile your programs:
arm-linux-gnueabi-gcc -shared -fPIE -fPIC <YOUR PROGRAM.C> -o <OUTPUT FILE>
I've compiled busybox successfully for STM32H7 with this method.
As I know, unfortunately FDPIC ELFs should be compiled with - shared flag so, they use shared libraries and cannot be compiled as -static ELF.
For more information take a look at this file:
https://github.com/torvalds/linux/blob/master/fs/binfmt_elf_fdpic.c
Track the crosstool-ng BFLAT issue from here:
https://github.com/crosstool-ng/crosstool-ng/issues/1399

RHEL7 - /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found

I know this question has been asked for many times while I still get stuck with it.
I have reviewed all answers previously asked like
version `CXXABI_1.3.8' not found (required by ...)
How to fix: [program name] /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version CXXABI_1.3.8' not found (required by [program name])
and I've read https://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.how_to_set_paths
My system is RHEL7, I had a gcc 4.8 installed before, and I install gcc 4.9 with yum -y install devtoolset-3-gcc devtoolset-3-gcc-c++
Then gcc 4.9 is successfully installed.
With gcc -v, I get
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-3/root/usr/libexec/gcc/x86_64-redhat-linux/4.9.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/opt/rh/devtoolset-3/root/usr --mandir=/opt/rh/devtoolset-3/root/usr/share/man --infodir=/opt/rh/devtoolset-3/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,fortran,lto --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.9.2 20150212 (Red Hat 4.9.2-6) (GCC)
Then I set my LD_LIBRARY_PATH following the others' suggestions like:
export LD_LIBRARY_PATH=/opt/rh/devtoolset-3/root/usr/lib/gcc/x86_64-redhat-linux/4.9.2:${LD_LIBRARY_PATH}
However, the error still exits and it seems my newer version gcc4.9 doesn't work.
Any help would be appreciated!
The problem is occurring because the devtoolset-x packages actually just wrap the standard system libstdc++.so so even tho' you have a new compiler, you still have the old ABI (application binary interface). So what you really need is a whole new compiler! Which will include a new library of its own.
To build the compiler you'll need to install some dependencies:
sudo yum install gmp-devel mpfr-devel libmpc-devel
You can download a newer version of GCC from one of the official mirrors, grab a version such as gcc-8.3.0.tar.gz, unpack it and in that directory
./configure --disable-multilib --enable-languages=c,c++ --prefix=$HOME/local
make -j5
make -j install
Then whenever you need a modern ABI,
export LD_LIBRARY_PATH=$HOME/local/lib64
and everything may start working. If your application spawns its own environment (such as Steam), you may want to place the libraries within a path it is searching already.
The "duplicate" answers are either wrong or outdated; this is the correct solution as of today. I know because I tried them all, and this is what actually works...

ARM toolchain build

I am building an ARM cross toolchain with GCC 4.6.3 using the sysroot approach. If I follow the LFS instructions and copy the gmp, mpfr and mpc source folders to the GCC source folder, the build will fail as mpc cannot locate mpfr even though the paths are correct.
The GCC build will complete without any errors when compiling gmp, mpfr and mpc manually as statically linked.
Now my question is if I should install gmp, mpfr and mpc to a random place in the toolchain build directory that gets deleted when the toolchain is finished, so they just are available for the different stages of GCC build or should I point the prefix at $SYSROOT so they become a permanent part of the toolchain? What is the most correct ting to do?
I take a different approach with cross-compiler infrastructure. I have a directory: $HOME/local, with all the expected subdirs: bin/, lib/, include/, etc. $HOME/local/bin is (first) in my $PATH, and $HOME/local/lib in $LD_LIBRARY_PATH (or $DYLD_LIBRARY_PATH on Darwin).
I then build and install gmp, mpfr, mpc, in --prefix=$HOME/local, with:
> ./configure --prefix=$HOME/local --enable-cxx [--disable-fft]
> ./configure --prefix=$HOME/local --with-gmp=$HOME/local
> ./configure --prefix=$HOME/local --with-mpfr=$HOME/local --with-gmp=$HOME/local
I can use fast, platform dependent flags for these packages, which generally don't work for gcc with a cross --target triple:
> env CFLAGS="-pipe -Wall -O2 -march=core2" CXXFLAGS="..." ./configure ...
The advantage is, wherever I build the cross compiler infrastructure, the gmp, mpfr, mpc libraries, includes, etc., are accessible - and the same libs can be used for more than one cross-compiler. i.e., I've got 4.6.x AVR, freestanding x86_64-pc-elf, ARM EABI. Each using the gcc configure options:
> --with-mpc=$HOME/local --with-mpfr=$HOME/local --with-gmp=$HOME/local
Obviously, when I fsck up a tool-chain build (I often do), at least I don't have to repeat this part of build.
Building a cross compiler is a tedious task. Why not use crosstool-NG to automate all the steps required to build a cross compiler?

Using software floating point on x86 linux

Is it (easily) possible to use software floating point on i386 linux without incurring the expense of trapping into the kernel on each call? I've tried -msoft-float, but it seems the normal (ubuntu) C libraries don't have a FP library included:
$ gcc -m32 -msoft-float -lm -o test test.c
/tmp/cc8RXn8F.o: In function `main':
test.c:(.text+0x39): undefined reference to `__muldf3'
collect2: ld returned 1 exit status
It is surprising that gcc doesn't support this natively as the code is clearly available in the source within a directory called soft-fp. It's possible to compile that library manually:
$ svn co svn://gcc.gnu.org/svn/gcc/trunk/libgcc/ libgcc
$ cd libgcc/soft-fp/
$ gcc -c -O2 -msoft-float -m32 -I../config/arm/ -I.. *.c
$ ar -crv libsoft-fp.a *.o
There are a few c files which don't compile due to errors but the majority does compile. After copying libsoft-fp.a into the directory with our source files they now compile fine with -msoft-float:
$ gcc -g -m32 -msoft-float test.c -lsoft-fp -L.
A quick inspection using
$ objdump -D --disassembler-options=intel a.out | less
shows that as expected no x87 floating point instructions are called and the code runs considerably slower as well, by a factor of 8 in my example which uses lots of division.
Note: I would've preferred to compile the soft-float library with
$ gcc -c -O2 -msoft-float -m32 -I../config/i386/ -I.. *.c
but that results in loads of error messages like
adddf3.c: In function '__adddf3':
adddf3.c:46: error: unknown register name 'st(1)' in 'asm'
Seems like the i386 version is not well maintained as st(1) points to one of the x87 registers which are obviously not available when using -msoft-float.
Strangely or luckily the arm version compiles fine on an i386 and seems to work just fine.
Unless you want to bootstrap your entire toolchain by hand, you could start with uclibc toolchain (the i386 version, I imagine) -- soft float is (AFAIK) not directly supported for "native" compilation on debian and derivatives, but it can be used via the "embedded" approach of the uclibc toolchain.
GCC does not support this without some extra libraries. From the 386 documentation:
-msoft-float Generate output containing library calls for floating
point. Warning: the requisite
libraries are not part of GCC.
Normally the facilities of the
machine's usual C compiler are used,
but this can't be done directly in
cross-compilation. You must make your
own arrangements to provide suitable
library functions for
cross-compilation.
On machines where a function returns
floating point results in the 80387
register stack, some floating point
opcodes may be emitted even if
-msoft-float is used
Also, you cannot set -mfpmath=unit to "none", it has to be sse, 387 or both.
However, according to this gnu wiki page, there is fp-soft and ieee. There is also SoftFloat.
(For ARM there is -mfloat-abi=softfp, but it does not seem like something similar is available for 386 SX).
It does not seem like tcc supports software floating point numbers either.
Good luck finding a library that works for you.
G'day,
Unless you're targetting a platform that doesn't have inbuilt FP support, I can't think of a reason why you'd want to emulate FP support.
Doesn't your x386 platform have external FPU support? Pity it's not a x486 with the FPU built in!
In my experience, any soft emulation is bound to be much slower than its hardware equivalent.
That's why I finished up writing a package in Ada to taget the onboard 68k FPU instead of using the soft emulation provided by the compiler manufacturer at the time. They finished up bundling it in their compiler as a matter of fact.
Edit: Just seen your comment below. Hmmm, if you don't need a full suite of FP support is it possible to roll your own for the few math functions you do need? That how the Ada package I mentioned got started.
HTH
cheers,

Resources