Cross-compiling - retrieve target CPU and version - cmake

I'm cross-compiling for VxWorks using cmake. When I run cmake the first time I have to provide informations about compiler, target OS etc..
In the cross-compile dialogue there are three target system settings I set:
Operating System
Version
Processor
(followed by compiler etc.)
While I can retrieve the first one using CMAKE_SYSTEM_NAME, i can't get the version and the processor.
Both return an empty string.
Here's an example:
MESSAGE("CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
MESSAGE("CMAKE_SYSTEM_VERSION: ${CMAKE_SYSTEM_VERSION}")
Output:
CMAKE_SYSTEM_PROCESSOR:
CMAKE_SYSTEM_VERSION:
My Cmake Version is 2.8.10.2 and target OS is VxWorks (if this matters - compiler are WindRiver GNU).
How can I get the version and processor I've set in the beginning? Or is this impossible if I cross-compile to an OS that's unknown to cmake?
(Btw. Compiling works fine)

It seems this is not possible so far. I'm getting empty strings all the time.
However, there's a working solution, and i guess it's the better way:
Before:
I specified cross-compile settings (Compiler and target system, see question), then it runs over VxWorks specific parts in the CMake list (checked with if( VxWorks ) to ensure it's not executed when other systems are used).
Now (Solution):
I wrote a toolchain file and platform files for VxWorks and required processors.
Cons:
I have to write some extra files:
Toolchain file
Platform file for VxWorks
Further Platform files for each Processor (and processor type, Gnu and Diab)
Pros:
CMake list is much cleaner now
Separate Project and Target settings
Separate System and processor settings - easy to add new Processors in a very clear way but keep System settings
I write some settings in the toolchain file and CMake loads related system / processor settings
...

Related

CMake, Cross compiling and dependencies across architectures

For background, my eventual hardware target is a custom ASIC with several MCUs and DSPs, and I need to make a single "boot" file from that.
Our codebase is modularized, and can support building each appropriate target for each processor.
CMake is configured with the target architecture and output in ./build/. The CMake scripting handles choosing the right source files when a module has specific source files for a given processor and building the appropriate libraries and to executable images/elf files.
What I haven't quite resolved is how to have an 'uber' CMake project that builds each architecture, then takes the appropriate elf files from each architecture and incorporates them in the "bootfile" to be downloaded to the target. I want to make sure that when I change the source in one of the DSP source files, the affected libraries rebuild for that, and the executable rebuilds, then that executable triggers a rebuild of the bootimage generation. (or maybe the cortex image depends on a generated header file or something).
Can anybody point to some examples of something like this? Or maybe the appropriate CMake functions to use?
I know I can do it in bash/bat/powershell but I'd like to be able to do this so it integrates well with VSCode and the CMake Tools extension.

Can the object file name be changed from .obj during cmake compiler testing?

Ultimately, I'm trying to build Apache QPID to run in the HPE NonStop OSS environment (a Posix-like environment on the NonStop system). The latest version of QPID uses cmake to build so I first need to get cmake to work for that environment. My earlier attempts tried to build in OSS directly (I needed to build cmake first before trying to build QPID), but I ran into many problems there. So lately I'm trying to build in Windows using a set of cross-development tools (compilers etc.) for NonStop. I've downloaded a Windows version of cmake 2.8 (suggested by the QPID build instructions) and am trying to use that with the X-dev tools to build QPID for OSS.
One big issue I've run into has to do with how cmake does things to test compilers and so forth early on. It will invoke the compiler to create an intermediate object file from C (and/or C++) source file and after that it will invoke the compiler to link an object file from the intermediate file. It seems that cmake prefers to add .obj to file names to create the intermediate object file name. This will work OK with my cross-compiler when creating the file (the name passed with -o to the compiler) but it will not work when passing this name for link purposes. Here is a short bit of the output per the CMakeError.log file (from trying build an OSS version of cmake 2.8 itself):
Determining if the C compiler works failed with the following output:
Change Dir: C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp
Run Build Command:C:/cygwin/bin/make.exe "cmTryCompileExec/fast"
/usr/bin/make -f CMakeFiles/cmTryCompileExec.dir/build.make CMakeFiles/cmTryCompileExec.dir/build
make[1]: Entering directory '/cygdrive/c/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp'
"C:/Program Files (x86)/CMake 2.8/bin/cmake.exe" -E cmake_progress_report C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp/CMakeFiles 1
Building C object CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj
/cygdrive/c/NonStop/tndm_cmplrs-j20/usr/bin/c89.exe -o CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj -c C:/Source/cmake-2.8.0/bld/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTryCompileExec
/cygdrive/c/NonStop/tndm_cmplrs-j20/usr/bin/c89.exe "CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj" -o cmTryCompileExec
c89.exe: error: Invalid input file extension"CMakeFiles/cmTryCompileExec.dir/testCCompiler.c.obj".
The cross-compiler fails because it requires intermediate object files to use .o for the extension, in order to determine they are intermediate object files. There is no way to get the c89 compiler to recognize testCCompiler.c.obj as a file type it knows what to do with.
So I've been searching (trying to find a local expert, but no one in my organization knows cmake; also numerous Google searches but could not find an answer) to see if there is any way to get cmake to change the name of the output file it uses for these type of compiles and tests. I've found info and then set CMAKE_C_OUTPUT_EXTENSION in a toolchain file:
SET(CMAKE_C_OUTPUT_EXTENSION ".o")
but that has made no difference.
If I can find a way to get cmake to create object files with names like testCCompiler.c.o instead of testCCompiler.c.obj, then the c89 cross-compiler would work.
Is it possible to do this?
UPDATE: I've managed to figure out that setting CMAKE_C_OUTPUT_EXTENSION in the toolchain file doesn't help. This gets overwritten in the CMakeCInformation.cmake (depending on whether UNIX is set or not). I also tracked down that UNIX gets set to true in Platform/UnixPaths.cmake, which gets INCLUDEd by various Platform files. So I've created a Modules/Platform/OSS.cmake file which includes it to takes care of that. I'll probably need/want to add other settings there later as I determine more flags for compilers etc that should be set to specific values for the OSS environment.

How can I detect the location of Qt5 core in a CMake file on OS X?

I am using CMake to build a Qt5 project on OS X. I need to create a build process that is as simple as possible for others.
By default Qt5 installs to the home folder on OS X. However, it then places its files within a directory named after the exact version number, e.g. 5.2.1.
At the moment I am using these lines in my CMake file:
set(QT5_PATH $ENV{HOME}/Qt5.2.1/5.2.1/clang_64/ CACHE PATH "Path to Qt5")
set(QT5_MODULE_PATH ${QT5_PATH}/lib/cmake)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT5_MODULE_PATH})
This works, but unfortunately breaks with each minor update of Qt as the 5.2.1 needs to be changed to 5.2.2, etc.
In Windows there are environment variables that can be used to find Qt. Is there anything similar in OS X that I can use within CMake to find a Qt installation?
Use find_package instead of juggling with the paths yourself. Then your users can rely on standard CMake mechanism instead of figuring out your own CMake code.
Use find_package(Qt5Widgets) to get targets like Qt::Widgets to link against and for the includes.
Similar for Qt5Core and whatever part of Qt 5 you need.
See Qt's documentation: http://doc.qt.io/qt-5/cmake-manual.html

