UNIX 高级环境编程 源码编译——方法

注:gilbc 源码下载地址:http://www.oschina.net/code/explore/glibc-2.9linux

/*******************************************************************************
*第0种-最简单实用果真是最简单的,后面的方法在feodra上总是报错,不过ubuntu上能够第二在方法仍是可行的)
*
*******************************************************************************/.

1.直接进入源码目录的lib目录
  cd lib
2.执行make命令
  make -f linux.mk
3.把生成的libapue.a与apue.h拷贝到你的源代码目录。如你的file目录下
4.使用gcc -o ls1 ls1.c  libapue.a来编译你的源代码
5.成功

/*******************************************************************************
*第一种
*
*******************************************************************************/.


《UNIX环境高级编程》(这里使用的是第二版本的源码)每一个历程中,都会有这样一行源码:
#include "apue.h"
    这个头文件是做者把把每一个例程中经常使用的标准头文件,一些经常使用的出错处理函数(err_**()之类的函

数)和一些经常使用的宏定义给整理在一个头文件中。这个能够省去在每一个例程中录入较多的重复代码,这样可

以减小每一个例程的长度。给读者带来了很多麻烦。下面给出一种源代码的编译方法。


一、解压文件到apue.2e目录
二、修改相应平台的文件,我使用的是linux,因此修改Make.defines.linux
你修改的只须要这一行WKDIR=/home/your_dir/apue2e_src/apue.2e,改为本身的目录路径
三、cd到apue.2e目录执行make -f linux.mk,以后你会在lib目录下面找到libapue.a这个文件.
如今,你能够把它拷贝到你能寻找的地方,在编写例子的时候,你就能够

四、拷贝apue2e_src/apue.2e/include/apue.h和apue2e_src/apue.2e/lib/libapue.a

到你的源代码目录。

五、使用gcc -o hello hello.c libapue.a来编译你的源代码

/*******************************************************************************
*第二种
*
*******************************************************************************/


最近在看apue的第二版,刚才在Linux下把随书的源代码编译了一遍,仍是稍微花了点时间,做为备忘把编译过

程记录下来
随书的源代码可从www.apuebook.com上得到,下载后的解压获得名为apue.2e的目录,在个人系统中该目录的

完整路径为/home/se/apue.2e
接着首先是要阅读/home/se/apue.2e/README,这是由apue第二版的做者Steve Rago写的如何编译随书代码的

基本指导以及部分自本书初版以来的更改,主要内容以下:
Some source changes needed to be made after the book went out for the first
printing.  I forgot to make corresponding changes in the source tree on the
system used to develop the book.  The changes are summarized below.
1. lib/recvfd.c and sockets/recvfd.c - needed sys/uio.h on Mac OS X
2. lib/sendfd.c and sockets/sendfd.c - needed sys/uio.h on Mac OS X
3. stdio/buf.c - added code for Mac OS X
4. threadctl/suspend.c - changed wait to waitloc to avoid symbol definition
 clash on Solaris
5. include/apue.h - FreeBSD compiles work better if we rely on the default
 system settings.  Solaris needed a different XOPEN_SOURCE definition
 and also a CMSG_LEN definition.
To build the source, edit the Make.defines.* file for your system and set
WKDIR to the pathname of the tree containing the source code.  Then just
run "make".  It should figure out the system type and build the source for
that platform automatically.  If you are running on a system other than
FreeBSD, Linux, Mac OS X, or Solaris, you'll need to modify the makefiles
to include the settings for your system.  Also, you'll probably need to
modify the source code to get it to build on a different operating system.
The example source was compiled and tested using FreeBSD 5.2.1, Linux 2.4.22,
Mac OS X 10.3, and Solaris 9.
For FAQs, updated source code, and the lost chapter, see http://www.apuebook.com.
Please direct questions, suggestions, and bug reports to sar@apuebook.com.
 
基本内容就是你用的系统若是是FreeBSD,Linux,Mac OS X或是Solaris,那么你只要修改相应的

