-
Notifications
You must be signed in to change notification settings - Fork 27
Building with Advance Toolchain cross compiler
A cross compiler is a compiler that runs in a certain processor architecture (host architecture) but is able to generate executable code to a different processor architecture (target architecture) 1.
The Advance Toolchain provides cross compilers that run on x86 and generate code for Power which help teams to start developing for Power without having immediate access to a POWER server. A cross compiler doesn't completely remove the dependency on the target processor because users still have to test and run the executable code on a different processor.
GNU wget 2 is a small program that highlights the important problems when cross compiling a certain software: it depends on libraries provided by the Advance Toolchain cross compiler and external libraries.
In this example, we'll build GNU wget for POWER little-endian, using a x86 computer with the Advance Toolchain cross compiler.
Firstly, it is necessary to copy all necessary libraries and headers to a certain directory. In this example I'll use:
- Headers: ${HOME}/wget/include
- Libraries: ${HOME}/wget/lib
In this case, ${HOME} is a shell variable holding the path of my home directory.
For GNU wget, we need to provide some OpenSSL libraries and Zlib. Both of them are available in the Advance Toolchain native compiler. However, the list of necessary libraries may vary according to the project. If you don't know well the project you can use the following tools in order to identify the list of libraries they use:
ldd <executable> rpm -q --requires -p <package.rpm> dpkg-deb -f <package.deb> | grep "Depends:"
Usually the list of libraries necessary to build a project is the same across all processor architectures. So, you may use the above commands against an executable or package compiled for another processor.
This is the list of files required in order to build wget:
$ ls -1 ${HOME}/wget/include/ openssl/ zconf.h zlib.h $ ls -1 ${HOME}/wget/lib/ libcrypto.so libcrypto.so.1.0.0 libssl.so libssl.so.1.0.0 libz.so libz.so.1 libz.so.1.2.6
Make sure the libraries are really compiled for the target processor. If they don't match, you won't be able to use them. You may use 'readelf -h' to verify this information:
$ /opt/at7.1/bin/powerpc64le-linux-gnu-readelf -h ${HOME}/wget/lib/libz.so.1.2.6 ... Data: 2's complement, little endian ... Machine: PowerPC64 ...
With the header files and libraries in place, the system is ready to start the build. So, create a separate build directory:
mkdir ${HOME}/wget/build && cd ${HOME}/wget/build
After entering the separate build directory, it's possible to configure the build by running:
CC=/opt/at7.1/bin/powerpc64le-linux-gnu-gcc \ CFLAGS="-I${HOME}/wget/include" \ LDFLAGS="-L${HOME}/wget/lib" \ ../wget-1.15/configure \ --host=powerpc64le-linux \ --with-ssl=openssl
Where:
- CC specifies which compiler to use. In this case, Advance Toolchain 7.1 cross compiler for POWER little endian. Cross compilers usually have a prefix in their program name to clearly indicate they won't generate executable code for the current processor. In this case, the prefix is "powerpc64le-linux-gnu-". This rule applies to all programs, e.g. g++, gdb, ld, as, etc.
- CFLAGS="-I" indicates where the compiler will find the header files.
- LDFLAGS="-L" indicates where the linker will find the libraries.
- ../wget-1.15 this is the directory where wget source code is available. In this case it is the same of ${HOME}/wget/wget-1.15.
- --host=powerpc64le-linux indicates this code will run on POWER little endian.
- --with-ssl=openssl forces wget to use OpenSSL.
Finally, build wget:
make
After running this you'll find the program available at ${HOME}/wget/build/src/wget.
You can now copy it to a POWER little endian system with the Advance Toolchain runtime package installed and run it.
- Are cross compiler builds slower?
- If I build a program using a cross compiler will it be slower than using a native toolchain?
- My project doesn't allow to pass flags to the linker or to the compiler. How can I use extra libraries?
Not necessarily. It depends on the code being built and the level of optimization in use.
No. There are some differences in the metadata of the binaries, but it will run at the same speed.
My project doesn't allow to pass flags to the linker or to the compiler. How can I use extra libraries?
In this case, it isn't possible to pass -I to the compiler or -L to linker and the only possible solution is to save the headers and libraries in one of the Advance Toolchain directories:
-
For POWER big endian (ppc or ppc64):
/opt/atX.X/ppc/usr/include
/opt/atX.X/ppc/usr/lib (32-bit libraries)
/opt/atX.X/ppc/usr/lib64 (64-bit libraries) -
For POWER little endian (ppc64le):
/opt/atX.X/ppc64le/usr/include
/opt/atX.X/ppc64le/usr/lib64
1 Wikipedia - Definition of cross compilers: http://en.wikipedia.org/wiki/Cross_compiler
2 GNU wget project page: https://www.gnu.org/software/wget/