使用clion阅读任意交叉编译软件的代码

clion是linux下比较强大的C/C++ IDE,通过扩展也可以支持很多其他语言,例如shell,lua, perl, python,rust。唯一缺点是收费,但是相对它给我带来的便利,这点费用不算什么。我一般用来开发C/C++/项目,它支持3种方式解析工程源码,分别是

  • Makefile
  • CMake
  • 编译数据库

像代码的高亮,跳转,补全,都依赖对源码的解析,其实CMake和Makefile应该是一回事,CMake最终也会生成Makefile。首先通过make分析出工程里面用到哪些源文件,然后通过内置语法分析器解析得到符号表等信息,从而实现高亮,补全等。

当你的工程是针对你开发的PC时,这些都没问题,但是如果是交叉编译时,便会由于无法通过make来获取依赖的源文件,导致接下来的语法分析也无法进行。例如基于openwrt,buildroot开发时,或者编译uboot,kernel。因为这些构建框架都有自己特定的一些环境变量,编译脚本什么的,导致clion这种IDE无法简单的通过指定工具链来执行make,来分析依赖的源文件。于是编译数据库这种方式就派上了用场。cmake可以直接生成编译数据库,通过cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1,但是嵌入式开发里面用的一些库,工具可能是基于比较古老的版本,仅支持automake, makefile等。此时需要借助另一个工具bear,ubuntu20.04上直接apt安装即可,或者源码编译。bear的用法十分的简单

bear 编译命令
#例如,builrdroot中编译某个软件
bear make xl2tpd-{dirclean,build}
#或者,openwrt中
bear make package/xl2tpd/{clean,prepare,compile}

它的工作原理好像是创建子进程执行编译命令,然后监听工具链的gcc的调用,类似strace分析gcc的调用,知道gcc执行时,参数是怎么样的,open等系统调用又是怎么样的。最终生成编译数据库文件,其实就是个json文件。这个文件里面对每个gcc处理过的文件作了记录,包括3个值:

  • gcc的参数
  • 源文件名称
  • 源文件目录
{
"arguments": [
"/home/a/workspace/exc-m620d/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-5.4.0_musl-1.1.16_eabi/bin/arm-openwrt-linux-muslgnueabi-gcc",
"-c",
"-Os",
"-pipe",
"-mcpu=cortex-a7",
"-mfpu=neon-vfpv4",
"-fno-caller-saves",
"-fno-plt",
"-fhonour-copts",
"-Wno-error=unused-but-set-variable",
"-Wno-error=unused-result",
"-mfloat-abi=hard",
"-iremap/home/a/workspace/exc-m620d/openwrt/build_dir/target-arm_cortex-a7+neon-vfpv4_musl-1.1.16_eabi/xl2tpd-devel-20151125:xl2tpd-devel-20151125",
"-Wformat",
"-Werror=format-security",
"-fstack-protector",
"-D_FORTIFY_SOURCE=1",
"-I/home/a/workspace/exc-m620d/openwrt/staging_dir/target-arm_cortex-a7+neon-vfpv4_musl-1.1.16_eabi/usr/include",
"-I/home/a/workspace/exc-m620d/openwrt/staging_dir/target-arm_cortex-a7+neon-vfpv4_musl-1.1.16_eabi/include",
"-I/home/a/workspace/exc-m620d/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-5.4.0_musl-1.1.16_eabi/usr/include",
"-I/home/a/workspace/exc-m620d/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-5.4.0_musl-1.1.16_eabi/include/fortify",
"-I/home/a/workspace/exc-m620d/openwrt/staging_dir/toolchain-arm_cortex-a7+neon-vfpv4_gcc-5.4.0_musl-1.1.16_eabi/include",
"-DDEBUG_PPPD",
"-DTRUST_PPPD_TO_DIE",
"-fno-builtin",
"-Wall",
"-DSANITY",
"-DLINUX",
"-I./linux/include/",
"-DUSE_KERNEL",
"-DIP_ALLOCATION",
"-o",
"call.o",
"call.c"
],
"directory": "/home/a/workspace/exc-m620d/openwrt/build_dir/target-arm_cortex-a7+neon-vfpv4_musl-1.1.16_eabi/xl2tpd-devel-20151125",
"file": "call.c"
}

然后语法分析器就知道分析谁了。这样就可以愉快的使用clion阅读编辑跑在ARM上的代码了。不过有个地方需要注意,如果你的交叉编译工具链是通过export到环境变量的方式来执行的,那么编译数据库的的arguments的第一项,gcc就不会是一个绝对路径,导致clion解析异常,这时只要全局替换这个编译数据库文件里面的xxx-gcc为绝对路径即可。其实我认为这个应该是bear需要改进的一个地方,bear在填这个工具链的gcc时,通过realpath就知道工具链的绝对路径。

posted @   thammer  阅读(588)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2017-08-29 使用 openssl 生成证书
2017-08-29 linux C单元测试工具CUnit的编译安装及使用
点击右上角即可分享
微信分享提示