转: 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命令源代码的更多相关文章

  1. 如何查看linux命令源代码

    如何查看linux命令源代码 用linux一段时间了,有时候想看看ls.cat.more等命令的源代码,在下载的内核源码中用cscope没能找到,在网上搜索了一下,将方 法总结如下: 以搜索ls命令源 ...

  2. Ubuntu:编译Linux内核源代码和内核模块

    1. 目的 内核模块需要运行在Linux 3.8.13内核中,因此需要为此内核重新编译内核模块源代码. 2. 步骤 1.在Ubuntu 14.04 64位(内核3.13.0-24-generic)上, ...

  3. linux内核源代码、配置与编译

    内核源代码下载:www.kernel.org Linux内核源代码采用树形结构进行组织,非常合理地把功能相关的文件都放在同一个子目录下,使得程序更具可读性. linux内核代码最好不要在windows ...

  4. 【hadoop之翊】——CentOS6.5 Linux上面编译Hadoop2.4源代码

    今天来说说编译hadoop源代码的事情吧~ 1.首先下载源代码 地址:http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.4.0/ 2.加压t ...

  5. Android源码浅析(四)——我在Android开发中常用到的adb命令,Linux命令,源码编译命令

    Android源码浅析(四)--我在Android开发中常用到的adb命令,Linux命令,源码编译命令 我自己平时开发的时候积累的一些命令,希望对你有所帮助 adb是什么?: adb的全称为Andr ...

  6. make 编译 linux 内核是单线程的任务 才用-j4命令使用4 线程加速

    今天使用 make 编译 linux 内核,发现CPU只用了30%多一点,而我的电脑是4核的,所以如果没有意外的话,make 编译 linux 内核的任务是用单线程做的. 又了解到,使用-j4参数可以 ...

  7. QA要懂的Linux命令

    <一>软件安装相关QA经常需要安装测试软件(jmeter.Mock.python环境搭建.java环境搭建),或者配置测试环境(nginx.ci等),需要了解linux下如何安装软件.在工 ...

  8. linux命令学习笔记

    操作文件和文件夹: copy: $ cp file1 file2 $ cp -r dir1 dir2 move: $ mv file .. $ mv file dir/ rename: $ mv fi ...

  9. python基础学习1(linux命令)

    读研时转人工智能,机器学习方向,必然要用到python,于是开始自学. 1.环境: 使用linux环境下python编译,熟悉各种基本操作. 2.书籍: --  笨方法学python --   a b ...

随机推荐

  1. tfs 任务自定义项

    vs 命令 cd C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE\PrivateAssemblies 导出工作项类型文件 修改xml ...

  2. 手把手教你用新浪云容器 Java 搭建自己的网站

    经过一段时间的开发,更新,迭代,新浪云容器 Java 环境逐渐成熟起来,相比过去的 Java 运行环境,可用性和易用性都得到了大量的提升.同时也收到了不少用户反馈的使用问题,特此在这篇文章里综合介绍一 ...

  3. HDU2063 过山车

    过山车 RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐.但是, ...

  4. JS的prototype

    初步理解: 在说prototype和constructor之前我们先得看几个例子. 1 2 3 4 function name(obj){     alert(obj)//"uw3c&quo ...

  5. C#中线程对控件的访问

    Control类提供了一个Invoke方法来给子线程访问主线程的控件,它的原型是酱紫的: object.Control.Invoke(Delegate method); object.Control. ...

  6. OC中类别、扩展、协议与委托

    一.类别(category) 类别(category)——通过使用类别,我们可以动态地为现有的类添加新方法,而且可以将类定义模块化地分不到多个相关文件中.通常只在类别中定义方法.(类别,接口部分的定义 ...

  7. Cookie的Secure属性

    基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie ...

  8. tomcat(二)--tomcat结构

    Tomcat结构及组件介绍 上面的层次结构在server.xml中有体现 <Server> <Service> <Connector> <Engine> ...

  9. Memcached Memcached.ClientLibrary.SockIOPool”的类型初始值设定项引发异常

    又一次遭遇"xxx类型初始值设定项引发异常" 下了个c#实现的轻量级IoC开源项目,可是在本地使用时发现一运行就捕捉到"类型初始值设定项引发异常"的异常信息,调 ...

  10. linuxMint下面的截图工具

    sudo apt-get install shutter 然后配合系统快捷键,我定义的和qq的截屏一样的.用着感觉很舒服.