Using CMake with the GCC RX/LLVM RL78/GCC RL78 toolchains
1. Introduction
CMake is a cross-platform, free and open-source tool for build automation, testing, packaging and installation of software.
By using platform and compiler independent configuration files, it allows developers to support the compilation process of their tools on multiple platforms.
This guide aims to provide a short overview on how to use CMake together with the GCC RX/LLVM RL78/GCC RL78 toolchains.
2. Overview
Since our target is the RL78/RX microcontroller and we are building on Windows, the following steps are necessary for this cross-compilation scenario:
• creation of a toolchain file (.cmake), since CMake cannot guess the assembler, compiler, linker and their respective option settings • creation of a CMake configuration file (CMakeLists.txt), which describes the project structure and how the final executable should be produced • execution of CMake with the previously created configuration files, to generate the Makefile • execution of make, to build the project
3. Prerequisites
• Renesas compilers for LLVM RL78/GCC RX/GCC RL78: https://llvm-gcc-renesas.com/ • CMake latest release: https://cmake.org/download/ • GNU Make for windows e.g GnuWin32: http://gnuwin32.sourceforge.net/packages/make.htm
Note: Please make sure that the environment variables are correctly set for the installed tools.
4. Project structure and configuration files
Create a project with the following structure:
• project/ ○ include/ ∎ foo.h ∎ MyClass.h ○ src/ ∎ bar.c ∎ Main.cpp ∎ MyClass.cpp ○ CMakeLists.txt ○ cross.cmake
include/foo.h
#ifdef __cplusplus extern "C" { #endif int bar(); #ifdef __cplusplus } #endif
include/MyClass.h
class MyClass { public: MyClass(int num) : myNum(num) {} int process(); private: int myNum; };
src/bar.c
#include "foo.h" int a = 13; int bar() { return a; }
src/Main.cpp
#include "MyClass.h" #include "foo.h" int main() { MyClass b(3); if (b.process() + bar() != 22) return 1; return 0; }
src/MyClass.cpp
#include "MyClass.h" int MyClass::process() { return this->myNum * 3; }
4.1 Toolchain file
Example toolchain file for GCC RX:
set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR GCCRX) set(CMAKE_FIND_ROOT_PATH "{Replace with toolchain install location}/rx-elf/rx-elf/bin") set(CMAKE_C_COMPILER ${CMAKE_FIND_ROOT_PATH}/rx-elf-gcc.exe) set(CMAKE_CXX_COMPILER ${CMAKE_FIND_ROOT_PATH}/rx-elf-gcc.exe) set(CMAKE_SYSROOT ${sysroot_target}) set(CMAKE_C_OBJCOPY ${CMAKE_FIND_ROOT_PATH}/rx-elf-objcopy.exe) 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)
Example toolchain file for LLVM RL78:
set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR LLVMRL78) set(CMAKE_FIND_ROOT_PATH "{Replace with toolchain install location}/bin") set(CMAKE_C_COMPILER ${CMAKE_FIND_ROOT_PATH}/clang.exe) set(CMAKE_CXX_COMPILER ${CMAKE_FIND_ROOT_PATH}/clang++.exe) set(CMAKE_SYSROOT ${sysroot_target}) set(CMAKE_C_OBJCOPY ${CMAKE_FIND_ROOT_PATH}/llvm-objcopy.exe) 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)
Example toolchain file for GCC RL78:
set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR GCCRL78) set(CMAKE_FIND_ROOT_PATH "{Replace with toolchain install location}/bin") set(CMAKE_C_COMPILER ${CMAKE_FIND_ROOT_PATH}/rl78-elf-gcc.exe) set(CMAKE_CXX_COMPILER ${CMAKE_FIND_ROOT_PATH}/rl78-elf-gcc.exe) set(CMAKE_SYSROOT ${sysroot_target}) set(CMAKE_C_OBJCOPY ${CMAKE_FIND_ROOT_PATH}/rl78-elf-objcopy.exe) 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)
4.2 Configuration file
Project configuration example for GCC RX:
cmake_minimum_required(VERSION 3.16.4) project(Project VERSION 1.0.0) enable_language(C ASM) file(GLOB_RECURSE Source_Files "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") SET(CMAKE_ASM_FLAGS "-g2 -mcpu=rx100 -misa=v1 -mlittle-endian-data") SET(CMAKE_C_FLAGS "${CMAKE_ASM_FLAGS} -ffunction-sections -fdata-sections -fdiagnostics-parseable-fixits -Wstack-usage=100") SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS}) SET(CMAKE_EXE_LINKER_FLAGS "-msim -Wl,-Map=${PROJECT_NAME}.map") add_executable(${PROJECT_NAME}.elf ${Source_Files}) add_custom_target(${PROJECT_NAME}.bin ALL DEPENDS ${PROJECT_NAME}.elf) add_custom_command(TARGET ${PROJECT_NAME}.bin COMMAND ${CMAKE_C_OBJCOPY} ARGS -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin)
Project configuration example for LLVM RL78 or GCC RL78:
cmake_minimum_required(VERSION 3.16.4) project(Project VERSION 1.0.0) enable_language(C ASM) file(GLOB_RECURSE Source_Files "${CMAKE_CURRENT_SOURCE_DIR}/src/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp" ) include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") SET(CMAKE_ASM_FLAGS "-g -mcpu=s3") SET(CMAKE_C_FLAGS "${CMAKE_ASM_FLAGS} -ffunction-sections -fdata-sections") SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS}) SET(CMAKE_EXE_LINKER_FLAGS "-fsim -Wl,-Map=${PROJECT_NAME}.map") add_executable(${PROJECT_NAME}.elf ${Source_Files}) add_custom_target(${PROJECT_NAME}.bin ALL DEPENDS ${PROJECT_NAME}.elf) add_custom_command(TARGET ${PROJECT_NAME}.bin COMMAND ${CMAKE_C_OBJCOPY} ARGS -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}.bin)
5. Project build
5.1 Build file generation
We have to tell CMake which target generator we want to use (via -G option) and that we are cross-compiling (by specifying the toolchain file via option -DCMAKE_TOOLCHAIN_FILE).
>cd project >cmake -H. -Bbuild -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=cross.cmake
Executing this command results in the creation of the project/build folder, which contains the build system specific configuration files.
5.2 Build execution
After CMake successfully generates the native build files, GNU Make needs to be executed to build the project:
>cd build >make all
If the build was successful, the linked executable can be found in the project/build folder.