Search code examples
linuxgcccross-compilingriscv

How to cross-compile elfutils for RISC-V?


I want to cross-compile elfutils for a RISC-V target and I get linker errors which I don't know how to solve. I use the riscv-gnu-toolchain.

Build zlib

elfutils is build against zlib, so I need to build it first:

CC=riscv64-unknown-linux-gnu-gcc ./configure --prefix=/usr/local/riscv64-unknown-linux-gnu
make
make install

I use this prefix to have all RV64 libraries at the same place, so that the linker can find them easily (maybe wrong?). Building zlib seems to be successful, no errors and libz.so.1 and other related files were placed into /usr/local/riscv64-unknown-linux-gnu/lib.

Build elfutils

Executing the configure script with RISC-V host: (I also cross-compiled zstd, bzip2 and xz with same CC and PREFIX as zlib)

$ ./configure --build=x86_64-linux-gnu --host=riscv64-unknown-linux-gnu --prefix=/usr/local/riscv64-unknown-linux-gnu --disable-libdebuginfod --disable-debuginfod
[checking a lot of stuff...]
=====================================================================
        elfutils: 0.183 (eu_version: 183)
=====================================================================

    Prefix                             : /usr/local/riscv64-unknown-linux-gnu
    Program prefix ("eu-" recommended) : eu-
    Source code location               : .
    Maintainer mode                    : 
    build arch                         : x86_64-pc-linux-gnu

  RECOMMENDED FEATURES (should all be yes)
    gzip support                       : yes
    bzip2 support                      : no
    lzma/xz support                    : yes
    zstd support                       : yes
    libstdc++ demangle support         : yes
    File textrel check                 : yes
    Symbol versioning                  : yes

  NOT RECOMMENDED FEATURES (should all be no)
    Experimental thread safety         : no
    install elf.h                      : no

  OTHER FEATURES
    Deterministic archives by default  : false
    Native language support            : yes
    Extra Valgrind annotations         : no
    libdebuginfod client support       : no
    Debuginfod server support          : no
    Default DEBUGINFOD_URLS            : 

  EXTRA TEST FEATURES (used with make check)
    have bunzip2 installed (required)  : yes
    have zstd installed                : no
    debug branch prediction            : no
    gprof support                      : no
    gcov support                       : no
    run all tests under valgrind       : no
    gcc undefined behaviour sanitizer  : no
    use rpath in tests                 : no
    test biarch                        : no

Then running make but I get this error:

$ make
make --no-print-directory all-recursive
Making all in config
make[2]: Nothing to be done for 'all'.
Making all in lib
  CC       xstrdup.o
  CC       xstrndup.o
  CC       xmalloc.o
[...]
  CC       disasm_str.os
  CC       symbolhash.os
  AR       libasm_pic.a
  CCLD     libasm.so
Making all in debuginfod
make[2]: Nothing to be done for 'all'.
Making all in src
  CC       readelf.o
  CCLD     readelf
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: warning: libz.so.1, needed by ../libdw/libdw.so, not found (try using -rpath or -rpath-link)
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: warning: libzstd.so.1, needed by ../libdw/libdw.so, not found (try using -rpath or -rpath-link)
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: warning: liblzma.so.5, needed by ../libdw/libdw.so, not found (try using -rpath or -rpath-link)
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `lzma_auto_decoder@XZ_5.0'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `gzclose'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libelf/libelf.so: undefined reference to `inflate'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `ZSTD_isError'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `gzdopen'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `ZSTD_freeDCtx'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libelf/libelf.so: undefined reference to `deflate'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libelf/libelf.so: undefined reference to `deflateInit_'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `gzread'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libelf/libelf.so: undefined reference to `inflateEnd'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `ZSTD_createDCtx'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `lzma_end@XZ_5.0'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `gzerror'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `lzma_code@XZ_5.0'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libelf/libelf.so: undefined reference to `deflateEnd'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libelf/libelf.so: undefined reference to `inflateInit_'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `ZSTD_decompressStream'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libelf/libelf.so: undefined reference to `inflateReset'
/usr/local/lib/gcc/riscv64-unknown-linux-gnu/10.2.0/../../../../riscv64-unknown-linux-gnu/bin/ld: ../libdw/libdw.so: undefined reference to `gzdirect@ZLIB_1.2.2.3'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:686: readelf] Error 1
make[1]: *** [Makefile:529: all-recursive] Error 1
make: *** [Makefile:445: all] Error 2

Why does the linker not find libz.so.1, libzstd.so.1 and liblzma.so.5? The libraries are available as you can see here:

$ find /usr/local/riscv64-unknown-linux-gnu -name "libz.so.*"
/usr/local/riscv64-unknown-linux-gnu/lib/libz.so.1.2.11
/usr/local/riscv64-unknown-linux-gnu/lib/libz.so.1
$ find /usr/local/riscv64-unknown-linux-gnu -name "libzstd.so.*"
/usr/local/riscv64-unknown-linux-gnu/lib/libzstd.so.1
/usr/local/riscv64-unknown-linux-gnu/lib/libzstd.so.1.5.0
$ find /usr/local/riscv64-unknown-linux-gnu -name "liblzma.so.*"
/usr/local/riscv64-unknown-linux-gnu/lib/liblzma.so.5.2.5
/usr/local/riscv64-unknown-linux-gnu/lib/liblzma.so.5


Solution

  • I needed to add LIBS="-lz -lzstd -llzma". The full configuration command looks like this:

    LIBS="-lz -lzstd -llzma" ./configure --build=x86_64-linux-gnu --host=riscv64-unknown-linux-gnu --disable-libdebuginfod --disable-debuginfod --prefix=/usr/local/riscv64-unknown-linux-gnu
    

    I expected, that the flags were already set by the configure script and the makefiles ... but for some reason they are not if the libs are dynamically linked.

    src/Makefile.am: (zip_LIBS= -lzstd -llzma)

    [...]
    if BUILD_STATIC
    libasm = ../libasm/libasm.a
    libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) -ldl -lpthread
    libelf = ../libelf/libelf.a -lz
    else
    libasm = ../libasm/libasm.so
    libdw = ../libdw/libdw.so
    libelf = ../libelf/libelf.so
    endif
    [...]