Anybody have info on steps to setup Tegra K1 cross compiles to run on x86 Ubuntu 12.04?
What do you want to cross compile? Some projects (e.g. the kernel) support cross compilation natively and with those it’s usually very simple. But cross compiling some other projects might be non-trivial.
Generally speaking you can just install the ARM harfloat EABI cross compiler from the Ubuntu repositories and use it to create ARMv7 binaries that will run on Tegra K1 (and on any other ARMv7 CPU).
Something like this:
$ sudo apt-get install gcc-arm-linux-gnueabihf
$ arm-linux-gnueabihf-gcc main.c -o arm-main
$ file arm-main
arm-main: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31, BuildID[sha1]=0x1fd75bbdd5955c5787dc001b2d400fa5b1da2fc5, not stripped
The tricky part are the shared libraries. You need ARM version of all the dependencies in a path that the linker uses. And the shared libraries should match closely what you have on the target board.
Jetson is quite fast so it’s possible to compile even bigger projects natively on the board itself.
If you are working with OpenCV and/or ROS and cross-compiling that, if you could share the binaries it’d be appreciated!
Thanks Kulve,
I was hoping NVidia would have recommendations as to toolchain, compiler settings etc. I also hoped the sample rootfs would have the needed libs/includes etc. At the moment I’m trying to build Qt5, but in general I need to be able to build various packages for several targets, so cross compiles on a Linux dev machine are most useful to me.
I’ve pulled the Linaro 4.8 binaries and, for Qt, guessed at a device mkspec. I also found I needed to copy the /usr/lib and /usr/include dirs from the target – oddly, the sample rootfs seems to be missing some basic headers and libs (or at least symlinks to the libs that are there).
Configure ran and it’s building now. Fingers crossed…
…the cross compile approach above appears to work after deleting the original target Qt libs and fixing a few broken symlinks (e.g. libm.so uses absolute path to /lib/…). At least the few Qt examples I’ve cross compiled run correctly.
Summarizing:
- follow NVidia recipe for creating a bootable image (need the rootfs): https://developer.nvidia.com/sites/default/files/akamai/mobile/files/L4T/l4t_quick_start_guide.txt
- pull the Linaro 4.8 toolchain binaries: http://releases.linaro.org/14.04/components/toolchain/binaries/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux.tar.xz
- replace rootfs usr/lib and usr/include with the versions copied from the dev board (make sure to keep symlinks intact, e.g., use rsync -rl)
- fix absolute symlinks (I had to fix libz.so, libm.so, libdl.so) to point to your replaced usr/lib versions
Then set your favorite build system (cmake or whatever) to use the linaro ./bin/arm-linux-gnueabihf-xxx tools.
Correction: point symlinks to your rootfs/lib version.
Having all the “needed” header files already on the default image would mean having absolutely everything there as everybody have their own goals and projects.
Cross compiling bigger projects is an art of its own. Generally speaking I would recommend compiling natively on the board as that is so much easier and you can get dependencies with apt-get. It is also possible to create a ARM hardfloat rootfs on your PC with debootstrap and you can even chroot to it and run binaries there with small qemu configuration to e.g. install more dependencies. Maybe you could use that as the rootfs for cross compilation.
Sorry, I should have been more clear. By “needed” I just meant needed to cross compile the kinds of programs you can natively compile on the board out of the box. Hopefully at that point you have enough to pull and cross compile from source for other packages.
And I agree that going with native compilation is great if it meets your needs. Those building for multiple targets, running distributed builds, etc. probably still need a cross compile environment.
Additional info on cross-compiling CUDA (assuming you’ve followed the general steps above):
- on your build machine, install the appropriate CUDA toolkit, e.g.: http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1204/x86_64/cuda-repo-ubuntu1204_6.0-37_amd64.deb
- also install the CUDA toolkit on the TK1 target board: https://developer.nvidia.com/rdp/assets/cuda-l4t-r192
- copy /usr/local/cuda and /usr/local/cuda-6.0 from the target to your build machine (preserving symlinks) – these go under your cross compile rootfs
- the key now is to point your BUILD machine’s nvcc to your cross compiler g++ – see: NVCC :: CUDA Toolkit Documentation
- in your makefiles, you’ll also need to add -I and -L options that point to your rootfs’ CUDA include/lib (under $ROOTFS/usr/local/cuda-6.0/targets/armv7-linux-gnueabihf/)
As a sanity check, if you follow the first 3 steps above (install CUDA build/target toolkits; copy cuda-6.0 to your rootfs), you can then cross-compile the CUDA samples:
- export GCC=
- export ARMv7=1
- export TARGET_FS=
- export EXTRA_CCFLAGS=-I<your-cuda-6.0-include-from-your-target>
- export EXTRA_LDFLAGS=-L<your-cuda-6.0-lib-from-your-target>
- cd $ROOTFS/usr/local/cuda-6.0/samples
- make
This post here explains how to configure cross compiling with Qt on Ubuntu and has some scripts to automate the process for setting up the environment, [url]https://devtalk.nvidia.com/default/topic/1015414/jetson-tx2/cross-compiling-with-qt/[/url].