编译源码-FAQ

源代码目录没有‘configure’文件,怎么办?
源代码目录中有‘Imakefile’、‘GNUmakefile’或‘Makefile.cvs’,但没有正常的‘ Makefile’,该怎么办?
我已经安装了缺少的库,但‘configure’或‘make’依然说找不到,怎么会这样?

原文出自:http://blog.chinaunix.net/u/2389/showart_33295.html

 

缺少 Build 文件或该文件异常

1,源代码目录没有‘configure’文件,怎么办?

在这种情况下,您得自己处理‘Makefile’文件。
只有开头大写的几行需要看看,可能还要作适当修改,当然‘Makefile’文件中不会都是这样的行。

  • CC = compiler 告诉‘make’用哪种编译器。在大多数情况下,GCC都能胜任,C++ 程序则要用 G++。
  • INCDIR = -I/path/dir1 -I/path/dir2 etc 将告诉‘make’到哪个目录去找头文件,请核实一下,看看您的系统是否能够满足。
  • LIBDIR = -L/path/dir1 -L/path/dir2 etc 告诉‘make’到哪个目录下找库文件,这也需要核实。
  • LIBS = -llib1 -llib2 -llib3 etc告诉‘make’需要哪些库。请记住:‘-llib’是‘liblib.so’的缩写。用 locate liblib.so 可以确认这个需要的库是否已安装。有时,这个变量用 LFLAGS 来表示。

现在可以运行 make 了。

2,源代码目录中有‘Imakefile’、‘GNUmakefile’或‘Makefile.cvs’,但没有正常的‘ Makefile’。

‘Imake’是老版本的‘configure’,直接运行命令:

xmkmf -a

将从‘Imakefile’产生一个‘Makefile’文件,这个命令在‘XFree86-devel’包中。然后照前面讲过的步骤继续。

‘GNUmakefile’和‘Makefile’是一样的,都可以用‘make’来处理。

如果您有‘Makefile.cvs’文件,可运行

make -f Makefile.cvs'

这将产生一个‘configure’文件。

3,源码目录下没有任何 build 文件。

首先,您在有源码的子目录中,看看有没有这样的文件。然后,找有没有可执行的文件:

find . -type f -perm -700

这个命令将列出所有当前目录及其子目录中的可执行文件。

如果什么也没找到,那看来您得直接用编译器编译源码文件了。很有可能那儿只有一个 *.c 文件,用:

gcc -o new_name file.c

‘-o new_name’定义的是生成的二进制文件名。如果目录中有多个 *.c(或*.C、*.cc、*.cxx)文件,应当省略‘-o’参数。这样,结果会是一个标准名称:‘a.out’,您可能要将其改为其他名称。

如果需要增加其他 include、library 或 library 的目录,您得直接在‘gcc’后面添加命令行参数,比如

gcc -o new_name file.c -L/path/dir -llib -I/path/dir

Build File 问题

1,‘configure’抱怨缺少库/头文件,但实际这些文件已经安装了。

出现这样的错误,至少有以下三种可能:

    1. ‘configure’没有找到含有该库的目录。
      如果是这样,您得用‘configure’的参数‘--with-extra-libs=[DIR]’添加该库的目录。对于头文件则用‘--with-extra-includes=[DIR]’。

    2. ‘configure’找到的是库的另外一个版本。
      现在,一个显著得例子就是用到 Qt2 来编译的软件。由于 Qt2 的次级版本号(minor version)旧了些(如最好用 2.2.2 而不是已安装的 2.2.1),‘configure’会报错。这样的话,您要升级一下。
      另一种常见的问题是 Qt1 和 Qt2(Qt3……)都安装了,但默认时,‘configure’找的是‘/usr/lib/qt’目录,而在 Mandrake Linux 中,这是 Qt1 的安装目录,Qt2 是在‘/usr/lib/qt2’,Qt3 在‘/usr/lib/qt3’。如果是这样,您得给‘congfigure’添加参数,如:
      ./configure --with-qt-dir=/usr/lib/qt2

    3. ‘configure’脚本中的文字(typo)错误
      仔细看一下‘config.log’中的出错信息,特别是库和头文件名的大小写错误。这种情况很少见(大概一年里能碰到一两回),但有这种可能,请相信我…… ;-)。

