ARM Embedded (Command Line)
This page will provide instructions for cross-compiling Crypto++ with Ubuntu's GNU C++ compiler for armel architecture. The tools are available in the g++-arm-linux-gnueabi
and gcc-arm-linux-gnueabi
packages.
There are four steps to building Crypto++ for embedded targets, and the process will create an embedded ARM version of cryptest.exe, the dynamic library, and the static library. After building the library, you can push cryptest.exe and the test vectors to the device. Once on the device, you can then execute the tests using a remote shell. The example below builds for the Cortex-M3 processor using the arm-linux-gnueabi
toolchain.
Note: setenv-embedded.sh
was added to the library sources in March 2016. It is available in Git and library ZIP files after 5.6.3. Also see Commit 22d6374ce7151ad0, Added Android and embedded environment and test script.
If you are build for Android or iOS, then there are separate pages for the platforms. The pages use the toolchains provided by AOSP and Apple. See Android (Command Line) and iOS (Command Line) for details. Also see ARM (Command Line) and ARM Embedded (Bare Metal) if building with the arm-linux-gnueabi
toolchain.
Note: the instructions below used to work with Ubuntu 12 or so. Ubuntu 14 and Ubuntu 16 appears to have toolschain problems. The toolchain cannot link an executable; also see Issue 565, Cross Compile for ARM Failure in the Crypto++ bug tracker. Please open bugs against package gcc-arm-linux-gnueabihf or g++-arm-linux-gnueabihf at Ubuntu Launchpad.
Install the Package
Installing the package is as simple as installing g++-arm-linux-gnueabi
and gcc-arm-linux-gnueabi
.
sudo apt-get update sudo apt-get install g++-arm-linux-gnueabi gcc-arm-linux-gnueabi
Set the Environment
Before you begin you must set the cross-compilation environment. Setting the environment will do two things. First, it will ensure the arm-linux-gnueabi toolchain is on-path. Second, it will ensure some environmental variables are set so the makefile picks up specific device flags. For example, the script will set IS_ARM_EMBEDDED
, ARM_EMBEDDED_FLAGS
and ARM_EMBEDDED_SYSROOT
.
Perform the following to run the script. The source
command is required to make changes to the current shell.
$ source ./setenv-embedded.sh CPP: /usr/bin/arm-linux-gnueabi-cpp CXX: /usr/bin/arm-linux-gnueabi-g++ AR: /usr/bin/arm-linux-gnueabi-ar LD: /usr/bin/arm-linux-gnueabi-ld RANLIB: /usr/bin/arm-linux-gnueabi-ranlib ARM_EMBEDDED_TOOLCHAIN: /usr/bin ARM_EMBEDDED_CXX_HEADERS: /usr/arm-linux-gnueabi/include/c++/5.4.0 ARM_EMBEDDED_FLAGS: -I/usr/arm-linux-gnueabi/include/c++/5.4.0 -I/usr/arm-linux-gnueabi/include/c++/5.4.0/arm-linux-gnueabi ARM_EMBEDDED_SYSROOT: /usr/arm-linux-gnueabi
You can tune the ARM_EMBEDDED_FLAGS
by opening setenv-embedded.sh
, scrolling down to line 100 or so, and changing the block below.
if [ -z "$ARM_EMBEDDED_FLAGS" ]; then export ARM_EMBEDDED_FLAGS="-I$ARM_EMBEDDED_CXX_HEADERS -I$ARM_EMBEDDED_CXX_HEADERS/arm-linux-gnueabi" fi
Build the Library
Building the library consists of running the following command after setting the environment:
$ make -f GNUmakefile-cross
If you plan on stripping the dead code, then you should issue make -f GNUmakefile-cross lean
. The lean
target builds libcryptopp.a
, libcryptopp.so
and cryptest.exe
; and it adds -ffunction-sections -fdata-sections
for you. When you link your shared object or application, you will still need to add -Wl,--gc-sections
to perform the stripping of the dead code from the final executable.
$ make -f GNUmakefile-cross static static dynamic cryptest.exe /usr/bin/arm-linux-gnueabi-g++ -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM -mthumb -mcpu=cortex-m3 -I/usr/arm-linux-gnueabi/include/c++/4.7.3 -I/usr/arm-linux-gnueabi/ include/c++/4.7.3/arm-linux-gnueabi --sysroot=/usr/arm-linux-gnueabi -c 3way.cpp /usr/bin/arm-linux-gnueabi-g++ -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM -mthumb -mcpu=cortex-m3 -I/usr/arm-linux-gnueabi/include/c++/4.7.3 -I/usr/arm-linux-gnueabi/ include/c++/4.7.3/arm-linux-gnueabi --sysroot=/usr/arm-linux-gnueabi -c adler32.cpp /usr/bin/arm-linux-gnueabi-g++ -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM -mthumb -mcpu=cortex-m3 -I/usr/arm-linux-gnueabi/include/c++/4.7.3 -I/usr/arm-linux-gnueabi/ include/c++/4.7.3/arm-linux-gnueabi --sysroot=/usr/arm-linux-gnueabi -c algebra.cpp ... /usr/bin/arm-linux-gnueabi-g++ -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM -mthumb -mcpu=cortex-m3 -I/usr/arm-linux-gnueabi/include/c++/4.7.3 -I/usr/arm-linux-gnueabi/include/ c++/4.7.3/arm-linux-gnueabi --sysroot=/usr/arm-linux-gnueabi -shared -o libcryptopp.so 3way.o ... vmac.o wait.o wake.o whrlpool.o winpipes.o xtr.o xtrcrypt.o zdeflate.o zinflate.o zlib.o ... /usr/bin/arm-linux-gnueabi-g++ -o cryptest.exe -DNDEBUG -g2 -Os -pipe -fPIC -DCRYPTOPP_DISABLE_ASM -mthumb -mcpu=cortex-m3 -I/usr/arm-linux-gnueabi/include/c++/4.7.3 -I/usr/arm-linux-gnueabi/include/c++/4.7.3/arm-linux-gnueabi --sysroot=/usr/arm-linux-gnueabi bench.o bench2.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o dlltest.o ./libcryptopp.a
After building the library, check it for architecture:
$ find . -name cryptest.exe ./cryptest.exe $ /usr/bin/arm-linux-gnueabi-readelf -h ./cryptest.exe | grep -i 'class\|machine' Class: ELF32 Machine: ARM $ find . -name libcryptopp.so ./libcryptopp.so $ /usr/bin/arm-linux-gnueabi-readelf -h ./libcryptopp.so | grep -i 'class\|machine' Class: ELF32 Machine: ARM
Execute the Program
To be determined.
Architecture Options
The following table provides some options to use for ARM_EMBEDDED_FLAGS
in setenv-embedded.sh
. The table below was shamelessly ripped from Terry Guo's GNU Tools for ARM Embedded Processors README:
+------------------------------------------------------------------+ | ARM Core | Command Line Options | multilib | |----------|--------------------------------------------|----------| |Cortex-M0+| -mthumb -mcpu=cortex-m0plus | armv6-m | |Cortex-M0 | -mthumb -mcpu=cortex-m0 | | |Cortex-M1 | -mthumb -mcpu=cortex-m1 | | | |--------------------------------------------| | | | -mthumb -march=armv6-m | | |----------|--------------------------------------------|----------| |Cortex-M3 | -mthumb -mcpu=cortex-m3 | armv7-m | | |--------------------------------------------| | | | -mthumb -march=armv7-m | | |----------|--------------------------------------------|----------| |Cortex-M4 | -mthumb -mcpu=cortex-m4 | armv7e-m | |(No FP) |--------------------------------------------| | | | -mthumb -march=armv7e-m | | |----------|--------------------------------------------|----------| |Cortex-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp | armv7e-m | |(Soft FP) | -mfpu=fpv4-sp-d16 | /softfp | | |--------------------------------------------| | | | -mthumb -march=armv7e-m -mfloat-abi=softfp | | | | -mfpu=fpv4-sp-d16 | | |----------|--------------------------------------------|----------| |Cortex-M4 | -mthumb -mcpu=cortex-m4 -mfloat-abi=hard | armv7e-m | |(Hard FP) | -mfpu=fpv4-sp-d16 | /fpu | | |--------------------------------------------| | | | -mthumb -march=armv7e-m -mfloat-abi=hard | | | | -mfpu=fpv4-sp-d16 | | |----------|--------------------------------------------|----------| |Cortex-R4 | [-mthumb] -march=armv7-r | armv7-ar | |Cortex-R5 | | /thumb | |Cortex-R7 | | | |(No FP) | | | |----------|--------------------------------------------|----------| |Cortex-R4 | [-mthumb] -march=armv7-r -mfloat-abi=softfp| armv7-ar | |Cortex-R5 | -mfpu=vfpv3-d16 | /thumb | |Cortex-R7 | | /softfp | |(Soft FP) | | | |----------|--------------------------------------------|----------| |Cortex-R4 | [-mthumb] -march=armv7-r -mfloat-abi=hard | armv7-ar | |Cortex-R5 | -mfpu=vfpv3-d16 | /thumb | |Cortex-R7 | | /fpu | |(Hard FP) | | | |----------|--------------------------------------------|----------| |Cortex-A* | [-mthumb] -march=armv7-a | armv7-ar | |(No FP) | | /thumb | |----------|--------------------------------------------|----------| |Cortex-A* | [-mthumb] -march=armv7-a -mfloat-abi=softfp| armv7-ar | |(Soft FP) | -mfpu=vfpv3-d16 | /thumb | | | | /softfp | |----------|--------------------------------------------|----------| |Cortex-A* | [-mthumb] -march=armv7-a -mfloat-abi=hard | armv7-ar | |(Hard FP) | -mfpu=vfpv3-d16 | /thumb | | | | /fpu | +------------------------------------------------------------------+
You might encounter issues with Cortex and hard floating point options. If you receive an error similar to:
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/bin/ld: error: 3way.o uses VFP register arguments, libcryptopp.so does not /usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/bin/ld: failed to merge target specific data of file 3way.o ...
Then see GCC with Cortex-M4 hard float link error "X uses VFP register arguments, Y does not" on the GCC mailing list.
Downloads
setenv-embedded.sh - Download from GitHub
GNUmakefile-cross - Download from GitHub