Make.defines.*文件(即若是你使用的是Linux,那么你须要修改 Make.defines.linux文件的内容),将其中的

设置改成你本身系统的设置而后在apue.2e目录下运行make就ok了.全部的代码都在 FreeBSD 5.2.1,Linux 

2.4.22,Mac OS X 10.3,Solaris 9上编译经过.
 
总的来讲要编译成功是很简单的,但总会由于平台的不一样会出现一些错误,这时你就要根据本身系统的配置情

况来进行修改了
1.首先粗略的看了一下makefile的内容,make首先会执行脚本文件systype.sh,判断所用系统的类型,而后根

据该类型选择对应的Make.defines文件.这里所要作的就是给systype.sh添加执行权限,chmod u+x 

systype.sh
2.由于我用的是Linux,因此先看Make.defines.linux,须要修改的地方是WKDIR=/home/sar/apue.2e,把WKDIR

改成你本身的工做目录,在我这就是改成WKDIR=/home/se/apue.2e,这个路径在编译时寻找"apue.h"头文件时

使用.

3.而后我尝试性的运行了一次make,果真有问题,在进入std目录后报错了,说找不到nawk命令,nawk是new 

awk,而个人系统上只有awk,这时你有两种选择,能够在运行make以前执行alias nawk='awk',这样本质上是给

awk取了个叫nawk的别名,实际上运行的仍是awk,另外一种方法就是修改WKDIR/std /linux.mk,把第10行和15行

中的nawk都改成awk,至于什么是awk和nawk,以及它们的使用方法能够参考我以前收藏的一篇文章

http://www.360doc.com/showWeb/0/0/308938.aspx
在这里,awk用来分别从makeconf.awk和makeopt.awk生成conf.c和options.c源文件,注意,在修改了linux.mk

或是添加了alias以后要先把以前make失败时生成的conf.c和options.c删除,不然会报错

4.进行了上述的修改后,回到WKDIR,运行make,ok,没有报错,编译成功了

以后,若是你要利用apue的lib,编译运行本身的代码,必须在编译时加上-I/home/se/apue.2e/include选项,

在链接时加上-L/home/se/apue.2e/lib source.c /home/se/apue.2e/lib/libapue.a选项,这样你就能够利

用apue提供的想err_sys等函数了^_^

/*******************************************************************************
*第三种
*
*******************************************************************************/


unix环境高级编程编译方法

    这里要谈到的一个问题就是该书中的源代码编译的问题。此书中差很少每一个历程中,都会有这样一行源

码:

    #include "ourhdr.h"
      
    在第二版中改成:
    #include "apue.h"

        这个头文件是做者把把每一个例程中经常使用的标准头文件,一些经常使用的出错处理函数(err_**()之类

的函数)和一些经常使用的宏定义给整理在一个头文件中。这个能够省去在每一个例程中录入较多的重复代码,这

样能够减小每一个例程的长度。可是,这样就给读者带来了很多麻烦。由于咱们还要去搞明白如何把这个头文

件编译,而后作成库文件,添加到咱们的系统中。特别读于初学者,原本满怀信心的,结果在编译第一个程

序的时候就出现了问题。我也没有搞明白如何把 "ourhdr.h"静态的编译到系统中。

        不过,不明白如何使用"ourhdr.h"这个头文件,并不会影响咱们学习APUE,也不会影响咱们编译和

运行每个例程。其实,简单的想一下,若是一个 C程序要能顺利的编译和运行,除了咱们要语法正确等方

面外,最根本的是要保证咱们程序中所调用的函数以及宏等等都要有完整的来源,也就是必须包含全部调用

函数和宏所在的头文件。对于一个具体的源程序,若是咱们正确的包含了头文件,那么剩下的就是程序本生

语法方面应该注意的事项。

        如何肯定系统调用函数包含在那个头文件中呢?这在Unix/Linux系统下并不是一件难事。Unix/Linux

下命令man能够帮助咱们找到。man命令不只能够帮助咱们查找通常命令的用法,同时提供不一样层次的帮助诸

