转: 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. IntelliJ设置鼠标悬浮提示和修改快捷键

    IntelliJ设置鼠标悬浮提示和修改快捷键 设置鼠标悬浮提示 修改快捷键 进入设置菜单 删除原来的快捷键(注:你可以选择保留原来的快捷键,同时使用两个快捷键) Good Luck

  2. Samba 共享文件后在Windows 上无法访问的问题

    /etc/samba/smb.conf的配置如下: #============================ Share Definitions ========================== ...

  3. maxiang.io css

    /**设置你自己的CSS.例如:h1 { border-bottom: 1px solid #ccc; line-height:1.6;}body { background:#FDFFD0} **/p ...

  4. VoLTE 注册流程

    1.开关按钮位置:   设置--> 更多--> 移动网络--> 增强型4G LTE模式 2.该设置开关使用了SwitchPreference控件,addEnhanced4GLteSw ...

  5. 使用AS编译jni文件无法编译出arm64-v8a,x86_64和mips64平台的.so文件的解决方法

    我用的插件版本是:classpath 'com.android.tools.build:gradle-experimental:0.4.0',AS集成和使用ndk编译项目参考官方demo:https: ...

  6. mysql中的where和having子句的区别

    mysql中的where和having子句的区别 having的用法 having字句可以让我们筛选成组后的各种数据,where字句在聚合前先筛选记录,也就是说作用在group by和having字句 ...

  7. android 很多牛叉布局github地址(转)

    原文地址 http://blog.csdn.net/luo15309823081/article/details/41449929 点击可到达github-------https://github.c ...

  8. Linux系统调用

    在前面,我们接触到了很多函数能够实现系统相关的功能,比如解析命令行参数.控制进程以及映射内存等等.实际上,这些函数能够分为两大类: 库函数--这些函数就像普通函数一样,参数放置在寄存器或者栈里,运行时 ...

  9. VS2010--canot determine the locationof the vs common tools folder

    在vcvars32.bat第一行后复制 @SET VSINSTALLDIR=c:\Program Files\Microsoft Visual Studio 10.0 @SET VCINSTALLDI ...

  10. cxf+spring+数字签名开发webservice(一)

    数字证书的准备         下面做的服务端和客户端证书在例子中无法加解密,不知道什么原因,我是使用正式环境中的客户端和服务端进行开发测试的,所以需要大家自己去准备证书,或者有人知道为什么jdk生成 ...