What Is a Sysroot Exactly and How to Create One

What is a sysroot exactly and how do I create one ?

A sysroot is a directory which is considered to be the root directory for the purpose of locating headers and libraries. So for example if your build toolchain wants to find /usr/include/foo.h but you are cross-compiling and the appropriate foo.h is in /my/other/place/usr/include/foo.h, you would use /my/other/place as your sysroot.

meaning of --sysroot=$SDKTARGETSYSROOT?

This has got to do more with the cross canadian compiler (GCC in this case) rather than Yocto, the Yocto Project wires its compiler logic using the --sysroot argument passed to GCC:
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html

This tells GCC to treat whats passed as --sysroot as if it was the sysroot on a typical compilation on target, e.g. usually GCC expects to find headers in /usr/include or libraries in /usr/lib , if we pass --sysroot=/foo/ then it will automatically look at /foo/usr/include and /foo/usr/lib respectively.

The toolchain scripts in the Yocto Project use --sysroot=SDKTARGETSYSROOT to pass the directory where the SDK is installed, hence it finds the proper header and libs to be able to cross compile from the SDK, for more info: https://git.yoctoproject.org/poky/tree/meta/classes/toolchain-scripts.bbclass

Now why is GCC outside that directory?, because that directory only contains files for the target architecture (hence SDKTARGETSYSROOT, SDK: for the SDK, TARGET: meant for the target arch, SYSROOT: the sysroot to be used), and GCC is not.
GCC is compiled to run in your HOST, hence it doesnt belong in that directory, it is precisely why you see the x86_64-pokysdk-linux part of the path where GCC is actually installed in, your HOST triplet is a 64 bit x86 architecture, an SDK built by poky (Yocto), and its OS is Linux.

How to create a cross-compilation sysroot for Linux?

You should be able to build rpm2cpio on OSX, and then unpack thus:

mkdir /desired/sysroot && cd /desired/sysroot
for j in /path/to/iso/*.rpm; do
rpm2cpio $j | cpio -idmB
done

But it might be easier to just unpack on a Linux host (perhaps inside a VM).

ld.exe cannot find /lib/libc.so.6 even after sysroot set

Thanks @n-1-8e9-wheres-my-share-m and @infinitezero for giving advice on how to debug this problem. Now I can answer it by myself.

The crucial point is that ld.exe does not always follow SYS_ROOT or see it as a virtual filesystem root.

It services as a shortcut for including a complete set of headers and libraries (usually useful when doing cross compilation). The documentation says:

--sysroot=dir

Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers in /usr/include and libraries in /usr/lib, it instead searches dir/usr/include and dir/usr/lib.

But the document omits some special rules. As was discussed here,

You misunderstand GNU ld's --sysroot rule, which is applicable in these two cases:

  • when a path begins with = or $SYSROOT
  • (Only) in case a sysroot prefix is configured, and the filename starts with
    the ‘/’ character
    , and the script being processed was located inside
    the sysroot prefix
    , the filename will be looked for in the sysroot
    prefix.

Otherwise, ld will only look at the absolute path defined in the script (/lib/xxx), instead of {SYS_ROOT}/lib/xxx.

So a quick fix for my problem is to change the ld script gtkHelloWorld/lib/libc.so in my project to

/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( =/lib/libc.so.6 =/usr/lib/libc_nonshared.a AS_NEEDED ( =/lib/ld-linux.so.3 ) )

Then it compiles normally.

Ref: for those who'd like to explore more about ld script, this is a comprehensive doc.



Related Topics



Leave a reply



Submit