LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2745|回复: 19

终于迈出了第一步!

[复制链接]
发表于 2002-11-30 13:47:48 | 显示全部楼层 |阅读模式
用了一天时间,终于把bash编译好了。最大的困难在于修改源程序,前后加起来总共改了十几处,有些地方还要反复修改。让人感到奇怪的是少了库文件也会提示为函数的问题,使人找不到方向。
发表于 2002-11-30 14:56:17 | 显示全部楼层
怎么bash的源程序还要修改呢?还有就是少库文件。具体说一下吧。
发表于 2002-11-30 16:33:50 | 显示全部楼层
用一天编译bash
发表于 2002-11-30 16:44:09 | 显示全部楼层
你是用的什么版本?是4.0rc1么?我在装它的时候,没有改过啊,挺正常的。
发表于 2002-11-30 17:04:16 | 显示全部楼层
cclnw阿,我通过linuxsir给你email,你看见没有?

就是说作为linuxsir中的高手( 我没说高手中的高手吧 ) 把gentoo的安装介绍一下吧,特别是你觉得当初比较费力的地方。现在版上还没有比较完善的gentoo文档。
还有就是原来你发的那个screenshot看不了了,再发几个吧 :)  (想看哦)
 楼主| 发表于 2002-11-30 17:27:04 | 显示全部楼层
第一次编译bash-2.05a时,编译失败,出现提示:
gcc -s  -DPROGRAM='"bash"' -DCONF_HOSTTYPE='"i686"' -DCONF_OSTYPE='"linux-gnu"' -DCONF_MACHTYPE='"i686-pc-linux-gnu"' -DCONF_VENDOR='"pc"' -DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib -g -O2 -c shell.c
In file included from shell.h:41,
                 from shell.c:48:
                 externs.h:163: conflicting types for `gethostname'
                 /usr/include/unistd.h:734: previous declaration of `gethostname'
                 externs.h:196: conflicting types for `strncasecmp'
                 /usr/include/string.h:277: previous declaration of `strncasecmp'
                 make: *** [shell.o] Error 1
当时就把我给吓一跳。后来冷静地看了错误提示,发现是函数类型冲突,于是打开shell.c,发现第48行为externs.h。看来是externs.h的问题。于是以打开externs.h,在第163行找到gethostname的函数定义:
extern int gethostname __P((char *, int));
再到/usr/include/unistd.h中找到gethostname的函数定义:
extern int gethostname (char *__name, size_t __len) __THROW;
两相比较,发现这两函数是不一样。我虽然学习过linux下的C编程,但象这么复杂的函数定义还是第一次看到,查书也找不到到__P和__THROW是什么意思。size_t的宏定义我没有找到,但在/usr/include/bits/types.h中和/usr/include/sys/types.h中ssize_t的宏定义都是int,所以我想size_t应该与ssize_t差不多,也是int。经过反复考虑,决定先把参数类型变为一致。于是将externs.h中的gethostname函数定义中的int改为size_t,即:
extern int gethostname __P((char *, size_t));
重新编译,出来一堆错误提示,仔细看看,没有gethostname的问题,剩下strncasecmp的错误提示。看来这招管用,继续对比strncasecmp的函数定义,也是一样的问题,照此办理后,以出来一堆错误提示,但没有发现这两个问题的错误提示重复出现,应该说是成功解决。其它类似的情况我就不说了。
但是,这招碰到下面这个问题就不灵了。
make[1]: Entering directory `/mnt/lfs/static/src/bash-2.05a/builtins'
rm -f mkbuiltins.o
gcc -s -c  -DHAVE_CONFIG_H -DSHELL   -I. -I..  -I.. -I../include -I../lib -I.  mkbuiltins.c
mkbuiltins.c:136: warning: static declaration for `rename' follows non-static
mkbuiltins.c: In function `rename':
mkbuiltins.c:1425: argument `from' doesn't match prototype
mkbuiltins.c:136: prototype declaration
mkbuiltins.c:1425: argument `to' doesn't match prototype
mkbuiltins.c:136: prototype declaration
make[1]: *** [mkbuiltins.o] Error 1
make[1]: Leaving directory `/mnt/lfs/static/src/bash-2.05a/builtins'
make: *** [builtins/builtext.h] Error 1
打开/mnt/lfs/static/src/bash-2.05a/builtins下的mkbuiltins.c文件,发现第136行的rename的函数定义为:
static int rename ();
而1423行开始的rename函数为:
  1. static int
  2. rename (from, to)
  3.      char *from, *to;
  4. {
  5.   unlink (to);
  6.   if (link (from, to) < 0)
  7.     return (-1);
  8.   unlink (from);
  9.   return (0);
  10. }
