Linking Libraries For Cross Compiling for Raspberry Pi

Ames Computer Geek Corner News Linking Libraries For Cross Compiling for Raspberry Pi NYC New York City North Bergen County
https://www.raspberrypi.org/

To cross compile for the Raspberry Pi, you will need to setup a toolchain such as crosstools-ng. The tutorials found on the internet for setting up crosstools-ng seems straight forward at first and the hello world compile runs great with it. However, what many tutorials fail to mention is linking libraries. On the pi, some libraries are stored in /usr/lib/arm-linux-gnueabihf/ but the toolchains linker does not search that path, it only searches /lib, /usr/lib and /usr/local/lib.

The problem lies with the linker. The linker that comes with the binutils that gets pulled in by crosstool-ng does not search the arm-linux-gnueabihf. This directory has to do with Debian multiarch, and in order to get a linker that looks in such a directory, binutils needs to be patched. The instructions that follow assume you have already installed crosstool-ng and generated a ct-ng config.


On a Raspberry Pi, install the bunutils source package which will give access to a patch file located in /usr/src/binutils/patches.


sudo apt install binutils-source



On the host machine, you need to add a patches directory in the directory where where the ct-ng config file is. It must have a specific structure that reflects the structure of packages in the crosstool-ng repo inside patches/ you must have a directory with the package name, inside that you must have the version number, and inside that is where you place the patch.


$ cd your_toolchain_directory
$ mkdir -p patches/binutils/2.31.1/



Now copy the patch file from the pi to the host, in this example, we will be using 129_multiarch_libpath.patch:

$ cd patches/binutils/2.31.1/
$ scp pi@raspberrypi:/usr/src/binutils/129_multiarch_libpath.patch

Now that we have the patch, we need to update the config file to tell ct-ng to include local patches as well as enable the multiarch flag for gcc. You can do this using ct-ng menuconfig so change back to the directory with the config file and run ct-ng menuconfig. Go to the path and misc options and change the patches origin to bundled then local and add ${CT_TOP_DIR}/patches as the local patch directory. This should produce the following lines under the extracting section of the .config file:


CT_PATCH_BUNDLED_LOCAL=y
CT_PATCH_ORDER="bundled,local"
CT_PATCH_USE_LOCAL=y
CT_LOCAL_PATCH_DIR="${CT_TOP_DIR}/patches"

Next we need to add the --enable-multiarch flag in the gcc options. Again using menuconfig, go to the C compiler settings. Add --enable-multiarch to the gcc extra config setting. After making the changes, save the config. The config file should have the following in the gcc settings:


CT_CC_GCC_EXTRA_CONFIG_ARRAY="--enable-multiarch"



Before we can build the toolchain, we need to export the variable:


$ export DEB_TARGET_MULTIARCH=arm-linux-gnueabihf



Finally, we can build the toolchain using ct-ng build. After building the toolchain, change into the bin directory of the toolchain and check if you see the library in the compile path by running the following command:


$ ./ld --verbose | grep -i "search"