CCS联合CLion调试__开发TI板——下

TI:MSPM0G3507

IDE:CCS20  CLion2025

一、引言

        承接上篇CCS联合CLion调试__开发TI板——上,本文主要内容是通过CLion提升CCS工程开发的体验,代码跳转、代码补全、静态检查等方面的提升不必多说,本文还提供了一种方法,在一定程度上解决CCS工程编译慢的问题,由于编译器只能用TI的,所以编译器方面并没有任何提升,解决的思路主要是围绕CCS工程的构建方面。

        CCS工程的构建系统基于Makefile的,gmake构建系统相较于流行的Nija可谓是相当慢,以本文为例,在工程中添加lvgl库后,CCS编译一次需要3~5分钟,而Nija仅需要半分钟(因人而异,但Nija仍有不同程度上的提升)。此外,CCS工程的构建逻辑相当落后,只要syscfg更改(这很常见),或者增删文件,那么CCS就会重新clean工程,把所有源码重新编译一遍,这对于添加第三方库的工程来说是相当痛苦的开发体验,这也是本文需要解决的部分。

        此外,本文的后面提供了基于MSPM0G3507的示例工程,确保刚打开工程即可被CLion识别

二、直接开始↗

1,创建CCS工程

        打开CCS,点击创建

        选择下方的设备(需要根据自身情况来选)

        本文使用的是C++,因此创建一个C++空工程,如果熟悉C工程,那么应选择empty模板

        上面就是新创建的空工程了,红框下面是以前的工程,可以忽略

        首次进入工程需要按住Ctrl+B进行编译,这一步是确保产生相关.h/c文件,为后面的CLion编译做准备的

       使用资源管理器打开CCS工程,进入刚才创建工程的根目录

        在根目录新建一个CMakeLists.txt空白文件(如果没有启用后缀名,那么就是创建CMakeLists文本文件),这一步也是为CLion准备的

2,CLion配置ti-clang工具链

         CLion的基本使用方法不在本篇介绍内容,不过在很多博客都有涉及,参考即可,比如【嵌入式】CLion开发STM32工程_clion cubemx-CSDN博客

        右键刚才创建的工程目录,点击更多选项,使用CLion打开工程

        打开后就会自动弹出CMake的配置选项,由于还没有添加ti-clang的工具链,因此这里先点击确定

        点击右上方的设置

        可以看到,这里除了默认的MinGW工具链外,还有一条是开发STM32工程的交叉编译工具链。当然,这些都不在本篇的讨论内容

        先点击“+”,然后选择创建MinGW类型工具链

        此处,我们创建的是ti-clang工具链,为的是完全模仿CCS工程的编译过程,确保原生开发。那么需要把名称改成ti-clang(随自己习惯就好),然后重点就是把C/C++编译器的路径指定为CCS的ti-clang

        这一步,需要知道CCS安装在哪,以本文为例,CCS安装在如图所示的目录

        那么ti-clang工具链就在下图的路径中

        继续深入到bin目录,就可以看到所需的C/C++编译器,tiarmclang在此处既负责C编译,同时又负责C++编译

        那么回到CLion,我们就把C和C++编译器的路径都指定为tiarm-clang,然后点击确定即可

 3,构建项目

        再次打开设置,找到CMake,这次需要把CMake里指定的工具链换成刚才配置的ti-clang

        切换完之后,也可以在构建选项里指定最大核数编译,因为CLion默认以最大核数-2进行编译。因此,如图所示最大可以指定-j 16进行编译

        点击CMakeLists.txt文件,接下来可以编写CMakeLists.txt

        这个CMakeLists.txt想要重头编写挺麻烦,因此这里提供了一套模板,可以依据这套模板进行修改。这套模板对于初学者来说,只需要更改红框内的东西即可,没有什么上手难度

cmake_minimum_required(VERSION 3.22)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 17)
project(MSPM0G3507 LANGUAGES C CXX ASM)

set(CMAKE_EXECUTABLE_SUFFIX_ASM     ".out")
set(CMAKE_EXECUTABLE_SUFFIX_C       ".out")
set(CMAKE_EXECUTABLE_SUFFIX_CXX     ".out")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")  # 强制使用 .a 后缀


# =============================== 解决ti-clang觉得rsp文件太长 =============================
# ========= TI 编译器响应文件格式修复 =========
# 设置响应文件格式为每行一个参数
set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@")
set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@")
set(CMAKE_ASM_RESPONSE_FILE_LINK_FLAG "@")

# 强制 CMake 在响应文件中每行一个参数
set(CMAKE_C_RESPONSE_FILE_FORMAT "LINES")
set(CMAKE_CXX_RESPONSE_FILE_FORMAT "LINES")
set(CMAKE_ASM_RESPONSE_FILE_FORMAT "LINES")

