Cross-compiling with Cmake and VSCode

Enes ÖZTÜRK
6 min readMay 10, 2020

--

In this post, I will cover integration between CMake and VSCode, also cross-compiling with using Cmake for arm based boards. Finally, we will deploy the hello world program to our board. My goal to write this post is that is using the CMake portability, which is independent of any compilers and OS, and beautiful VSCode IntelliSense and themes. Let’s get started!

1.Installation

1.a) Vs code installation

Download https://code.visualstudio.com/ based on your Linux distro. In my case, I have downloaded the .deb package.

#To install visual studio code$ sudo apt install ./code_1.45.0–1588868285_amd64.deb

1.b) CMake installation

#To download cmake , create directory$mkdir cmake-files#Download cmake from github$wget -P ./cmake-files \ https://github.com/Kitware/CMake/releases/download/v3.16.4/cmake-3.16.4-Linux-x86_64.sh$cd cmake-files#Install cmake$sudo ./cmake-3.16.4-Linux-x86_64.sh — prefix=/usr/local/ — exclude-subdir –skip-license

when “cmake” command is typed on the shell, the output should be like the picture below

1.c) Toolchain installation

A toolchain is necessary to make cross-compilation for 32-bit arm architecture. I will download the linaro toolchain. In my case, the cross-compiled binary will be tried on the raspberry pi 3 model bv2 board. But, you can also try on different arm-based boards such as orange pi, ti am335x(beaglebone) so on.

Note: If your board provider recommends toolchain, please use it.

#Create project folder$mkdir test-project$cd test-project$mkdir toolchain$cd toolchain#To install toolchain$wget https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/arm-linux-gnueabihf/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz$tar -Jxvf gcc-linaro-7.4.1–2019.02-x86_64_arm-linux-gnueabihf.tar.xz

2.Preparing Compiling Environment

Go to the “test-project” directory which is created 1.c) Toolchain installation section.

#Create test-vscode directory$mkdir test-vscode$cd test-vscode# Create src and build directories$mkdir src build#Create CmakeLists.txt file$vi CMakeLists.txt

I have written a basic CMakeLists.txt file to generate Makefile. Then, project can be compiled with using the Makefile. The Content of CMakeLists.txt is shown following :

#Project version minimumcmake_minimum_required(VERSION 3.16.4)#Project nameproject(HelloWorldProject VERSION 1.0.0)#source files directoryset(Source_Files"src/main.c")
set(ALL_FILES ${Source_Files})
add_executable(${PROJECT_NAME} ${ALL_FILES})

Now, main.c can be created under src directory.

$vi src/main.c

Let’s code our first program. Then, save and exit(:x) the source file.

“*.cmake” file must be created for custom toolchain configuration. Go to the “test-vscode” path. Then create “cross.cmake” file. Content of the file should be the following:

set(CMAKE_SYSTEM_NAME Linux)set(CMAKE_SYSTEM_PROCESSOR arm)#set test-project path (NOTE: edit this parameter based on test-#project path in your pc )set(test-project_path YOUR_TEST_PROJECT_PATH)#set toolchain pathset(sysroot_target ${test-project_path}/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc)set(tools ${test-project_path}/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin)set(CMAKE_C_COMPILER ${tools}/arm-linux-gnueabihf-gcc)set(CMAKE_CXX_COMPILER ${tools}/arm-linux-gnueabihf-g++)set(CMAKE_SYSROOT ${sysroot_target})SET(CMAKE_CXX_FLAGS " -march=armv7-a -marm -mfpu=neon -mfloat-abi=hard --sysroot=${sysroot_target}")SET(CMAKE_C_FLAGS ${CMAKE_CXX_FLAGS})SET(CMAKE_EXE_LINKER_FLAGS "--sysroot=${sysroot_target}")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)

Pay attention : please enter your test-project path instead of YOUR_TEST_PROJECT_PATH in cross.cmake file.

“test-project” directory structure should look like the picture below.

At the moment, VScode comes in the play. Let’s run “code . “ command to open VScode.

VSCode is beautiful with extensions :), so we will need some extensions to use CMake on the project. At least, three extensions are needed to compile the project:

  • C/C++ (0.28.0-insiders3 by Microsoft)
  • CMake (0.0.17 by twxs)
  • CMake Tools (1.3.1 by Microsoft)

The custom toolchain directory has not been set yet. “settings.json” file should be modified to make toolchain settings. Ctrl+P combination is used to open the VSCode command line. Then, type “settings.json” and press enter.

Now, the path of cross.cmake file must be set to “cmake.configureArgs” variable.

We should use CTRL+P combination again. Then, type “>Cmake:Delete Cache and Reconfigure” and press enter. Makefile will be generated to make cross-compile with the command.

The output should look like the following:

[main] Configuring folder: test-vscode[driver] Removing /home/enes/test-project/test-vscode/build/CMakeCache.txt[driver] Removing /home/enes/test-project/test-vscode/build/CMakeFiles[proc] Executing command: /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_TOOLCHAIN_FILE=/home/enes/test-project/test-vscode/cross.cmake -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -H/home/enes/test-project/test-vscode -B/home/enes/test-project/test-vscode/build -G "Unix Makefiles"[cmake] Not searching for unused variables given on the command line.[cmake] -- The C compiler identification is GNU 7.4.1[cmake] -- The CXX compiler identification is GNU 7.4.1[cmake] -- Check for working C compiler: /home/enes/test-project/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc[cmake] -- Check for working C compiler: /home/enes/test-project/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -- works[cmake] -- Detecting C compiler ABI info[cmake] -- Detecting C compiler ABI info - done[cmake] -- Detecting C compile features[cmake] -- Detecting C compile features - done[cmake] -- Check for working CXX compiler: /home/enes/test-project/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++[cmake] -- Check for working CXX compiler: /home/enes/test-project/toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -- works[cmake] -- Detecting CXX compiler ABI info[cmake] -- Detecting CXX compiler ABI info - done[cmake] -- Detecting CXX compile features[cmake] -- Detecting CXX compile features - done[cmake] -- Configuring done[cmake] -- Generating done[cmake] -- Build files have been written to: /home/enes/test-project/test-vscode/build

Let’s check source file. It seems fine.

The most exciting moment is building time :). Let’s build.

It is built successfully, great ;)

The executable file, which is called Hello World Project, is created under build directory. We can check executable binary with file command whether it is compatible with arm based board or not.

Now, time to run executable on our board. You can send the executable file to arm based board with scp command. Enter your board IP instead of “Board IP”.

We can connect to our board with Putty and run the executable.

It probably comes in your mind how to debug your code. It will be discussed in the next chapter. If there is something wrong, please let me know.Thank you for reading :)

Stay tuned…

Update : Click for PART -2

Enes ÖZTÜRK, 2020

References

https://code.visualstudio.com/docs/cpp/config-linux

How to CMake Good youtube video series powered by vector-of-bool

https://linux.die.net/man/1/scp

--

--