apue学习第三天——深度解析apue第三版示例程序编译问题

来源:互联网 发布:c语言编程需要什么软件 编辑:程序博客网 时间:2024/06/06 21:06

说“深度解析”,不免贻笑大方了,但菜鸟还是厚着脸皮说吧,初生牛犊不怕虎嘛。
从apuebook.com下载第三版源码,解压,make。遇到错误:cannot find -lbsd。遇到这方面错误,也就是缺少libbsd文件,那么添加:$sudo apt-get install libbsd-dev。make,done!
下面就是对第三版书中1-3的编译问题了。我的apue.3e源码放在/home/*/下(*是我自己的名称),那么同样在/home/*/下,我新建了一个workspace文件夹用于存放书中的示例代码文件。接下来,创建1_3.c文件,将代码输入。gcc 1_3.c。
我这个菜鸟也知道显然会有问题,首先,系统哪里知道你这个#include "apue.h"放在哪里?于是我把它改成了#include "../apue.3e/inlcude/apue.h"(../代表当前路径的前一目录),沾沾自喜的以为解决了一个大问题,gcc编译还是出错,这个错误是这样的:
# gcc 1_3.c
/tmp/cchudidN.o: In function `main':
1_3.c:(.text+0x20): undefined reference to `err_quit'
1_3.c:(.text+0x5b): undefined reference to `err_sys'
collect2: ld returned 1 exit status
哪里出错了呢?从.o这个文件后缀来看,是链接时候出了问题,那么,我们首先分解步骤来看“gcc 1_3.c”这个命令的执行过程。
gcc过程(也就是我们常说的编译过程)分为四步:preprocessing, compilation, assemble, linking,也就是常说的预处理,编译,汇编,链接4个阶段。既然是这四个阶段,那么一步步来看看输出文件是什么呗。
gcc -E test.c -o test.i //预处理,gcc的-E选项可以让预处理停止,输出结果;
gcc -S test.i -o test.s //编译,输出的汇编代码,可打开看一看,很简洁啊!-S是在编译后让gcc停止;
gcc -c test.s -o test.o //汇编,那就是二进制文件啦;
gcc test.o -o test //最后一步,链接,输出执行文件。
这个过程当然会出错,但只是在第四部链接阶段出错。为什么会出错?下面先来看看出错时候,gcc发生了什么情况吧。
(我找到了一个perfect的网站!只能用perfect来形容!GCC and Make Compiling, linking and building C/C++ applications.自己看吧:http://www.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html)
当compiling一个程序的时候,compiler需要#include里面的东西来完成编译,linker需要其它libraries里面的Object files来完成linking。对于一个新加进来的程序,系统显然不愿意自动给你找,比如说#include "apue.h",那就需要你自己告诉它apue.h在哪里了。那么就需要设置gcc的environment variables。具体如下:
PATH: For searching the executables and run-time shared libraries (.dll, .so).

CPATH: For searching the include-paths for headers. It is searched after paths specified in -I<dir> options. C_INCLUDE_PATH and CPLUS_INCLUDE_PATH can be used to specify C and C++ headers if the particular language was indicated in pre-processing.

LIBRARY_PATH: For searching library-paths for link libraries. It is searched after paths specified in -L<dir> options.
CPATH是系统自动查找你程序中#include "*.h"头文件的地方,LIBRARY_PATH是系统自动查找链接时候libraries的地方。你可以通过如下类似的命令查看这几个地方:echo $CPATH。
之前提到的解决办法之一就是上面的道理(http://unix.stackexchange.com/questions/105483/compiling-code-from-apue):
它用如下命令:
gcc -o myls myls.c -I SCADDRESS/include/ -L SCADDRESS/lib/ -lapue
手动指定了到哪里找include,到哪里找lib,这样可行,链接不会发生错误,但是那么复杂的语句,显然不是我想要的。那么接着指定系统查找路径,就不用输那么多命令啦。
输入$cpp -v可以查看在#include “”或者#include <>的时候系统到底自动找了哪些地方,显然它自动寻找的地方不符合你的要求。那么,我们需要的是:How to add a default include path for gcc in Linux?(http://stackoverflow.com/questions/558803/how-to-add-a-default-include-path-for-gcc-in-linux)
答案在下面,关于设置environment variables:http://www.network-theory.co.uk/docs/gccintro/gccintro_23.html。
我们给系统添加自动查找的路径,那么输入以下命令:
$ C_INCLUDE_PATH=/home/*/apue.3e/include //*是我的Ubuntu用户名
$ export C_INCLUDE_PATH //作用是使其生效
$ LIBRARY_PATH=/home/*/apue.3e/lib
$ export LIBRARY_PATH
那么输入 echo $C_INCLUDE_PATH和echo $LIBRARY_PATH来看一下吧!
接下来,1_3示例程序中的#include "apue.h"不用改,直接使用命令:$gcc 1_3.c -lapue即可编译成功!
———————————————————————————————————————————————————
这样下来,算是按照自己的方法解决了编译问题,而不是照着网上来路不明的方法乱改一通,很欣慰。至于最后的-lapue怎么去掉,说实话,我不知道,以后再看,赶快进行后面的程序!
并且,有一个感想,遇到Linux问题,中文论坛或网站上的解决方法很杂乱,不能不明原理就乱套方法。引以为戒。


0 0
原创粉丝点击