1

I'm trying to cross compile for arm-linux-gnueabihf on Ubuntu 16.04 x86_64 box. I use Cmake with toolchain.cmake file where perhaps all important is declared like :

set(CMAKE_C_COMPILER "/usr/bin/arm-linux-gnueabihf-gcc")
set(CMAKE_CXX_COMPILER "/usr/bin/arm-linux-gnueabihf-g++")
set(CMAKE_FIND_ROOT_PATH "/usr/arm-linux-gnueabihf")

It seems it generates all I need. But the make fails when linking executable target. Snooping around there I found that in the link.txt in <target>.dir I have g++ command. I expected to have there compiler from cross toolchain like arm-linux-gnueabihf-g++.

Looking into other link.txt in other <target> which is not executable but static library there is command from cross toolchain like /usr/bin/arm-linux-gnueabihf-ar.

Why do I have just g++ in link.txt at executable target instead of arm-linux-gnueabihf-g++?

Please help, or I'll get mad soon..

adding my toolchain.cmake file:

SET(CMAKE_CROSSCOMPILING TRUE)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR ARMV7)

set(CMAKE_C_COMPILER "/usr/bin/arm-linux-gnueabihf-gcc")
set(CMAKE_CXX_COMPILER "/usr/bin/arm-linux-gnueabihf-g++")

set(CMAKE_C_COMPILER_TARGET "/usr/bin/arm-linux-gnueabihf-gcc")
set(CMAKE_CXX_COMPILER_TARGET "/usr/bin/arm-linux-gnueabihf-g++")

SET(CMAKE_LINKER "/usr/bin/arm-linux-gnueabihf-g++")

# path exists, but not needed to actually compile this
set(CMAKE_FIND_ROOT_PATH "/usr/arm-linux-gnueabihf")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

SET(OpenBLAS_DIR /root/OpenBLAS/buildArm/lib/cmake/openblas)
zty
  • 51
  • 1
  • 7

1 Answers1

1

Checking for the correct Toolchain Prefix

Normally CMake does determine the prefix needed automatically (and stores it in internal variable _CMAKE_TOOLCHAIN_PREFIX). So please cross-check with something like:

message(STATUS "_CMAKE_TOOLCHAIN_PREFIX: ${_CMAKE_TOOLCHAIN_PREFIX}")

If the value is correct but you have a mixture of compiler tools with and without prefix, that could be the result of trying/changing things in the toolchain file. Please try to delete your binary output directory including CMake variable cache including the compiler ids and build from scratch again.

Checking if your Toolchain contains a Linker/Make Program

Are you sure that your toolchain also contains a linker/make programm? Otherwise CMake tries to search for alternatives. To check you could clear your PATH variable before the cmake call or check the cached variable with:

message(STATUS "CMAKE_MAKE_PROGRAM: ${CMAKE_MAKE_PROGRAM}")

I would recommend using Ninja for toolchains that do not come with their own make program. It's fast, easy to use and there is no mix-up with two GNU toolchains. Its just:

cmake -G "Ninja" -D... 

See also here.

Reduce your Toolchain to its simplest Form

If it still does not work, you can explicitly define the prefix for the compiler in your toolchain file with CMAKE_C_COMPILER_TARGET/CMAKE_CXX_COMPILER_TARGET global variables.

Try to build a simple "Hello World" program with a very basic/reduced toolchain file.

For an example see e.g. here:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(triple arm-linux-gnueabihf)

set(CMAKE_C_COMPILER gcc)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})

Try to Force the Toolchain Paths Settings

Please don't modify anything - with the exception of CMakeCache.txt - that CMake does create. It will be lost the next time CMake does run its configuration/generation steps again (e.g. when a toolchain or CMakeLists.txt file is changed).

You can always force the settings of the tool's paths in your toolchain file by using the set(... CACHE INTERNAL "") syntax. So in your case it would look like:

SET(CMAKE_LINKER "/usr/bin/arm-linux-gnueabihf-ld" CACHE INTERNAL "")
SET(CMAKE_AR "/usr/bin/arm-linux-gnueabihf-ar" CACHE INTERNAL "")

References