How to add header file path in CMake file

I am new to OpenCL. I have written a vector addition code in OpenCL with help from Internet. I have included one header file i.e. CL/cl.h using #include.
I am using NVIDIA graphic card and the OpenCL implementation is NVIDIA_GPU_Computing_SDK. My OpenCL header files are residing at this path /opt/NVIDIA_GPU_Computing_SDK/OpenCL/common/inc. I can run OpenCL programs through linux terminal by adding this path when compiling my code. But now I want to write CMake file for this code. CMake files are working fine for C programs, but not OpenCL programs because of this Path problem. In terminal, I used to enter $cmake ., after this $make, it will search for a Makefile which is created by cmake, now my error is after entering command make
fatal error: CL/cl.h: No such file or directory!
Now tell me how can I include this header file into CMake file?
You will need to put these lines into CMakeLists.txt:
include_directories(/opt/NVIDIA_GPU_Computing_SDK/OpenCL/common/inc)
link_directories(/opt/NVIDIA_GPU_Computing_SDK/OpenCL/common/<lib or something similar>)
add_executable(yourexe src1.c ...)
target_link_libraries(yourexe OpenCL)
But beware that this is not portable, because OpenCL SDK can be somewhere else on another machine. The proper way to do this is to use FindOpenCL.cmake module.
Maybe you can use a CMake "find" script like:
http://gitorious.org/findopencl/findopencl/blobs/master/FindOpenCL.cmake
http://code.google.com/p/opencl-book-samples/source/browse/trunk/cmake/FindOpenCL.cmake?r=14
CMake file example from OpenCL Programming Guide Book: http://code.google.com/p/opencl-book-samples/source/browse/trunk/CMakeLists.txt?r=14
I was looking for FindOpenCL.cmake macro which would work well on Windows, OSX and Linux... I couldn't find any which did work well on every platform, so I wrote new one which I use in couple of projects (webcl-validator and opencl-testsuite).
https://github.com/elhigu/cmake-findopencl
Especially Windows support is improved in this one.
In Windows it checks if 64bit or 32bit lib should be used and it also tries to find libraries from according to environment variables set by Nvidia, Intel and AMD OpenCL SDKs.
It also tries to find .lib in Cygwin, which didn't work with other scripts I tried.

