Linux平台静-动态库中强符号修改工具

  1. 1、前言
  2. 2、nm命令和sed命令用法
    1. 2.1、sed \b用法
    2. 2.2、通过shell执行perl语句
  3. 3、库中强符号修改脚本
  4. THE END!

1、前言

    通常在一个大的项目中,可能需要很多不同的库,如果在不同的库中含有相同的符号,就会导致链接出现问题。为了解决不同库中函数符号的冲突,可以在函数符号前面加上前缀以作区分。

2、nm命令和sed命令用法

nm命令:查看目标文件中的符号。
sed命令:流编辑器,sed命令功能非常强大,尤其是处理字符串流。参考:强大的流编辑器sed用法

强符号:全局变量、全局函数
弱符号与强符号:

对于C++来说,弱符号通常来源于未初始化的全局变量。而默认情况下,编译器将函数和初始化了的全局变量作为强符号。

可以通过gcc的 attribute((weak)) 来定义任何一个强符号为弱符号。

不同的目标文件中不能有同名的强符号,否则不能链接在一起。
参考:http://www.cnblogs.com/whos/archive/2010/10/20/1856274.html

【用法剖析】
http://man.linuxde.net/sed
https://blog.csdn.net/listener51/article/details/81876907

2.1、sed \b用法

2.2、通过shell执行perl语句

3、库中强符号修改脚本

使用方法:

  1. 在配置文件(如下)config.txt中的相应位置填写相应的路径和符号前后缀
  2. 运行脚本命令: ./refinesymol.sh config.txt

配置文件config.txt

#lib path
./build/lib/libxxx.a
#code path
./src
#add prefix
pre_test_
#not modified function prefix or suffix
TEST_
_mmx
_sse
_3dnow
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

强符号修改shell脚本如下:

#!/bin/bash
## usage: refinesymol.sh config.txt
cp $1 config.txt
##删除注释行
sed -i "s/^#.*//g" config.txt
sed -i "/^\$/d" config.txt

##删除每行后面的\r
sed -i "s/\r//g" config.txt

##读取配置信息
config_arr=()
n=0
while read line
do
    config_arr[n++]=$line
done < config.txt

## 获取数组元素个数
arr=${#config_arr[@]}
arr_length=$[$arr-1]

#config_arr[0] 库的路径
#config_arr[1] 代码路径
#config_arr[2] 前缀
#config_arr[3]...[n-1] 保留的函数名
symfile='symbol.txt'
echo ${config_arr[0]}
#导出所有定义的符号到文件symfile中
nm --define-only ${config_arr[0]} > $symfile
cp $symfile file.txt

#去掉symfile中的目标文件名
sed -i "s/\w\+\.o://g" $symfile

#删除所有的弱符号, 只保留强符号
sed -i "s/[0-9a-fA-F]\{8,16\} [TRDC] //g" $symfile

#每行只保留函数名
sed -i "s/[0-9a-fA-F]\{8,16\} [TRDC] //g" $symfile

#删除后缀名_sse,mmx的函数和接口函数名
for((i=3; i<$arr_length; i++))
do
sed -i 's/.*'${config_arr[$i]}'\b//g' $symfile  ##删除带后缀的函数
sed -i 's/^'${config_arr[$i]}'.*//g' $symfile  ##删除带前缀的函数
echo ${config_arr[$i]}

#处理函数名前加了下划线的情况
sed -i "s/\b_//g" $symfile
#去除r表示的带.的名称
sed -i "s/.*\..*//g" $symfile

#删除空行
sed -i "/^\$/d" $symfile

#一次处理每个函数名
while read line
do
    tmp_name=$(echo $line)
    echo $tmp_name
    new_name=${config_arr[2]}$tmp_name  
    echo "rename $line to $new_name" >>rename.txt
    echo ${config_arr[1]}
    find ${config_arr[1]} -name '*.h' -print0 | xargs -0 perl -pi 's/\b'$line'\b/'$new_name'/g'
    find ${config_arr[1]} -name '*.c' -print0 | xargs -0 perl -pi 's/\b'$line'\b/'$new_name'/g'
    find ${config_arr[1]} -name '*.cpp' -print0 | xargs -0 perl -pi 's/\b'$line'\b/'$new_name'/g'
    find ${config_arr[1]} -name '*.asm' -print0 | xargs -0 perl -pi 's/\b'$line'\b/'$new_name'/g'
done < $symfile
shell复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

THE END!


本博文只能阅读,谢绝转载,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2963033731@qq.com

文章标题:Linux平台静-动态库中强符号修改工具

字数:887

本文作者:Soaring Lee

发布时间:2018-11-29, 15:13:47

最后更新:2021-06-14, 12:13:44

原始链接:https://soaringleefighting.github.io/2018/11/29/【Tools系列】Linux平台静-动态库中强符号修改工具/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

0 条评论
未登录用户
支持 Markdown 语法

来做第一个留言的人吧!

×

喜欢就点赞,疼爱就打赏

相册