复制代码

我左看右看,怎么也看不出有什么错误。因为在同一个函数内部,所有函数都采用类似的定义,如is_special_builtin ()的定义方式:
static int is_special_builtin ();
和它的内容:
  1. static int
  2. is_special_builtin (name)
  3.      char *name;
  4. {
  5.   return (_find_in_table (name, special_builtins));
  6. }
复制代码

与rename相比是一样的。没有办法,只好先按照经验,让函数声明和类型保持一致。将rename函数声明改为:
static int rename (char *,char *);
编译,出现错误提示:
make[1]: Entering directory `/mnt/lfs/static/src/bash-2.05a/builtins'
rm -f mkbuiltins.o
gcc -s -c  -DHAVE_CONFIG_H -DSHELL   -I. -I..  -I.. -I../include -I../lib -I.  mkbuiltins.c
mkbuiltins.c:137: conflicting types for `rename'
/usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.2/include/stdio.h:153: previous declaration of `rename'
make[1]: *** [mkbuiltins.o] Error 1
make[1]: Leaving directory `/mnt/lfs/static/src/bash-2.05a/builtins'
make: *** [builtins/builtext.h] Error 1
在/usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.2/include/stdio.h第153行找到rename函数,其定义为:
extern int rename (__const char *__old, __const char *__new) __THROW;
与mkbuiltins.c的相比较,看不出应该改什么地方。从mkbuiltins.c中的rename()函数的定义来看,前面加有static字样,应该是一个局部函数的声明,即使与其它函数重名也应该没有关系,怎么会编译出错?迫于无奈,只好将mkbuiltins.c中的rename()函数改名为rename1(),编译后仍然出现一堆错误。看来是山穷水尽没有办法了。由于当时我已经感到很烦也很没希望,所以下面的错误提示我没有记录。我真的是感到有点后悔,不应该这么冒失,早知道装LFS这么麻烦,不如干点别的。我到外面转了转,感觉心情好点之后,再回到计算机前,仔细看看提示,发现有ld找不到-lc字样。学过编程的都知道-lc是一种简略写法,表示标准库/usr/lib下的libc.a文件,我到/usr/lib下一看,果然没有libc.a文件,只有一个libc.so文件,于是进入mandrake控制中心,以libc搜索没有安装的软件包,把所有找到的软件包(共有44M)全部安装。安装后,果然在/usr/lib下有了一个libc.a文件。再编译,还是一堆错误,不过内容变了。好象是提示rename1()没有定义之类的,看来刚才修改的函数名还得再改回去,真是让人啼笑皆非,改完之后,再编译,终于成功。看来这个问题实际上是缺少函数链接库造成的,编译器可能在什么地方需要间接调用这个函数库,却不能给出明确的提示,结果让人大伤脑筋。
发表于 2002-11-30 17:32:28 | 显示全部楼层
哇,这第一步好扎实啊,以后的问题都不是问题了,只要有兄弟你这样的精神!
发表于 2002-11-30 18:03:18 | 显示全部楼层
厉害厉害,尤其佩服百折不挠的精神。我要是改源码,改一次,还有毛病就算了想别的折了。

但是,我编译的也是这个205a,编译过很多编,好象只有一次有问题。我想可能兄弟的编译环境的问题。我不太懂编程了,但是象gcc32下有些原来可以编译的程序就编不了。bison的版本不一样,对语法的要求严格程度也不一样。

kj兄的系统是什么呢?
 楼主| 发表于 2002-11-30 18:16:53 | 显示全部楼层
我用的是mandrake9.0rc2测试版,是从网上下载的。gcc是3.2版的。
发表于 2002-11-30 18:20:46 | 显示全部楼层
我第一次装的时候用的也的mandrake,不过是8.1的,用的是gcc-3.2,还可以,有些包出了点问题,不过第六章就不用它了,也无所谓。开始我用gcc-2.9x,结果编译gcc-3.2通不过,就换了gcc-3.2来编译gcc-3.2(好啰索),就行了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表