重编译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 ...
随机推荐
- angularjs(一)基础概念
一.前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,作为一名业界新秀,紧跟时代潮流,学习掌握新知识自然是不敢怠慢.当听到AngularJs这个名字并知道是google在维 ...
- 【面向对象版】HashMap(增删改查)
前言: 关于什么是HashMap,HashMap可以用来做些什么,这些定义类的描述,请参照[简易版]HashMap(增删改查)的内容. 这章节主要是面向实例,直接进行HashMap(增删改查)的演示. ...
- MySQL存储引擎的实际应用以及对MySQL数据库中各主要存储引擎的独特特点的描述
MySQL存储引擎的实际应用以及对MySQL数据库中各主要存储引擎的独特特点的描述: 1.MySQL有多种存储引擎: MyISAM.InnoDB.MERGE.MEMORY(HEAP).BDB(Berk ...
- linux命令(4):mkdir命令
linux mkdir 命令 用来创建指定的名称的目录,要求创建目录的用户在当前目录中具有写权限,并且指定的目录名不能是当前目录中已有的目录. 1.命令格式: mkdir [选项] 目录... 2.命 ...
- 历史命令:history
[root@linux ~]# history [n][root@linux ~]# history [-c][root@linux ~]# history [-raw] histfiles参数:n ...
- [原创]Matlab生成随机数
Matlab中有着丰富的随机数生成函数以应用于不同的情景,我一般使用生成随机的1~N的整数,但是之前了解的只有rand函数,其生成主要为0~1之间的随机数,但是和所预想的有差异.在此进行进行了help ...
- libcurl 函数curl_easy_perform在release下崩溃的问题
今天遇到一个很奇怪的问题: 工程中用到了libcurl, debug可以正常运行,release每次都崩溃,断到curl_easy_perform这一行.堆栈中也得不到有用信息,于是GOOGLE一番, ...
- Java 标识符、数据类型、运算符
一.标识符 1.组成 首字母(字母,下划线,﹩)+其余部分(数字,字母,下划线,﹩) 2.命名规范 ①由大小写字母.下划线.数字.﹩ ②数字不能开头 ③标识符长度没有限制 ④标识符不能是关键字和保留字 ...
- python 类变量 在多线程下的共享与释放问题
最近被多线程给坑了下,没意识到类变量在多线程下是共享的,还有一个就是没意识到 内存释放问题,导致越累越大 1.python 类变量 在多线程情况 下的 是共享的 2.python 类变量 在多线程情况 ...
- PHP正则表达式 /i, /is, /s, /isU等
PHP正则表达式 /i, /is, /s, /isU等 都是些什么东西呢? i 匹配大小写 s 模式中的圆点元字符(.)匹配所有的字符,包括换行符 x 模式中的空白字符除了被转义的或在字符类中的以外完 ...