# 对于 Ninja 生成器,需要额外设置
if(CMAKE_GENERATOR MATCHES "Ninja")
    set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1)
    set(CMAKE_NINJA_RESPONSE_FILE_CONTENT_FORMAT "LINES")
    message(STATUS "Enabled per-line response files for TI compiler (Ninja)")
else()
    message(STATUS "Enabled per-line response files for TI compiler")
endif()
# ============================================

# ===============================  目录 =============================
# 定义可配置的 SDK 路径变量(带默认值和描述)
set(SDK_DIR "D:/DevTools/TI/CCS2020/mspm0_sdk_2_05_01_00" CACHE PATH "Path to TI MSPM0 SDK")
message(STATUS "Using SDK path: ${SDK_DIR}")

# 检查 SDK 路径是否有效
if(NOT EXISTS ${SDK_DIR})
    # 在CLion的CMake配置选项里传递参数【-DSDK_DIR="……"】,引号内就是路径
    message(SEND_ERROR "SDK directory not found: ${SDK_DIR}")
endif()

# 获取编译器所在目录(bin目录)
get_filename_component(COMPILER_DIR "${CMAKE_C_COMPILER}" DIRECTORY)
message(STATUS "Compiler bin directory: ${COMPILER_DIR}")

# 获取上级目录(编译器根目录)
get_filename_component(COMPILER_ROOT_DIR "${COMPILER_DIR}" DIRECTORY)
message(STATUS "Compiler root directory: ${COMPILER_ROOT_DIR}")

# =============================== 编译链接 =================================
# 添加预编译宏
add_compile_definitions(
        __MSPM0G3507__
)
# 添加编译标志
add_compile_options(
        -march=thumbv6m -mcpu=cortex-m0plus -mfloat-abi=soft -mlittle-endian -mthumb -O0
        -gdwarf-3

)
# 添加链接标志
add_link_options(
        -Wl,-mmspm0g3507.map
        -Wl,--diag_wrap=off -Wl,--display_error_number
        -Wl,--warn_sections -Wl,--xml_link_info=${CMAKE_SOURCE_DIR}/Debug/mspm0g3507_linkInfo.xml -Wl,--rom_model
        # 添加链接脚本
        -Wl,-l${CMAKE_SOURCE_DIR}/Debug/device_linker.cmd
)
# 创建可执行目标
add_executable(${PROJECT_NAME})


# ----------- 添加链接库目录 -----------
target_link_directories(${PROJECT_NAME} PUBLIC
        ${CMAKE_SOURCE_DIR}/Debug/syscfg
        ${COMPILER_ROOT_DIR}/lib
)

# ----------- 添加头文件目录 -----------
target_include_directories(${PROJECT_NAME} PUBLIC
        # 默认目录
        ${SDK_DIR}/source
        ${SDK_DIR}/source/third_party/CMSIS/Core/Include
        ${CMAKE_SOURCE_DIR}
        Debug

        # 用户自定义目录
        data
)



# ----------- 添加源文件 -----------
file(GLOB_RECURSE SOURCE
        # 默认文件
        "${SDK_DIR}/source/ti/devices/msp/m0p/startup_system_files/ticlang/startup_mspm0g350x_ticlang.c"
        # 驱动库文件,不能直接在SDK目录里以静态库的方式链接,否则会出问题。TI编译器过于特立独行,寻常CMake链接库的实现根本就不能使用
        "${SDK_DIR}/source/ti/driverlib/*.c"
        "Debug/ti_msp_dl_config.c"

        # 用户自定义文件
        "core/empty_cpp.cpp"

)

# 添加资源文件
target_sources(${PROJECT_NAME} PUBLIC ${SOURCE})



# ================== 创建 LVGL 静态库 ==================
#add_library(lvgl STATIC)
#file(GLOB_RECURSE LVGL_SOURCES "middleware/LVGL/lvgl/src/*.c")
#target_sources(lvgl PUBLIC ${LVGL_SOURCES})
#target_include_directories(lvgl PUBLIC
#        ${CMAKE_SOURCE_DIR}/middleware/LVGL/lvgl
#        ${CMAKE_SOURCE_DIR}/middleware/LVGL/lvgl/src
#)
## 设置静态库输出目录
#set_target_properties(lvgl PROPERTIES
#        ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/middleware/lib
#)
#target_link_libraries(${PROJECT_NAME} PUBLIC lvgl)