How to cross compile CMake for ARM with CMake

In short I'm trying to cross compile CMake with CMake, and I don't think I'm linking libraries correctly. What I want to do may not be possible, but I'd at least like to know why it isn't possible if that's the case.
System: The host is a Linux box with a Cavium ARM9 CPU. It's currently running version 2.6.24.4 of the Linux kernel and Debian 5.0 (Lenny). My workstation is a Core i5 running Ubuntu 12.04 LTS (Precise Pangolin).
My overall goal is to get ROS running on the Linux box. I have to compile from source rather than use apt since Debian 6.0 (Squeeze) binaries require thumb support that the Cavium does not give, and not many of the needed packages are available for Debian 5.0 (Lenny). I'd made progress installing the various libraries needed, but when I got to step 1.3.1 and tried to run CMake, I got the error
CMake 2.8 or higher is required. You are running version 2.6.0
Next I tried to download and build CMake 2.8.8 on the Linux box itself, but it was too much for the system. When that failed, I downloaded the toolchain suggested on the manufacturer's website and used the cross-compiling guide at [www.cmake.org/Wiki/CMake_Cross_Compiling] to build the CMake executables. Here is my toolchain file:
# This one is important
SET(CMAKE_SYSTEM_NAME Linux)
# Specify the cross compiler
SET(CMAKE_C_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-g++)
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/arm-unknown-linux-gnu)
# Search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
However, use of the binary on the Linux box gives the error
cmake: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by cmake)
Sure enough, the library is not there:
prompt# strings /usr/lib/libstdc++.so.6 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBC_2.3
GLIBC_2.0
GLIBC_2.3.2
GLIBC_2.1
GLIBC_2.1.3
GLIBC_2.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
I've never cross-compiled before, but I can see one of two scenarios happening: either the binary got created with a link to a higher version of glibcxx on the host machine or the manufacturer's toolchain is more modern than their image. I don't know how to check which is happening or if something else is happening that I don't know about.
My last effort involved trying to statically cross-compile CMake to hopefully get rid of the linking error with
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-technologic.cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS_RELEASE="-static" ..
I got build errors, and that binary didn't work either. I got:
FATAL: kernel too old
Segmentation fault
I'd try installing glibcxx 3.4.14 on the Linux box, but it doesn't look like it's available for this processor.
I've tried searching for CMake dependencies or system requirements and can't find anything. I've also searched on how to build CMake, but most searches turn up how to build other things with CMake rather than building CMake itself.
I do cross-compile a lot for ARM9 devices using CMake, and indeed this looks like you're not linking to the same libs you have on your target device. You shouldn't need to build CMake yourself to get this done, since it does have good support for cross-compiling since version 2.6. Just make sure you set the CMAKE_FIND_ROOT_PATH variable to a path where you have an exact copy of the root filesystem you have on your target device (with libraries and binaries pre-compiled for the target processor). That should solve your problems.
As a sidenote, I like to use crosstool-ng for building my cross-compilers. It is a really nice tool which helps you to build them from scratch, so I try to match the compiler version and glibc to the ones originally used to build the root filesystem (I usually start with a ready made root filesystem from ARMedslack, since I use Slackware for my development box and ARMedslack for my ARM targets).