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

强符号修改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

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" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏

相册