重编译Linux命令源代码
转: http://blog.csdn.net/endoresu/article/details/6967435
以su命令为例。
查看su命令的路径:
# which su
/bin/su
查看su是由哪个包安装的:
# rpm -qf /bin/su
coreutils-5.97-12.1.el5
去网上搜索“coreutils-5.97-12.1.el5.src.rpm”包,注意,后面还多了个“.src”,表示源代码的安装包。
将下载到的源代码的包直接安装是行不通的,需要先安装下列.rpm包:
elfutils-libs-0.125-3.el5.i386.rpm
elfutils-0.125-3.el5.i386.rpm
rpm-build-4.4.2-47.el5.i386.rpm
安装完上面的包,就可以安装任意源代码的包了。注意,使用命令
# rpm -ivh coreutils-5.97-12.1.el5.src.rpm
安装时会报错,但这没影响。安装包依然会在/usr/src/redhat/SOURCES/目录下生成我们想要的。
进入/usr/src/redhat/SOURCES/目录,解压缩coreutils-5.97.tar.bz2:
# bzip2 -d coreutils-5.97.tar.bz2
#tar -xvf coreutils-5.97.tar
进入解压出来的coreutils-5.97目录,各命令的源代码就放在src目录中,需要的头文件放在lib目录中。直接用
# gcc -I/usr/src/redhat/SOURCES/coreutils-5.97/lib/ -E -o su.i /usr/src/redhat/SOURCES/coreutils-5.97/src/su.c
是无法生成预处理文件的,因为源代码需要的某些头文件是由coreutils-5.97目录下的configure脚本产生的,有些头文件是由make命令产生的。
运行configure配置脚本:
# ./configure --prefix=/tmp/coreutils/prefix
其中--prefix参数的作用是指定安装路径为等号后面的“/tmp/coreutils/prefix”,这是一个我自建的目录。configure脚本将生成Makefile文件,这是一个提供给make命令用于编译的配置文件,其中包含当前安装环境的信息。
运行make命令,这里我们需要重定向命令的输出,以便从中查找有用的信息:
# make>/tmp/coreutils/make.log
步骤到此,其实所有命令的可执行程序已经被编译出来了,在src目录下,只是还没移动到我们指定的安装路径去,文件的属性也还没修改。只要再执行
# make install
这个命令才算完全安装完成。这里我们不需要这步。
到这一步,如果你修改了su命令的源代码,想重新编译的话需要把整个所有命令都编译一遍,非常浪费时间。下面介绍下怎么把su.c单独拿出来编译。
我们把su命令的源代码复制到自己的目录下,我这边是/tmp/coreutils/
然后就能预编译了:
# gcc -E -I/usr/src/redhat/SOURCES/coreutils-5.97/lib/
-I/usr/src/redhat/SOURCES/coreutils-5.97/
-I/usr/src/redhat/SOURCES/coreutils-5.97/src/ -o su.i su.c
-E参数告诉gcc只要进行预编译,-o参数告诉gcc将预编译输出到文件su.i,-I/usr/src/redhat/SOURCES
/coreutils-5.97/lib/告诉gcc在/usr/src/redhat/SOURCES/coreutils-5.97/lib/目录下
寻找头文件。
将预编译文件su.i编译成.o文件:
# gcc -c -o su.o su.i
-c参数告诉gcc将源代码编译成.o文件。
链接静态库libcoreutils.a、动态库libcrypt.so,生成可执行文件su:
# gcc -L/usr/src/redhat/SOURCES/coreutils-5.97/lib/ -L/usr/lib/ -o su su.o -lcoreutils -lcrypt
注意两个-L参数写在一起,两个-l参数写在一起。-L参数告诉gcc库文件的位置,-l参数指明了库文件的文件名。如-lcoreutils,其文件名
为libcoreutils,在前面加个lib就行了。至于后缀,没有什么讲究,因为一般名字都不一样,就不深究了。.a库是静态库,链接完可以独立库运
行;.so库是动态库,链接完缺少库就不能单独运行。
简单地用
# gcc -o su su.o
会报错,错误信息都是找不到需要的函数。因为.o文件的源代码中调用了本身没有具体实现的函数(可能声明过),这些函数也编译在了包含它的.o文件或者.a、.so文件。在编译成可执行文件时,需要将这些可执行文件一并链接起来。
libcoreutils.a文件包含了编译所有命令可能需要调用的函数。
如何知道一个.o/.a/.so文件中包含哪些函数?使用nm命令:
#nm /usr/lib/libcrypt.so
OK。到此你修改su命令的源代码,可以单独编译它了。不用为了编译su命令的源代码,把整个命令都编译一遍。可以把需要的头文件、库复制下来。其
中config.h这个头文件configure脚本产生的,它在/usr/src/redhat/SOURCES/coreutils-5.97/目录
下面;localedir.h在/usr/src/redhat/SOURCES/coreutils-5.97/src/目录下面,由make命令产生
的。其实localedir.h的内容非常简单
#define LOCALEDIR "/tmp/coreutils/prefix//share/locale"
就是把执行configure脚本时prefix参数的内容后面接上“/share/locale”。完全可以自己写一个。但是make命令还是要执行的,静态库libcoreutils.a是由make命令产生的。
直接把所有头文件复制到一个目录下,-I参数就省了很多。
两个需要的库路径为:
/usr/src/redhat/SOURCES/coreutils-5.97/lib/libcoreutils.a
/usr/lib/libcrypt.so
config.h头文件路径为:
/usr/src/redhat/SOURCES/coreutils-5.97/config.h
其他头文件的路径为:
/usr/src/redhat/SOURCES/coreutils-5.97/lib/*.h
/usr/src/redhat/SOURCES/coreutils-5.97/src/*.h
删除之前安装的命令,很简单,之前configure的脚本指定prefix参数的值为/tmp/coreutils/prefix,参数这个目录就行了。然后还要清除由configure、make产生的文件:
# make clean
# make distclean
重编译Linux命令源代码的更多相关文章
- 如何查看linux命令源代码
如何查看linux命令源代码 用linux一段时间了,有时候想看看ls.cat.more等命令的源代码,在下载的内核源码中用cscope没能找到,在网上搜索了一下,将方 法总结如下: 以搜索ls命令源 ...
- Ubuntu:编译Linux内核源代码和内核模块
1. 目的 内核模块需要运行在Linux 3.8.13内核中,因此需要为此内核重新编译内核模块源代码. 2. 步骤 1.在Ubuntu 14.04 64位(内核3.13.0-24-generic)上, ...
- linux内核源代码、配置与编译
内核源代码下载:www.kernel.org Linux内核源代码采用树形结构进行组织,非常合理地把功能相关的文件都放在同一个子目录下,使得程序更具可读性. linux内核代码最好不要在windows ...
- 【hadoop之翊】——CentOS6.5 Linux上面编译Hadoop2.4源代码
今天来说说编译hadoop源代码的事情吧~ 1.首先下载源代码 地址:http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.4.0/ 2.加压t ...
- Android源码浅析(四)——我在Android开发中常用到的adb命令,Linux命令,源码编译命令
Android源码浅析(四)--我在Android开发中常用到的adb命令,Linux命令,源码编译命令 我自己平时开发的时候积累的一些命令,希望对你有所帮助 adb是什么?: adb的全称为Andr ...
- make 编译 linux 内核是单线程的任务 才用-j4命令使用4 线程加速
今天使用 make 编译 linux 内核,发现CPU只用了30%多一点,而我的电脑是4核的,所以如果没有意外的话,make 编译 linux 内核的任务是用单线程做的. 又了解到,使用-j4参数可以 ...
- QA要懂的Linux命令
<一>软件安装相关QA经常需要安装测试软件(jmeter.Mock.python环境搭建.java环境搭建),或者配置测试环境(nginx.ci等),需要了解linux下如何安装软件.在工 ...
- linux命令学习笔记
操作文件和文件夹: copy: $ cp file1 file2 $ cp -r dir1 dir2 move: $ mv file .. $ mv file dir/ rename: $ mv fi ...
- python基础学习1(linux命令)
读研时转人工智能,机器学习方向,必然要用到python,于是开始自学. 1.环境: 使用linux环境下python编译,熟悉各种基本操作. 2.书籍: -- 笨方法学python -- a b ...
随机推荐
- lua 代码风格
参考 http://www.kancloud.cn/kancloud/lua_style_guide/66327 1.命名 1.命名法:小驼峰命名法,大驼峰命名法(Pascal命名法),小下划线命名 ...
- c++的默认构造函数 VS 深拷贝(值拷贝) 与 浅拷贝(位拷贝)
C++默认为类生成了四个缺省函数: A(void); // 缺省的无参数构造函数 A(const A &a); // 缺省的拷贝构造函数 ~A(void); // 缺省的析构函数 A & ...
- 自用debug单元
将之前的内存查看单元小幅修改,加上文件操作和计时,组成了一个自用debug单元,使用方法如示例. 此单元便捷之处在于直接将#define DEBUG注释掉而无需改动源码,即可取消debug模式. #d ...
- Linux中多线程信号的处理
1. 博文:Linux多线程中使用信号-1 http://blog.csdn.net/qq276592716/article/details/7325250 2. 博文:Linux多线程信号总结 ...
- 树莓派配置文档 config.txt 说明(转)
原文连接:http://elinux.org/RPi_config.txt 由于树莓派并没有传统意义上的BIOS, 所以现在各种系统配置参数通常被存在"config.txt"这个文 ...
- june 14
Thank you for your applying for employment with our company. Your application is now being processed ...
- java中运算符的优先级
所谓优先级,就是在表达式中的运算顺序.Java 中常用的运算符的优先级如下表所示: 级别为 1 的优先级最高,级别 11 的优先级最低.譬如,x = 7 + 3 * 2 得到的结果是 13 &quo ...
- hdu 1251 统计难题 (字典树入门题)
/******************************************************* 题目: 统计难题 (hdu 1251) 链接: http://acm.hdu.edu. ...
- VBA使用的Randomize和DoEvents
Randomize private function getInt() dim n,m as integer Randomize n=1 m=3 getInt=Int((m+1-n)*rnd + n) ...
- 对于cookie和session的形象解释
生活中的场景: 一群人,买豆浆,也不排队,乱哄哄的 豆浆现磨. 先交钱,交完钱蹲在一边等. 这个老板非常健忘! 记忆时间:转脸就忘. 李四给老板钱<--->"大杯黄豆!" ...