cmake:基于MDK(Keil)的Nationstech.N32G45x平台交叉编译工具链定义

本文详细介绍了如何在CMake中配置N32G45X平台的ARMKeil编译器工具链,包括设置环境变量、定义编译器路径和SDK搜索路径,以便在不依赖μVision的前提下进行跨平台编译。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Keil MDK是非常常用的单片机开发集成环境,Keil公司2005年由ARM公司收购,现在是ARM主要的嵌入系统开发平台(ARM的另一个开发环境ds-5早在九年前就停止更新了)。
Keil虽然是个集成开发环境,但Keil本身其实是由μVision IDE和arm编译器构成。cmake虽然目前不支持生成μVision的工程文件,但cmake完全可以使用MDK中提供的arm编译器来实现独立于μVision的交叉编译(说到底μVision只是一个为开发者提供易用的GUI界面,真正干活儿的还是编译器)。
cmake实现交叉编译最重要的就是正确的定义编译工具链(toolchain),本文以Nationstech.N32G45X(国民技术)平台为例说明如何在定义cmake交叉编译工具链来实现使用MDK的armcc编译器执行单片系统的交叉编译。

N32G45X交叉编译

要求安装Arm Keil编译器(mdk525.rar)及N32G45X SDK(N32G452xx.rar)

并如下设置环境变量:

n32g45x_env.bat

@rem ------------------------------------------------------------
@rem set environment variable for N32G45X cross compile
@rem ------------------------------------------------------------

@set PATH=C:\Keil_v5\ARM\ARMCC\bin;%PATH%
@set N32G45X_SDK_PREFIX=E:\mdk\Nationstech.N32G45x_Library.1.1.1
  1. N32G452xx使用ARM Keil编译器,C:\Keil_v5为Keil 编译器的安装位置
  2. N32G45X_SDK_PREFIX为 N32G45X SDK安装位置,这个很重要,因为后面的交叉编译脚本中(cmake/n32g45x.toolchain.cmake)会用到这个环境变量

cmake的交叉编译工具链文件定义如下:
n32g45x.toolchain.cmake

# toolchain for Nationstech.N32G45X
INCLUDE(CMakeForceCompiler)

# This one is important
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_PROCESSOR arm)
# Keil armcc编译器安装默认位置
set(_compiler_prefix "C:/Keil_v5/ARM/ARMCC")
if(NOT EXISTS ${_compiler_prefix})
	if(NOT $ENV{CROSS_COMPILER_PREFIX} STREQUAL "")
	    set(_compiler_prefix $ENV{CROSS_COMPILER_PREFIX})
	elseif(CROSS_COMPILER_PREFIX)
	    set(_compiler_prefix ${CROSS_COMPILER_PREFIX})
	else()
		find_program(_armcc_path armcc)
		if(NOT _armcc_path)
			message(FATAL_ERROR "NOT FOUND compiler armcc in system path")
		endif()
		get_filename_component(_bin ${_armcc_path} DIRECTORY )
		get_filename_component(_compiler_prefix ${_bin} DIRECTORY )
	endif()	
endif()
set(_suffix)
if(WIN32)
	set(_suffix .exe)
endif()

# 要求环境变量定义 N32G45X_SDK_PREFIX 以指定 N32G45X SDK的安装位置 
# 或由cmake变量N32G45X_SDK_PREFIX 定义
if(NOT $ENV{N32G45X_SDK_PREFIX} STREQUAL "")
    set(N32G45X_SDK_PREFIX $ENV{N32G45X_SDK_PREFIX})
endif()
if(NOT N32G45X_SDK_PREFIX)
	message(FATAL_ERROR "NOT DEFINE N32G45X SDK PREFIX FOR CROSS COMIPILER")
endif()

# Specify the cross compiler
# 定义编译器名字
SET(CMAKE_C_COMPILER "${_compiler_prefix}/bin/armcc${_suffix}")
SET(CMAKE_CXX_COMPILER "${_compiler_prefix}/bin/armcc${_suffix}")
SET(CMAKE_AR "${_compiler_prefix}/bin/armar${_suffix}" CACHE FILEPATH "Archiver")

# 参考N32G45X SDK 工程文件(.uvprojx)中的编译选项定义CMAKE_C_FLAGS_INIT,CMAKE_CXX_FLAGS_INIT  
UNSET(CMAKE_C_FLAGS_INIT CACHE)
SET(CMAKE_C_FLAGS_INIT "--c99 --cpu=Cortex-M4.fp --apcs=interwork --split_sections -DN32G45X -DUSE_STDPERIPH_DRIVER" CACHE STRING "" FORCE)
UNSET(CMAKE_CXX_FLAGS_INIT CACHE)
SET(CMAKE_CXX_FLAGS_INIT "--cpu=Cortex-M4.fp --apcs=interwork --split_sections -DN32G45X -DUSE_STDPERIPH_DRIVER" CACHE STRING "" FORCE)
UNSET(CMAKE_EXE_LINKER_FLAGS_INIT CACHE)
SET(CMAKE_EXE_LINKER_FLAGS_INIT "" CACHE STRING "" FORCE)
UNSET(CMAKE_AR_FLAGS CACHE)
SET(CMAKE_AR_FLAGS "-p -armcc,-Ospace" CACHE STRING "" FORCE)

