使用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就知道工具链的绝对路径。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
2017-08-29 使用 openssl 生成证书
2017-08-29 linux C单元测试工具CUnit的编译安装及使用