不要错过!SourceInsight 快速、精确导入 Linux Kernel 源码的方法
本帖最后由 jujiaqi 于 2015-6-24 16:35 编辑相信有很多人用 SourceInsight 查看 Linux Kernel 源码,但导入源码时会遇到一些问题。
1、如果把整个源码树都导入进去,查看符号定义的时候,会发现有大量重复定义,很难找到正确的位置
2、如果手动导入只和该硬件平台相关的源码,工作量太大
本帖提供了一个方法,可用脚本生成只和该硬件平台相关的源码的文件列表,然后通过该文件列表,将相应文件导入 SourceInsight 。
以下是步骤,共4步:
1、新建 SourceInsight 项目
先不要导入文件,停在如下界面:
2、完整编译内核,将编译时输出的信息保存到一个文件中
例如:
make ARCH=arm > build_log.txt
build_log.txt 文件中内容大致如下:
CC init/main.o
CHK include/generated/compile.h
CC init/do_mounts.o
HOSTCCusr/gen_init_cpio
CC arch/arm/vfp/vfpmodule.o
CC arch/arm/kernel/elf.o
AS arch/arm/kernel/entry-armv.o
AS arch/arm/vfp/entry.o
AS arch/arm/kernel/entry-common.o
CC arch/arm/kernel/irq.o
AS arch/arm/vfp/vfphw.o
GEN usr/initramfs_data.cpio
CC arch/arm/kernel/opcodes.o
3、生成文件列表
下载 帖子 最后面的附件,解压后是 linux shell 脚本。
编辑脚本两个变量,ARCH 和 MACH,MACH是平台的名字。如果你用的平台对应 arch/arm/mach-at91 的话,就改成 MACH=at91,以此类推。
在内核源码目录下执行:
./sg.sh build_log.txt file_list.txt
这样,SourceInsight 需要的 文件列表 file_list.txt 就生成了。里面的内容大致如下:
4、导入文件列表
回到 SourceInsight,点击窗口右下角 help 按钮上方的 “add from list” 按钮导入生成的 file_list.txt 文件。
到此为止,文件导入完成了。重新打开工程,会提示同步、构建,之后就可以正常的查看源码了。
这样导入的文件和硬件平台是完全对应的。
下面是本帖的核心,就是这个脚本,有兴趣的可以看看:
#!/bin/sh
ARCH=arm
MACH=at91
FILE_IN=$1
FILE_OUT=$2
# .c
SOURCE_LIST=""
# generated file list
FILE_LIST=""
# nest depth for function get_includes()
NEST_DTPTH=0
# recursive function, used to get included files from files.
# result is stored in FILE_LIST
# $1 : file list, e.g. "fs/ext4/file.c fs/ext4/fsync.c"
get_includes()
{
local includes
local file
for file in $1
do
if [ ! -e ${file} ]; then
continue
fi
if echo "${FILE_LIST}" | grep -E ${file} > /dev/null; then
continue
fi
FILE_LIST="${FILE_LIST} ${file}"
NEST_DTPTH=$((NEST_DTPTH+1))
echo "<${NEST_DTPTH} : ${file}"
includes=$( \
grep -E -H '^#include' ${file} | \
sed -r \
-e 's@^.*<(acpi/.*)>@include/\1@' \
-e 's@^.*<(asm-generic/.*)>@include/\1@'\
-e 's@^.*<(config/.*)>@include/\1@' \
-e 's@^.*<(crypto/.*)>@include/\1@' \
-e 's@^.*<(drm/.*)>@include/\1@' \
-e 's@^.*<(generated/.*)>@include/\1@' \
-e 's@^.*<(keys/.*)>@include/\1@' \
-e 's@^.*<(linux/.*)>@include/\1@' \
-e 's@^.*<(math-emu/.*)>@include/\1@' \
-e 's@^.*<(media/.*)>@include/\1@' \
-e 's@^.*<(misc/.*)>@include/\1@' \
-e 's@^.*<(mtd/.*)>@include/\1@' \
-e 's@^.*<(net/.*)>@include/\1@' \
-e 's@^.*<(pcmcia/.*)>@include/\1@' \
-e 's@^.*<(rdma/.*)>@include/\1@' \
-e 's@^.*<(rxrpc/.*)>@include/\1@' \
-e 's@^.*<(scsi/.*)>@include/\1@' \
-e 's@^.*<(sound/.*)>@include/\1@' \
-e 's@^.*<(target/.*)>@include/\1@' \
-e 's@^.*<(trace/.*)>@include/\1@' \
-e 's@^.*<(uapi/.*)>@include/\1@' \
-e 's@^.*<(video/.*)>@include/\1@' \
-e 's@^.*<(xen/.*)>@include/\1@' \
-e "s@^.*<(asm/.*)>@arch/${ARCH}/include/\1 arch/${ARCH}/include/generated/\1@" \
-e "s@^.*<(mach/.*)>@arch/${ARCH}/mach-${MACH}/include/\1@" \
-e 's@(^.*/)[^/]+\.c.*\"(.*)\"@\1\2@' \
-e 's@/\*.*@@' \
-e 's@^.*\#include.*$@@' \
-e 's@^@ @' | \
sort | \
uniq | \
tr -d '\n' | \
tr -d '\r' \
)
if [ -n "${includes}" ]; then
get_includes "${includes}"
fi
echo ">${NEST_DTPTH}) : ${file}"
NEST_DTPTH=$((NEST_DTPTH-1))
done
}
# get *.c from kernel build log
SOURCE_LIST=$( \
grep -E '^\s*CC' ${FILE_IN} | \
sed -r \
-e 's/^\s*CC\s*/ /' \
-e 's/\.o/\.c/' | \
tr -d '\n' | \
tr -d '\r' \
)
echo ${SOURCE_LIST}
get_includes "${SOURCE_LIST}"
FILE_LIST=$(echo "${FILE_LIST}" | sed -r -e 's/\s/\r\n/g' )
echo "${FILE_LIST}" > ${FILE_OUT}
沙发 学习学习 这个必须顶,以前学习内核的时候确实遇到这样的问题 只是不知道这么解决 呵,后来者可以收藏了 楼主好人啊,我平时都是一个文件夹一个文件夹添加的 好方法,我下次试试 mark,以后留着看 {:lol:}很好的方法 赞!!!!! 这个方法不错 真心不错,真心感谢 太好了。。之前一直是全部加到工程里面看,太乱了。{:lol:} 学习了,明天试一试。 此方法甚好,我以前也是一个个文件夹添加的。 方法真不错,有空验证一下 绝对赞…方法好。 楼主真用心啊, 学习啦! 赞,楼主太给力了! 本帖最后由 zlyny 于 2015-6-25 09:59 编辑
用这个方法 .h 文件能导入么
------
修改:可以导入,没看全sh脚本 快速、精确导入 Linux Kernel 这个好东西,每次导入Linux内核都是一大推无关的平台 找时间试一试 有心人,方法不错。 好方法,感谢楼主,收藏了! 有想法,做事方法值得学习 这个必须顶,楼主解决了很多人在阅读内核代码的问题。 楼主是不是可以考虑把 ARCH 和 MACH 这两个变量作为脚步的输入参数,这样就不用手动修改脚步内容了。
例如:sg.sharm at91 build_log.txt file_list.txt 必须必须顶啊!非常感谢! 赞一个,这样看linux内核就方便多了 好方法,准备学习Linux,感谢分享。 好办法,参考下 谢谢学习了 有必要看linux源码么 脚本真心强大 强大,赞! 楼主厉害,非常感谢。 非常感谢 不错 学习,谢谢楼主 学习 学习了,实测 添加不完全,那些相关的 .S 汇编文件没有添加. 确实没有考虑到汇编,不过默认设置下,用 SI 阅读 ARM 汇编有难度啊,不知道有没有什么好方法 有时间试试 jujiaqi 发表于 2015-6-25 15:15
确实没有考虑到汇编,不过默认设置下,用 SI 阅读 ARM 汇编有难度啊,不知道有没有什么好方法 ...
建议楼主把acpi这些头文件的搜索,改成目录递归查询的方式,就能不仅linux代码,ucos,mbed,.... 都能用了 jujiaqi 发表于 2015-6-25 15:15
确实没有考虑到汇编,不过默认设置下,用 SI 阅读 ARM 汇编有难度啊,不知道有没有什么好方法 ...
大概看了下LZ的脚本,LZ你只解析了C语言的 CC 没有解析汇编的 AS ,能加上解析AS的么? linux里的汇编就那么几个,比较好找的 bbstr 发表于 2015-6-25 15:39
建议楼主把acpi这些头文件的搜索,改成目录递归查询的方式,就能不仅linux代码,ucos,mbed,.... 都能用了 ...
acpi 这几行可不是搜索头文件,而是做替换,比如,将头文件包含指示“#include <linux/module.h>” 替换成 文件路径"include/linux/module"。
这个方法并不是将 include 下面所有的头文件都包含进来,而是从参与编译的C文件出发,递归搜索引用的头文件,避免包含无用的头文件。 了解了,那如果需要用到的头文件不是在linux/,而是在别的某个路径下的,是-e 's@^.*<(path_to_inc_dir/.*)>@include/\1@' \
? bbstr 发表于 2015-6-25 16:49
了解了,那如果需要用到的头文件不是在linux/,而是在别的某个路径下的,是-e 's@^.*@include/\1@' \ ...
凡是引用 include 目录下头文件的地方,都要做替换,因为编译内核时, include 目录是被加入到系统搜索路径的,所以可以使用
#include <linux/xxx.h>
#include <sound/xxx.h>
#include <video/xxx.h>
liniux sound video 都是 include 目录下的子目录。
所以说,这一句只适合处理包含 include 目录下头文件的情况 gaojieqq123 发表于 2015-6-25 15:48
大概看了下LZ的脚本,LZ你只解析了C语言的 CC 没有解析汇编的 AS ,能加上解析AS的么? ...
# get *.c from kernel build log
SOURCE_LIST=$( \
grep -E '^\s*CC' ${FILE_IN} | \
sed -r \
-e 's/^\s*CC\s*/ /' \
-e 's/\.o/\.c/' | \
tr -d '\n' | \
tr -d '\r' \
)
ASSEMBLY_LIST=$( \
grep -E '^\s*AS' ${FILE_IN} | \
sed -r \
-e 's/^\s*AS\s*/ /' \
-e 's/\.o/\.S/' | \
tr -d '\n' | \
tr -d '\r' \
)
SOURCE_LIST="${SOURCE_LIST}${ASSEMBLY_LIST}"
要添加汇编,可以这样做。对比原来的脚本,就知道改哪里了。
因为不太了解汇编文件的一些包含规则,所以这样做是否准确还不能确定。 wangcjishu 发表于 2015-6-25 09:32
楼主是不是可以考虑把 ARCH 和 MACH 这两个变量作为脚步的输入参数,这样就不用手动修改脚步内容了。
例如 ...
好建议,就是找不到编辑帖子的入口了{:sweat:} 。难道现在发布的帖子不让编辑了吗? 可以导RT-Thread么? 导u-boot,rt-thread,ucos,mbed,。。。。 jujiaqi 发表于 2015-6-25 17:07
好建议,就是找不到编辑帖子的入口了 。难道现在发布的帖子不让编辑了吗? ...
COOL !完美了 !汇编也加入了. 好方法,下次再用。{:handshake:} bbstr 发表于 2015-6-25 17:19
导u-boot,rt-thread,ucos,mbed,。。。。
需要大家自由发挥了,这个脚本提供了一个框架。
如果目标换成 uboot、rtt等,难点在于:
需要清楚其源码结构,才能处理一些像"#include <linux/xxx.h>"这样的路径不完全的头文件包含指令。 jujiaqi 发表于 2015-6-25 17:42
需要大家自由发挥了,这个脚本提供了一个框架。
如果目标换成 uboot、rtt等,难点在于:
需要清楚其源码 ...
{:lol:}这个还是比较清楚的,就是你这个shell脚本一时不好懂 不知道这个思路行不行,将一个工程里的所有头文件做成一个链表,解析c时去链表里查,然后将路径摘出来作为list 这个真是不错 这个方法太神奇了。 一直使用这个 very good 这个办法好,顶起~~ 奇怪了 为什么我执行脚本 输出的的东西都在屏幕上 而没有写进参数2的txt文件{:sad:} jujiaqi 发表于 2015-6-25 17:07
好建议,就是找不到编辑帖子的入口了 。难道现在发布的帖子不让编辑了吗? ...
我看了一下我之前发的帖子也没找到编辑,楼主的脚本写的挺好,感觉递归能把挺复杂的问题给简化了。
此外问个问题sed 中's@^.*<(acpi/.*)>@include/\1@' 中\1是指被替换的那个参数(即^.*<(acpi/.*)>)是吧,这个是sed的内部变量吗? MARK 不一定用sed啊。cut命令也可以 先收藏,谢谢 这个脚本能否用于uboot? 太好了,谢谢分享! 谢谢楼主的经验分享。 kernel mark lize91 发表于 2015-6-25 21:08
奇怪了 为什么我执行脚本 输出的的东西都在屏幕上 而没有写进参数2的txt文件 ...
屏幕上显示的是当前处理的文件。脚本运行结束后,才会创建文件,写入文件列表。 教程写得清晰明白,感谢lz,收藏了先。 收藏,好东西 这个主意不错,值得赞一下。 好东西,Mark 不得不顶,mark之 必须顶起,省去很多时间啊。 是个好方法,学习了!! niub的帖子 实践下 收藏了,非常感谢。
是不是对于bootload等类似的工程也可以这样导入? 想知道国外的linux开发人员一般是怎么搞的 Mark,Source Insight 通过编译文件列表导入Linux代码。谢谢lz分享! 好帖呀~~~~~~~~~~~~~~ 本帖最后由 QQ373466062 于 2015-7-7 10:32 编辑
我也写了一个类似的脚本,不过应该比楼主的这个包含的更全。欢迎拍砖。 一起改进。
http://www.amobbs.com/thread-5626800-1-1.html QQ373466062 发表于 2015-7-7 10:29
我也写了一个类似的脚本,不过应该比楼主的这个包含的更全。欢迎拍砖。 一起改进。
http://www.amobbs.com/ ...
你那个做的挺全面的,而且脚本写得真漂亮 谢谢楼主分享 赞一下,现在天天用这玩意 赞一个,感谢楼主分享 Mark,SourceInsight添加linux内核源代码,谢谢lz分享。 好东西,值得看下!! 谢谢分享! 好东西,以前看的老师加入些垃圾文件,{:biggrin:} 好久不用mark! 收藏,正在学呢~~~ 回头试试 高手,去试试。 挺好的,谢了
好东东{:smile:} 感谢分享,导入确实方便
页:
[1]
2