Community
  • 1
  • 1
Florian
  • 39,996
  • 9
  • 133
  • 149
  • Thank you @Florian. message prints out what I expect: '-- _CMAKE_TOOLCHAIN_PREFIX: arm-linux-gnueabihf-' I added to toolchain.cmake file lines defining 'set(CMAKE_CXX_COMPILER_TARGET "/usr/bin/arm-linux-gnueabihf-g++")' and for C compiler as well. Unfortunately it results same. What I found more is that it uses g++ and gcc everywhere. I mean also for compilation in build.make. So only the archiver (ar) is used proper one from toolchain for static lib packing. The compilers gcc and g++ are used from linux box not from toolchain. Please have you some idea what I could check? – zty Nov 09 '16 at 09:28
  • @zty Using the `gcc`/`g++` not `ar` for the linker call is normal. You are just missing the prefix. Can you please add the complete toolchain file content to your question? There has to be something else there conflicting with the compiler detection. – Florian Nov 09 '16 at 09:32
  • I edited my question. I added my toolchain.cmke file. @Florian I understand that g++ and gcc are used to compile and link. AR is used to pack static lib. It's clear. Bud I expected the gcc and g++ from toolchain to be use. Thank you very much. – zty Nov 09 '16 at 10:18
  • I also tried `export CXX=/usr/bin/arm-linux-gnueabihf-g++` and for gcc too. Did not help. It still uses g++ and gcc not from toolchain... Please, any suggestion? – zty Nov 09 '16 at 11:40
  • @zty Ok. Some things you can try: Don't specify `CMAKE_CROSSCOMPILING`. With `CMAKE_SYSTEM_NAME` its implicit. `CMAKE_CXX_COMPILER_TARGET` would only be `arm-linux-gnueabihf` (no paths, just the prefix without the trailing `-`). Are you sure that your toolchain also contains a `make` programm? Otherwise CMake tries to search for alternatives. To check you could clear your `PATH` variable before the `cmake` call or check the cached variable with `message(STATUS "CMAKE_MAKE_PROGRAM: ${CMAKE_MAKE_PROGRAM}")`. – Florian Nov 09 '16 at 11:54
  • Oh, I did not know the make should also be from toolchain. I'm affraid there is not any. `message` shows `make` NOT from toolchain just in bins on box. Should it be in toolchain? And where? Thank you. – zty Nov 09 '16 at 12:27
  • @zty I'm using [`Ninja`](https://ninja-build.org/) for toolchains that do not come with their own `make`. It's fast, easy to use and there is no mix-up with two GNU toolchains. Its just `cmake -G "Ninja" -D...` (see also [here](https://cmake.org/cmake/help/latest/generator/Ninja.html)). – Florian Nov 09 '16 at 14:50
  • Thank you for Ninja suggestion. I installed it. It seems I got to the same situation. If I use command `file` on some my produced `.o` file I see : `FFT.cpp.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped` . It probably means the native compiler was used instead of one from toolchain for arm. Correct? I snoop in ninja's files and I see for example for `rule CXX_COMPILER__myproject` `command g++`... It is probably not what I need. I also purged and re-installed toolchain and binutils stuff for arm... Did not help. Do you have any idea what I could check more? Thank you. – zty Nov 09 '16 at 16:39
  • Thanks to @Florian. I got deeper into all that stuff, I could analyze it and I found: 1) In `CMakeList.txt` in some condition I had `set(CMAKE_CXX_COMPILER g++)` which overwrote definition from toolchain file... 2) `cmake` do not set properly `CMAKE_AR, CMAKE_RANLIB` and `CMAKE_LINKER` in the `CMakeFiles\3.5.1\CMakeCXXCompiler.cmake` and in `CMakeCCompiler.cmake` - I wrote it there manually and then the build passed. – zty Nov 10 '16 at 18:52
  • @zty Your're welcome. Just please don't modify anything - with the exception of `CMakeCache.txt` - that CMake does create. I've update my answer accordingly (also including the content of my other comments). Use the `set(... CACHE INTERNAL "")` syntax in your toolchain file. – Florian Nov 12 '16 at 20:21