# set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> ${CMAKE_AR_FLAGS} -o <TARGET> <OBJECTS>" CACHE STRING "C Archive Create")
# set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> ${CMAKE_AR_FLAGS} -o <TARGET> <OBJECTS>" CACHE STRING "CXX Archive Create")

# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH "${_compiler_prefix}")

# 将 N32G45X SDK 的header文件夹添加到include搜索路径
include_directories(
	"${N32G45X_SDK_PREFIX}/firmware/CMSIS/core/"
	"${N32G45X_SDK_PREFIX}/firmware/CMSIS/device"
	"${N32G45X_SDK_PREFIX}/firmware/n32g45x_algo_lib/inc" 
	"${N32G45X_SDK_PREFIX}/firmware/n32g45x_std_periph_driver/inc" 
	"${N32G45X_SDK_PREFIX}/firmware/n32g45x_usbfs_driver/inc" 
	"${N32G45X_SDK_PREFIX}/projects/n32g45x_EVAL/bsp/inc" 
)

# 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)

unset(_compiler_prefix)

**NOTE:**在我的项目中只是用这个工具链文件生成静态库提供给客户调用,这个工具链文件中编译选项部分是可以正常执行的,链接选项并没有验证是否正确。

{ "blockman.n04ColorComboPreset": "Classic Light (Gradients)", "editor.inlayHints.enabled": "off", "workbench.colorCustomizations": { "editor.lineHighlightBackground": "#1073cf2d", "editor.lineHighlightBorder": "#9fced11f" }, "editor.wordWrap": "off", "diffEditor.wordWrap": "off", "editor.guides.indentation": false, "editor.guides.bracketPairs": true, "cmake.configureOnOpen": true, "C_Cpp.dimInactiveRegions": false, "highlightwords.colors": [ { "light": "#b3d9ff", "dark": "cyan" }, { "light": "#e6ffb3", "dark": "pink" }, { "light": "#b3b3ff", "dark": "lightgreen" }, { "light": "#ffd9b3", "dark": "magenta" }, { "light": "#ffb3ff", "dark": "cornflowerblue" }, { "light": "#b3ffb3", "dark": "orange" }, { "light": "#ffff80", "dark": "green" }, { "light": "#d1e0e0", "dark": "red" } ], "highlightwords.box": { "light": true, "dark": false }, "highlightwords.defaultMode": 0, "highlightwords.showSidebar": true, "git.openRepositoryInParentFolders": "never", "files.autoGuessEncoding": true, "files.encoding": "gbk", "editor.fontSize": 18, "workbench.editor.enablePreview": false, "editor.rename.enablePreview": false, "notebook.diff.enablePreview": false, "KeilAssistant.MDK.Uv4Path": "C:\\Keilarm\\UV4\\UV4.exe", "files.autoSave": "afterDelay", "git.ignoreMissingGitWarning": true, "SerialTerminal.log.savePath": "c:\\Users\\mysel\\serialTerminal\\terminalLog", "SerialTerminal.script.savePath": "c:\\Users\\mysel\\serialTerminal\\scriptNoteBook", "idf.pythonInstallPath": "C:\\Users\\mysel\\.espressif\\tools\\idf-python\\3.11.2\\python.exe", "idf.hasWalkthroughBeenShown": true, "idf.gitPathWin": "C:\\Users\\mysel\\.espressif\\tools\\idf-git\\2.39.2\\cmd\\git.exe", "idf.espIdfPathWin": "C:\\Users\\mysel\\esp\\v5.4\\esp-idf", "idf.toolsPathWin": "C:\\Users\\mysel\\.espressif", "security.workspace.trust.untrustedFiles": "open", "files.associations": { "*.evue": "html" }, "workbench.colorTheme": "Visual Studio Dark", "[html]": { "editor.defaultFormatter": "vscode.html-language-features" }, "[javascript]": { "editor.defaultFormatter": "vscode.typescript-language-features" }, "makefile.configureOnOpen": true, "git.autofetch": true, "explorer.confirmDelete": false, "continue.showInlineTip": false, "editor.accessibilitySupport": "off", "github.copilot.enable": { "*": false, "plaintext": false, "markdown": false, "scminput": false }, "git.confirmSync": false, "tabnine.experimentalAutoImports": true, "workbench.iconTheme": "vscode-icons", "vue.server.hybridMode": true, } 请帮我修改
最新发布
06-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值