分类: C/C++
2005-06-29 21:53:49
在这种情况下,您得自己处理‘Makefile’文件。
只有开头大写的几行需要看看,可能还要作适当修改,当然‘Makefile’文件中不会都是这样的行。
在这种情况下,您得自己处理‘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 了。
‘Imake’是老版本的‘configure’,直接运行命令:
xmkmf -a
将从‘Imakefile’产生一个‘Makefile’文件,这个命令在‘XFree86-devel’包中。然后照前面讲过的步骤继续。
‘GNUmakefile’和‘Makefile’是一样的,都可以用‘make’来处理。
如果您有‘Makefile.cvs’文件,可运行
make -f Makefile.cvs'
这将产生一个‘configure’文件。
首先,您在有源码的子目录中,看看有没有这样的文件。然后,找有没有可执行的文件:
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
出现这样的错误,至少有以下三种可能:
‘configure’没有找到含有该库的目录。
如果是这样,您得用‘configure’的参数‘--with-extra-libs=[DIR]’添加该库的目录。对于头文件则用‘--with-extra-includes=[DIR]’。
‘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
‘configure’脚本中的文字(typo)错误
仔细看一下‘config.log’中的出错信息,特别是库和头文件名的大小写错误。这种情况很少见(大概一年里能碰到一两回),但有这种可能,请相信我…… ;-)。
这取决于程序作者,缺少哪些库,‘configure’或‘make’才会出错中止。 所以成功的编译并不保证最后的程序有全部的功能。好好研究一下‘config.log’文件,看看到底是少了哪些库,然后安装后,再编译试试。
由于‘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
现在,刷新源码目录,再编译试试。
在大多数情况下,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’命令新建需要的符号链接。第一个参数是存在的文件名,第二个是您希望创建的符号链接名称。
新建时,您得小心了,因为这有可能破坏其他程序。如果可能,向开发员核实,因为作者对此最清楚。