CMake
CMake is an open-source, cross-platform build system that uses CMakeLists.txt files to describe the build rules of a project. Its core function is to generate platform-specific build files (such as Makefile on Linux/Unix or Visual Studio projects on Windows) from a project description, enabling efficient, portable multi-platform compilation.
The diagram outlines a configuration and build process that involves Kconfig and several CMake scripts. Each element of the process plays a vital role in project configuration and build setup. Below are descriptions of each component along with its role:
CMake Introduction
The SDK project structure is meticulously designed to facilitate an organized setup for software development. At the root, the src\ directory houses C source files alongside a CMakeLists.txt, which outlines the dependencies and source file configuration for the compilation process. Its counterpart, the inc\ directory, contains header files essential for declaring interfaces, with its own CMakeLists.txt for managing dependencies.
Delving deeper, the config\cmake folder includes pivotal CMake scripts such as build.cmake for managing sub-library descriptions, compile.cmake for handling compilation parameters, and version_generate.cmake for version control automation. A top-level CMakeLists.txt serves as the primary entry point for configuring the build across the entire SDK. Additional configuration is supported by specific setup scripts located in board\evb\my_app\gcc and bin\ic_type\, where localized CMakeLists.txt files help in tailoring the build to specific platforms and output formats.
SDK\
├──── src\
│ ├── CMakeLists.txt # Specifies source files and dependencies.
│ └── *.c
├──── inc\
│ ├── CMakeLists.txt # Specifies header files and dependencies.
│ └── *.h
├──── config\cmake
│ ├── build.cmake
│ ├── compile.cmake
│ └── version_generate.cmake
├──── CMakeLists.txt # Top-level entry.
├──── board\evb\
│ └──my_APP/gcc
│ └──CMakeLists.txt # Before build/after build/linker setting
└──── bin\ic_type\
└──CMakeLists.txt # Specifies lib files and dependencies.
Structure of APP CMakeLists
A typical CMake project structure looks like this:
cmake_minimum_required(VERSION 3.16)
project(MyAPP VERSION 1.0 LANGUAGES C CXX)
add_executable(myAPP main.c foo.c)
target_include_directories(myAPP PRIVATE include/)
target_compile_definitions(myAPP PRIVATE USE_FOO=1)
target_link_libraries(myAPP m)
-
Add target
CMake manages project objects as targets. To add an APP target, use the
add_executablecommand:Format:
add_executable(<name> <options>... <sources>...)
Example:
add_executable(btAudioTrx " ")
Where
<name>is the name of the APP target. Options are usually left as default, and sources can be omitted here and added later. For example, in thebtAudioTrxproject, this is sufficient for initialization. -
Set APP target properties
After adding the
btAudioTrxtarget, you can set properties for this target with theset_target_propertiescommand:Format:
set_target_properties(<targets> ... PROPERTIES <prop1> <value1> [<prop2> <value2>] ...)
Example:
set_target_properties(btAudioTrx PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${lib_output_path} LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path} OUTPUT_NAME btAudioTrx${build_bank})
-
Add required libraries for the APP
To add libraries, use the
target_link_librariescommand:target_link_libraries(<target> ... <item>...)
<target>is the APP target,<item>is the library being added. UsePUBLICorPRIVATEas appropriate. For most single-project builds, either is acceptable.For released SDK, libraries are not compiled, So each library has two targets for compatibility, one for a collection of header files and another for the implementation. For example, add the math library like so:
if(compile_lib) target_link_libraries(btAudioTrx PUBLIC ${audioLib_link} PUBLIC ${btmLib_link}) endif() #remove to sdk/bin target_link_libraries(btAudioTrx PUBLIC btmLib PUBLIC audioLib PUBLIC m)
Both
mandlibm.aare the default math libraries and can be added together.Once a library is linked, its include paths are automatically added; there is no need to add them separately.
-
Add Preinclude Header Files and Predefines
To add default preinclude headers, use:
target_precompile_headers(<target> <INTERFACE|PUBLIC|PRIVATE> [header1...] [<INTERFACE|PUBLIC|PRIVATE> [header2...] ...]) target_compile_definitions(<target> <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
Example:
#preinclude kconfig.h target_precompile_headers(btAudioTrx PRIVATE ${kconfig_header_dir_path}/config.h) #preinclude RAM_TYPE_DATA_ON target_compile_definitions(btAudioTrx PUBLIC RAM_TYPE_DATA_ON=0)
-
Add Boot Files
The boot files, such as
system_rtl87x3.candstartup.s, are responsible for hardware initialization and setting up the runtime environment. These files typically contain startup routines and low-level hardware configurations. Make sure to add them to your target sources using CMake as shown below. You can usually copy this section directly from the provided template or standard setup:target_sources(btAudioTrx PRIVATE ${realtek_start_up_boot_file} PRIVATE ${arm_start_up_boot_file}) set_property(SOURCE ${arm_start_up_boot_file} PROPERTY LANGUAGE C)
-
Add linker Script
The linker script, such as
APP.ld, tells the compiler how to organize different code and data sections in the final binary. This is essential to ensure the application is linked correctly according to the chip and memory layout. This step is generally included as is from your template.generate_ldscript("${CMAKE_CURRENT_SOURCE_DIR}/APP_rtl87x3e.ld" btAudioTrx)
-
Add Post Build script
Post-build scripts are used to automate a series of steps after compilation, such as converting the output file format (ELF to HEX), embedding encryption info, and generating the final deployable binary. Here's a sample post-build process:
set(gcc_tool_path ${REALTEK_SDK_BASE_PATH}/tool/Gadgets/gcc_tool) set(debug_table_tool_path ${REALTEK_SDK_BASE_PATH}/tool/Gadgets/build_debug_table_tool) add_custom_command(TARGET btAudioTrx POST_BUILD WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path} COMMAND ${CMAKE_OBJCOPY} -O ihex ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path}/btAudioTrx_${build_bank}.elf ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path}/btAudioTrx_${build_bank}.hex COMMAND ${gcc_tool_path}/Hex2Bin.exe ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path}/btAudioTrx_${build_bank}.hex ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path}/btAudioTrx_${build_bank}.bin COMMAND ${gcc_tool_path}/prepend_header.exe /APP_code ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path}/btAudioTrx_${build_bank}.bin /${encryption_type} ${gcc_tool_path}/../${encryption_key} COMMAND ${gcc_tool_path}/prepend_header.exe /APP_code ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path}/btAudioTrx_${build_bank}.bin /mp_ini ${CMAKE_CURRENT_SOURCE_DIR}/../mdk/mp.ini COMMAND bash ${gcc_tool_path}/md5_generate.sh ${CMAKE_CURRENT_SOURCE_DIR}/bin/${bin_output_path}/btAudioTrx_${build_bank}_MP.bin ${version_path} )
Basic Workflow
Write the CMake configuration Create a
CMakeLists.txtfile in the project's root directory to define the project name, source files, dependencies, etc.Use
cmaketo generate local build files Runcmakethrough the command line to convert the configuration into the local build system (e.g., Makefile or Visual Studio project).Build the project Run commands like
makeor compile within your IDE.
Basic command-line usage:
# Generate build files (example for Linux)
cmake -B build
# Build the project
cmake --build build
Quick Troubleshooting
Compiler cannot find header files: Check header paths and
target_include_directories.Missing third-party library linkage: Confirm
target_link_librariesis correctly added.Variable not effective: Verify the scope of CMake variables.