-- Main.PiotrTrojanek - 09 Nov 2009

This is a mini-howto for creating GNAT cross compiler on a Linux host for QNX target.

For native QNX GNAT compiler please visit http://www.ajam.org.pl. I would like to thank the author of this build for inspiration!

Please note: most of the patching required to make cross-target build has been taken from the native build above.

Getting the sources, etc.

You will have to download the following in order to build cross compiler.

Cross-target binutils

I assume that the QNX Linux host tools are already installed. In general it is possible to do full cross-target build, but it seems easier to use cross-binutils already available.

GNAT compiler for the host

GNAT compiler for the host (Linux), which is necessary to bootstrap the cross GNAT build. You can download the binary from Libre website or use the one packaged for your Linux distribution.

Note: for some reason (probably glibc version mismatch) I had to substitute Libre package header files, probably to match my gentoo GLIBC version:

# cd /opt/gnat-2010-i686-gnu-linux-libc2.3-bin/lib/gcc/i686-pc-linux-gnu/4.3.6/include-fixed
# mv sys/sysmacros.h sys/sysmacros.h.bak
# mv sys/stat.h sys/stat.h.bak

GCC/GNAT source codes

I have compiled the current QNX trunk version of gcc (tested with revision 398), available for download after login with QNX account. You can probably try with different GCC version (mainstream or AdaCore Libre). For the latest GCC-4.5 snapshot (gcc-4.5-20091029) the Ada part did not compile.

Patch the GCC source code

Apply the following patch to enable QNX specific file GNAT sources substitutions as well as one small fixup taken from GCC upstream:

Building the cross-compiler

It is necessary to make a symbolic link for a generic ranlib tool:

# ln -s $QNX_HOST/usr/bin/i386-pc-nto-qnx6.4.0-ranlib i386-pc-nto-qnx6.4.0-ranlib-2.19

Prepare empty build directory, ie. mkdir build-gcc and issue the following configure script invocation:

../gcc/configure \
        --build=i686-pc-linux-gnu \
        --target=i386-pc-nto-qnx6.4.0 \
        --enable-cheaders=c \
        --with-as=$QNX_HOST/usr/bin/ntox86-as \
        --with-ld=$QNX_HOST/usr/bin/ntox86-ld \
        --with-sysroot=$QNX_TARGET/ \
        --libdir=$QNX_HOST/usr/lib \
        --libexecdir=$QNX_HOST/usr/lib \
        --prefix=$QNX_HOST/usr \
        --exec-prefix=$QNX_HOST/usr \
        --with-local-prefix=$QNX_HOST/usr \
        --enable-languages=c++,ada \
        --enable-threads=posix \
        --disable-nls \
        --disable-libssp \
        --disable-tls \
        --disable-libstdcxx-pch \
        --enable-libmudflap \
        --enable-__cxa_atexit \
        --with-gxx-include-dir=$QNX_TARGET/usr/include/c++/4.3.3 \
        --with-bugurl=http://www.qnx.com/support/bugreports \
        --enable-shared

Note: if you want to build stripped down version of the binaries export appropriate environment variables, ie. export LDFLAGS="-Wl,-s" (see this post).

Issuing make command takes some time, but after that you can do make install as superuser. This will put the compiled stuff in $QNX_HOST folder, but you can change this with different prefixes in configure invocation.

Running cross-target ACATS check

Running the ACATS tests with cross compiler is somewhat tricky.

You need to setup rsh access to QNX node and sharing of cross-build directory between Linux host and QNX node.

Enabling rsh QNX access

For the rsh access it is necessary to uncomment the following lines in QNX's /etc/inetd.conf:

#
# Shell, login, exec are BSD protocols.
#
shell   stream  tcp     nowait:1000     root    /usr/sbin/rshd  in.rshd
login   stream  tcp     nowait  root    /usr/sbin/rlogind       in.rlogind

Please make sure that :1000 is appended to nowait. It is necessary to increase allowed number of connections per minute (defaults to 40), since every run of ACATS test is done by rsh command.

Enabling NFS QNX access

QNX node needs access to test executables compiled on the host filesystem. I use the following entry in the /etc/exports on my Linux box:

/home/ptroja/ports/qnx 192.168.0.0/255.255.0.0(rw,root_squash,anonuid=1000,anongid=1000,async,no_subtree_check)

It is good to have anonuid/anongid options matching your normal (non-superuser) Linux account:

$ id
uid=1000(ptroja) gid=1000(ptroja)

Finally mount the shared host directory on QNX node:

# fs-nfs3 192.168.2.100:/home/ptroja/ports/qnx /home/ptroja/ports/qnx

Enabling cross-target testing

You need to make some fixes to ACATS testing framework in order to execute tests on the remote QNX machine

Do not forget to change the QNX node IP address in gcc/testsuite/ada/acats/run_all.sh file.

Running the ACATS check

You can run the ACATS test from the build's gcc directory with the following command:

build-gcc/gcc $ make check-ada

You can inspect the test's results in the files acats.log and acats.sum in the build-gcc/gcc/testsuite/ada/acats directory (attached).

At the moment the following tests fail: