TS-7600 Cross Compiling

From Technologic Systems Manuals

While it is recommend to develop entirely on the SBC itself, it is also possible to develop from an x86 compatible Linux system using a cross compiler. For this SBC use the cross compiler located here. The resulting binary will be for ARM.

[user@localhost]$ /path/to/arm-fsl-linux-gnueabi/bin/arm-linux-gcc hello.c -o hello
[user@localhost]$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

This is one of the simplest examples. For working with a larger project a Makefile will typically be used. More information about Makefiles is available here. Another common requirement is linking to third party libraries provided by Debian on the SBC. There is no exact set of steps for every project when cross compiling, but the process will be very much the same. Provide the cross compiler with access to the necessary headers, libraries, and source files, and install the binary on the target. The following example will link to sqlite from Debian.

Install the sqlite library and header on the SBC:

apt-get update && apt-get install -y libsqlite3-0 libsqlite-dev

This will fetch the binaries from the internet and install them on the SBC. The installed files can then be listed with dpkg:

dpkg -L libsqlite3-0 libsqlite3-dev

The needed files from this output will be the .h and .so files, they will need to be copied to the project directory on the cross-compling host.

See the example with libsqlite3 below. This is not intended to provide any functionality, but just call functions provided by sqlite.

#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"

int main(int argc, char **argv)
{
	sqlite3 *db;
	char *zErrMsg = 0;
	int rc;
	printf("opening test.db\n");
	rc = sqlite3_open("test.db", &db);
	if(rc){
		fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
		sqlite3_close(db);
		exit(1);
	}
	if(rc!=SQLITE_OK){
		fprintf(stderr, "SQL error: %s\n", zErrMsg);
	}
	printf("closing test.db\n");
	sqlite3_close(db);
	return 0;
}

To build this with the external libraries the makefile below can be used. This will have to be adjusted for the proper toolchain path. In this example, the headers are located in external/include and the library in external/lib.

CC=/opt/arm-2008q3/bin/arm-none-linux-gnueabi-gcc
CFLAGS=-c -Wall

all: sqlitetest

sqlitetest: sqlitetest.o
        $(CC) sqlitetest.o external/lib/libsqlite3.so.0 -o sqlitetest
sqlitetest.o: sqlitetest.c
        $(CC) $(CFLAGS) sqlitetest.c -Iexternal/include/

clean:  
        rm -rf *o sqlitetest.o sqlitetest

The resulting binary can be copied to the target and executed. There are many ways to transfer the compiled binaries to the board. Using a network filesystem such as sshfs or NFS will be the simplest to use if needed frequently during development, but will require a setup. See the host linux distribution's manual for more details. The simplest network method is using ssh/sftp. If running Windows, winscp can be used, or just scp in linux. Make sure a password is set for a user account, root or otherwise, in order to properly ssh or scp files to the target. From winscp, enter the ip address of the SBC, the root username, and the password; this will create an explorer window that can use drag-and-drop of files to copy them to the target.

For scp in linux, run:

#replace with the binary name and the SBC IP address
scp sqlitetest root@192.168.0.50:/root/

After transferring the file to the board, execute it:

ts:~# ./sqlitetest 
opening test.db
closing test.db