2,为何自编译的程序好象少了些应该有的功能?

这取决于程序作者,缺少哪些库,‘configure’或‘make’才会出错中止。 所以成功的编译并不保证最后的程序有全部的功能。好好研究一下‘config.log’文件,看看到底是少了哪些库,然后安装后,再编译试试。

Building 问题

1,我已经安装了缺少的库,但‘configure’或‘make’依然说找不到,怎么会这样?

由于‘configure’和‘make’的结果被缓存了,要用

make distclean

刷新源码目录。这样做后,就能保证再编译时,会重新检查系统。
如果‘Makefile’没有提供‘distclean’目标,那可以用

make clean && rm config.cache

另一个这类问题的原因是,这个已安装库的目录并没有在‘/etc/ld.so.conf’文件中列出。这个文件搜集的是标准库位置(如‘/usr/lib’、‘/lib’)以外的目录,Linux Loader/Linker ‘ld’在这些地方寻找相应的库。
比如,新安装的库放在‘/usr/local/lib’,但这个目录不在‘/etc/ld.so.conf’中,因此这个库在系统中就不可用。
要修改的话,只要将目录添加进‘/etc/ld.so.conf’,然后用‘root’帐号运行:

ldconfig

现在,刷新源码目录,再编译试试。

2,需要的库都安装了,但如何消除库的版本冲突?

在大多数情况下,build 过程不会寻找指定次级版本号(a specfic minor version)的库,真正需要的是‘/usr/lib’目录下,合适的符号链接(symlink)
下面列出‘/usr/lib’中的‘libungif.so’作为例子(有删改)

lrwxrwxrwx /usr/lib/libungif.so -> libungif.so.4.1.0*
lrwxrwxrwx /usr/lib/libungif.so.3 -> libungif.so.3.1.0*
-rwxr-xr-x /usr/lib/libungif.so.3.1.0*
lrwxrwxrwx /usr/lib/libungif.so.4 -> libungif.so.4.1.0*
-rwxr-xr-x /usr/lib/libungif.so.4.1.0*

这里安装了两个版本的库:libungif.so.4.1.0 和 libungif.so.3.1.0(以 * 标识)。另外,还有三个符号链接(entries以 ‘l’开头):libungif.so、libungif.so.3 及 libungif.so.4。

符号链接不是真正的文件,而是指向其他文件的指针(pointer)
build 进程将在‘/usr/lib’中找到‘libungif.so.3’,然后由符号链接指向实际安装的次级版本的库,在这里是 3.1.0。

现在我们假定开发员没有明确(有时会意外发生),所以 build 进程只会找‘libungif.so’。而在这个例子中,指向的是‘libungif.so.4.1.0’——库的另一主版本(major version)。但不同主版本间一般是无法相容的,所以,如果可执行文件依赖的是主版本为 3 的库,但 build 进程找到的主版本是 4,‘make’或‘configure’将出错中止,而且抱怨说‘missing library’(缺少库)或‘undefined reference’(未知的引用)
对于第一个问题,简单的办法是为 build 进程重置符号链接:

ln -sf /usr/lib/libungif.so.3.1.0 /usr/lib/libungif.so

如果您碰到了第二个问题,可以用‘ln’命令新建需要的符号链接。第一个参数是存在的文件名,第二个是您希望创建的符号链接名称。

新建时,您得小心了,因为这有可能破坏其他程序。如果可能,向开发员核实,因为作者对此最清楚。

Monthly Archives

Pages

Powered by Movable Type 7.7.2

About this Entry

This page contains a single entry by Cnangel published on November 25, 2007 10:09 AM.

今天收到了google的T-Shirt was the previous entry in this blog.

xcb_xlib.c:50: xcb_xlib_unlock: Assertion `c->xlib.lock failed.问题的彻底解决 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.