如系统调用或者管理员级别的命令等等(譬如FreeBSD6.1中,man 1是用户专用手册,man 2是系统调用,

man 3是库函数查询等等)。

        下面咱们就以APUE书中程序1-1 (实现ls命令部分功能)为例,来讲明如何将书中的程序改编成全

部使用标准头文件的程序。其中,操做系统用的是FreeBSD6.1,通过相应的修改能够在书中所说的几个Unix

系统及Linux系统中运行,我也曾在Debian Linux下成功编译和运行该程序。书中1-1.c的原始代码以下:

    #include <sys/types.h>
    #include <dirent.h>
    #include "ourhdr.h"

    int
    main(int argc, char *argv[])
    {
        DIR                *dp;
        struct dirent    *dirp;

        if (argc != 2)
            err_quit("usage: ls directory_name");

        if ((dp = opendir(argv[1])) == NULL)
            err_sys("can't open %s", argv[1]);
        while ((dirp = readdir(dp)) != NULL)
            printf("%s"n", dirp->d_name);

        closedir(dp);
        exit(0);
    }

        从书后面的附录中能够看到"ourhdr.h"的内容比较多,包含了比较多的经常使用头文件,一些宏定义和

一些经常使用函数和出错函数的定义。其实,对于每个具体的程序,咱们只须要找到该程序中用到的头文件即

可。

        该1-1.c中所用到的系统函数调用有:opnedir(),readdir(),printf(),closedir()和exit()。
    其中,对于经常使用的函数prinft()和exit(),它们所在的头文件通常都知道,分别是<stdio.h>和< 

stdlib.h>。而对于opnedir (),readdir()和closedir(),咱们能够经过man opendir,man readdir,man 

closedir获得这三个关于目录操做的函数所在的头文件都是:<sys/types.h>和<dirent.h>。这两个头文件

在源程序中也已经列出。

        其次,1-1.c中还用到了做者自定义的两个函数:err_quit()和err_sys()。这两个函数主要使用来

进行出错处理的。固然,使用这两个函数对错误信息的处理是比较完善的。可是,做为咱们学习来说,了解

程序的核心功能是首要的,咱们能够将出错处理简化一点,即当遇到错误的时候,咱们只简单的使用

printf()函数来提示一下有错误发生。固然,用printf()来进行出错处理并非一种很合理的方法,并且往

往咱们看不到更关键的错误信息,但对于咱们仅仅做为学习来用仍是能够接受的。毕竟咱们要理解的核心部

分是程序的功能实现,出错处理在于其次。

       经过以上的说明,咱们能够将1-1.c修改成以下内容:

    #include <sys/types.h>
    #include <dirent.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main(int argc, char* argv[])
    {
        DIR *dp;
        struct dirent *dirp;
       
        if(argc != 2)
        {
            printf("You need input the directory name."n");
            exit(1);  
        }
       
        if((dp = opendir(argv[1])) == NULL)
        {
            printf("cannot open %s"n", argv[1]);
            exit(1);   
        }

        while ((dirp = readdir(dp)) != NULL)
            printf("%s"n", dirp->d_name);


        closedir(dp);

        exit(0);
    }

        这样修改后的程序已经与做者的头文件"ourhdr.h"没有关系,能够单独的进行编译。我使用的是

root用户,执行命令:

    # gcc 1-1.c  //生成目标文件a.out
    或者
    # gcc -o 1-1 1-1.c  //生成目标文件1-1

        没有任何错误和警告,说明编译成功。这时咱们执行生成的目标文件:

    # ./a.out /home
    或者
    # ./1-1 /home

        则会列出/home路径下的全部文件,包括目录(.)和(..)。

        经过这样的方法,基本上咱们能够将该书中全部的例程修改为不包含"ourhdr.h"的程序。这样,我

们就能够单独的编译每个例程,而不用顾及做者所给的杂凑的头文件。同时这种比较笨的方法,反而有利

于帮助咱们了解不一样系统调用所对应的头文件,对于学习来讲,这应该是一件好事。编程

相关文章
相关标签/搜索