CMake, cross compilation for Jetson TK1, makefile for Nsight

Hi,

I am currently working on an Stereo Vision project, which has to be ported to the Jetson TK1. The project is running on both Win and Linux, with or without the usage of the GPU and with different performance libraries, which will be deselected for the Jetson TK1 (so I just need the CUDA lib).

I tried some CUDA Samples on the target (remote: debugging, running and profiling).

My goal is to create a Eclipse CDT4 makefile that can be imported in the Nsight IDE and later on to perform remote debugging and profiling on the target.

The Host-PC has Ubuntu 14.04 with the JetPackTK1-1.0 (with CUDA 6.5).
I have already successfully built/run/tested the project on the host, but now I have to cross compile it and I hardly found any information how to do that. cmake-gui wants me to specify a tool-chain file but I am not sure which one or what exactly it is, or if NVIDIA already provided one.

On chooru.code (Loading...) I have found some information about CUDA in combination with CMake.

Questions:
Q1: Where/What is the tool-chain file and what is defined in it?
Q2: Do I have to make any adoptions in the existing CMakeList?
Q3: If have found to directories on my host: /usr/arm-linux-gnueabi and /usr/amr-linux-gnueabihf. So what is the purpose of those two? Furthermore I found the directory /usr/local/cuda-6.5/targets/armv7-linux-gnueabihf/{lib, include} … I guess it is the CUDA stuff compiled for the Jetson.
Q4: Does NVIDIA provide any documents for this topic?
Q5: What is the best practice using CMake in my case? (Unfortunately I cannot create a Nsight project from scratch)

So I want to know the best practice to achieve my goals and would be really glad if someone could help me, as I have already wasted some days in research.

Kind regards

I can’t answer all of the questions, but some of the basic terms used cause great confusion when introducing cross-compile. The answer as to where to get your cross toolochain depends on distribution…ubuntu has this in a package which works great (from what I’m told…I don’t have any ubuntu hosts), while others will probably use the linaro toolchain. In pretty much every case you will have the equivalent to all files used for building software, e.g., the equivalent to gcc or nm. These will have a name theme prefixed to them so they will not be directly named as gcc or nm. Here is what it would look like:

arm-linux-gnueabihf-gcc
arm-none-gnueabihf-gcc

In those two the “arm” is because it is ARMv7 architecture, such Cortex A15 on Jetson. “linux” versus “none” is for linux calling conventions versus bare metal; everything in jetson is “linux” except for the boot loader. When running the boot loader linux has not run…you could use “linux” in the boot loader but you would just complicate things with no benefit (everything else beyond boot loader must use “linux” instead of “none”). The “gnueabihf” says you are using the E ABI with hardware floating point support. All of this up to and including the hyphen just before “gcc”, including it’s full path, is a string which can be used to substitute plain gcc for this new architecture with all of its quirks. Typically a script will want “gcc”, and if there is a toolchain noted, it’ll silently prefix that string to get it…else it uses the file system search path. So I have multiple linaro toolchains on my fedora system. One such example toolchain has this file:

/usr/local/gcc-linaro-4.9-2014.12/bin/arm-linux-gnueabihf-gcc

In any project set up to enable cross compile (such as the linux kernel) a variable can be ignored, and it uses gcc…but if this variable in the Makefile is set, it uses the cross compile versions of all of the toolchain commands. That string for this particular example is:

/usr/local/gcc-linaro-4.9-2014.12/bin/arm-linux-gnueabihf-

If you look at kernel source the top level Makefile will have “ARCH” and “CROSS_COMPILE” variables such that if they pre-exist in the environment they will use those values. ARCH setting for Jetson in kernel sources is valid if “arm” is chosen; CROSS_COMPILE is valid if that prefix string is chosen. So for kernel compile I could do this on my x86_64 host:

export ARCH="arm"
export CROSS_COMPILE="/usr/local/gcc-linaro-4.9-2014.12/bin/arm-linux-gnueabihf-"
make .......

This is the general cross compile theme. Beware the cross compile of the kernel is very simple compared to many other cross compiles because the kernel has for a very very long time been cross compiled for many architectures. The linux kernel is basically the easiest cross compile you’ll ever find. Additional details are required for almost any other cross compile.

Hi linuxdev,

thank you so much for your comprehensive answer about cross compiling and it cleared many doubts!

For the cross compilation with cmake (the call in build directory looks like: cmake -DCMAKE_TOOLCHAIN_FILE=arm-gnueabihf.toolchain.cmake …) use the following cmake toolchain file:

# file name: arm-gnueabihf.toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(GCC_COMPILER_VERSION "4.8" CACHE STRING "GCC Compiler version")

set(FLOAT_ABI_SUFFIX "hf")

set(CMAKE_C_COMPILER    arm-linux-gnueabi${FLOAT_ABI_SUFFIX}-gcc-${GCC_COMPILER_VERSION})
set(CMAKE_CXX_COMPILER  arm-linux-gnueabi${FLOAT_ABI_SUFFIX}-g++-${GCC_COMPILER_VERSION})
set(ARM_LINUX_SYSROOT /usr/arm-linux-gnueabi${FLOAT_ABI_SUFFIX} CACHE PATH "ARM cross compilation system root") # search path for the cross compile toolchain

set(CMAKE_CXX_FLAGS           ""                    CACHE STRING "c++ flags")
set(CMAKE_C_FLAGS             ""                    CACHE STRING "c flags")
set(CMAKE_SHARED_LINKER_FLAGS ""                    CACHE STRING "shared linker flags")
set(CMAKE_MODULE_LINKER_FLAGS ""                    CACHE STRING "module linker flags")
set(CMAKE_EXE_LINKER_FLAGS    "-Wl,-z,nocopyreloc"  CACHE STRING "executable linker flags")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")
set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -mthumb -fdata-sections -Wa,--noexecstack -fsigned-char -Wno-psabi")

set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS    "-Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now ${CMAKE_EXE_LINKER_FLAGS}")

set(COMPILER_IS_ARM "1")       #flags for the CMakeList.txt
add_definitions(-D_ARM_TEGRA3) # C/C++ preprocessor macro, which will be used in many many files

With this toolchain file I could sucessfully create a binary and the shared libs for my project and I have already run the application on Jetson TK1.

Next step is to make use of the CUDA Code in the project and I will report it, if I managed to build it. → In this step I would need an answer for Q2, or I have to find a solution on my own ;)

I am still interessted in an answer for Q4 and for Q5 … I hope some gurus will help me.

Kind regards

I think I’m having a related issue. If I create an Eclipse project from CMake I can’t seem to be able to configure a remote toolchain. Was anyone able to do this correctly?