CMake

        有了这个模板后,还需要手动指定SDK路径,这个SDK路径在CCS里就可以找到。回到CCS,右键创建的工程,打开首选项

        找到Arm Compiler,右边的红框内就是SDK的路径了,SDK的路径的格式很好认,最后两级目录含有sdk、source之类的就是了,把这个路径复制下来,包括引号

        【"D:/DevTools/TI/CCS2020/mspm0_sdk_2_05_01_00"

        回到CLion里,再次打开设置,在CMake配置里找到CMake选项中,添加参数【-DSDK_DIR="……"】,-D后面就是SDK路径,即【-DSDK_DIR="D:/DevTools/TI/CCS2020/mspm0_sdk_2_05_01_00"

        下图里多了source这个目录,不需要包含它,前面的CMakeLists也修复了

        点击确定后,一般会自动刷新CMake,如果不报错,就说明路径没有问题

        

源文件

        回到项目目录,我们可以看到主工程里就一个光秃秃的empty_cpp.cpp文件,我们可以新建一个core目录,把empty_cpp.cpp放进去

        接下来需要在file函数里指定这个源文件(按Tab键可以自动补全),指定源文件可以使用通配符,比如"core/*.cpp",就会自动包含core里的所有cpp文件,不需要一个一个手动输入

        每次更改完CMakeLists.txt,都需要手动重新刷新CMake,一般在修改CMakeLists后,右上方会出现刷新的符号,点击即可刷新

        或者点击左下方的CMake图标,进入CMake工具,然后点击刷新图标

头文件

        假如需要使用头文件,比如创建一个data目录,在其内创建一个data.h头文件。如果在empty_cpp.cpp里直接引用这个头文件会报错。#include"data.h"是引用当前目录的头文件,如果找不到就去指定的头文件目录里找,显然当前目录里并没有,而头文件目录我们又并未指定

        回到CMakeLists.txt中,在file函数的上方添加这个data目录,然后重新CMake

        empty_cpp.cpp这里可以看到引用头文件不再报错

编译

        编译只需要点击左上方的锤子即可,虽然本工程只有一个empty_cpp.cpp源文件,但编译却编译了48个源文件。这是因为在配置过程中,笔者发现在CMakeLists链接SDK里的静态库总是会出现缺失符号定义的问题,试了许多方法都无效,最终选择直接编译源文件,结果一遍就过。

        不过也无需担心,CMake是增量编译,这些源文件只会在初次编译,因为后续并不会对这些SDK里的源文件进行修改,所以后续过程不会再次重复编译。当然也可以手动把这些设备库文件添加为静态库目标,编译为静态库,再链接到可执行目标上(这个方法是可行的),后面会介绍。

CCS同步编译

        虽然在CLion上编译成功了,但由于调试仍在CCS上操作的,因此还需要在CCS上编译一遍(只有调试时或者修改syscfg才在CCS上编译,其余时候尽量在CLion上编译,可以大幅节省时间)

        回到CCS,CLion构建时会产生cmake-build之类的目录,这个目录里包含了一些.h/c文件,这些会被CCS自动检测并包含进去,从而导致编译错误,所以需要把它排除掉

        右键该目录,点击Exclude from Build即可排除

        然后,我们重新编译一遍,可以看到头文件报错了,这是因为CCS也需要主动添加头文件目录,此前我们只在CLion的CMakeLists里添加过

        同样右键工程,进入工程的配置选项里,找到Arm Compiler下的Include Options,这里就是头文件目录添加的地方。这里使用的是相对路径,data目录处于根目录下的data目录,因此是${PROJECT_ROOT}/data,点击右上角的“+”即可添加

        添加并保存后,回到项目界面,重新编译,即可通过

        此外,介绍一下CCS的构建逻辑,如果增删文件或者修改工程属性或者修改syscfg,那么都会因此CCS清理工程,根据syscfg重新生成对应的.h/c文件到Debug目录,然后进行全量编译。

        修改工程属性并不会频繁用到,所以不用担心,增删文件和平时写代码都可以在CLion上进行,那么这一块也无忧。但syscfg需要频繁更改的,如果在CCS里编译就会全量编译,巨慢,如果不在CCS编译,那么对应的.h/c文件又不会产生。所以这里需要我们选择一个折中的方案,解决的思路就在前面提到的构建过程,只要编译的时候在生成syscfg配置之后取消编译,或者感觉不管它,直接切回CLion继续编写代码即可。

        当然,后面还有一种静态库的方法来解决这个问题。

 4,添加静态库目标

        虽然CMake在编译库文件时,只需第一次编译即可,后续增删文件均不会重新编译,除非主动修改库文件。不过最终都要在CCS上编译一遍,因为需要使用到CCS的调试功能。如果将这些不常更改的库文件编译为静态库,在CCS以静态库的方式链接,那么CCS编译就会快很多 。不过有利就有弊,如果项目属性改变,但由于静态库是使用CLion产生的,CLion的CMakeLists也需要做出相应改变,重新编译静态库,确保静态库和原CCS工程适配。

        此外,编译为静态库之后,就会把静态库里面的每个.o文件视作一个编译单元,只要调用库文件的任何一个函数,那么整个.o文件就会被链接到.out文件里,造成.out文件变大。因此,平时开发时为了快速编译和调试,可以使用静态库链接的方式,开发差不多时,再以源码编译并开启优化等。

        下面以LVGL库为例,LVGL放在middleware目录里,同时还建了lib目录

        那么就可以添加一个静态目标lvgl

add_library(lvgl STATIC)

        然后收集所有用到的lvgl源文件,放到LVGL_SOURCES变量里

file(GLOB_RECURSE LVGL_SOURCES "middleware/LVGL/lvgl/src/*.c")

        把刚才收集的所有文件传递给lvgl静态库,作为静态库lvgl的源文件

target_sources(lvgl PUBLIC ${LVGL_SOURCES})

        lvgl库是有头文件的,那么把对应的头文件目录传递给lvgl静态库

target_include_directories(lvgl PUBLIC
        ${CMAKE_SOURCE_DIR}/middleware/LVGL/lvgl
        ${CMAKE_SOURCE_DIR}/middleware/LVGL/lvgl/src
)

        设置lvgl静态库的输出目录,使其输出在middleware/lib目录里,这一步是给CCS链接用的

set_target_properties(lvgl PROPERTIES
        ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/middleware/lib
)

        最后为我们的可执行目标链接上lvgl静态库

target_link_libraries(${PROJECT_NAME} PUBLIC lvgl)

        重新CMake后,开始构建,可以看到正常构建了

        也可以调用lvgl里面的库函数,编译一切正常

        回到CCS这里,由于使用静态库链接,那么需要把lvgl源码给排除工程中(右键目录,然后Exclude)

        打开项目属性,进入到链接器的设置里,上方添加lvgl静态库,在下面填上静态库的链接目录

        empty_cpp.cpp里已经使用了lvgl的头文件,因此这个头文件目录也需要添加进来,那么需要打开项目属性,在编译器的设置里添加lvgl的头文件目录

        可以看到此时CCS编译极快,几秒没到就已经编译好了,不必再痛苦地等待那五六百文件一个一个编译完了,现在只要编译两个文件,链接一个库就完成了

三、编写CMakeLists 

1,编译链接标志

         编写CMakeLists是根据CCS工程里的设置,不然CLion里使用CMake编译出的静态库也无法让CCS工程链接使用。前面创建CCS工程后,只要编译一遍,CCS就会自动在Debug目录产生各种配置文件,比如makefile,里面是CCS对本工程的构建规则,此外还有许多.mk文件,即子makefile文件

        不过这些不是本文的重点,在编写CMakeLists时,重点是设置编译和链接标志,因为其他内容都与前文提供的CMakeLists模板相同,不用改。

        上面的编译和链接标志,打开工程的项目属性,找到对应的编译器和链接器即可看到。先看编译标志,带-I的可以不用看,因为这些东西是头文件目录,在CMakeLists里是通过target_include_directories添加的,不属于这里讲的编译标志范畴。

        这是链接的头文件目录

        链接标志同理,-Wl,-i是添加链接库目录的,不在此处链接标志讨论范畴

        这是链接库目录

2,预编译宏

         除了编译和链接标志外,还需要添加预编译宏

        这个宏在Debug目录里的device.opt文件里,-D就是添加宏的意思

3,rsp文件响应问题

        像编译lvgl这样有几百个源文件的工程,ti-clang会报错,因为CMakeLists生成的rsp文件,默认把所有目标文件都放在同一行中,而ti-clang对目标文件的行数有所限制(arm-gnu等编译器并没有这种问题)

        所以需要让响应文件强制每行一个目标

四、示例工程 

 gitcode项目首页 - MSPM0G3507 - GitCode

        进入CLion新建项目界面,点击克隆仓库

        选择需要创建的目录(后面目录改为demo了),把上面的gitcode网址放入,点击克隆

        克隆完成后,自动弹出cmake,选择ti-clang,然后在CMake选项处输入SDK目录(在前文提到过),SDK目录如果输错会导致CMake失败,打开设置找到CMake再输入正确的即可。

        cmake成功后,构建会失败,因为缺少文件,这些文件需要使用CCS编译产生

        打开CCS,选择打开目录

        找到前面克隆的demo工程,在此处打开(打开的一定是下载工程的父目录所在的地方)

打开后,工程可能要下载SDK之类的,有时候会卡bug,重新打开CCS即可

        首次编译,一般是没有问题的。如果有问题,说明上传的工程可能改了不少东西,导致工程不兼容

        目前来说7月6号的这个提交,编译是没有问题

        最后返回CLion,这里编译也一切正常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值