Tuesday, July 15, 2008

在cygwin下编译libid3tag程序

今天心血来潮,想玩一玩mp3的id3tag编程,就找到了libid3tag这个库。下载,解压,在cygwin下面运行
./configure
make all
make install
发现libid3tag.a, libid3tag.la两个文件被安装到了/usr/local/lib下面。尝试写了一个很简单的程序:

#include <id3tag.h>
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
struct id3_file * mp3file;
struct id3_tag * tag;
struct id3_frame * frame;
union id3_field * field;

mp3file = id3_file_open("1.mp3", ID3_FILE_MODE_READONLY);
if(mp3file == NULL){
printf("Error open mp3 file!\n");
exit(-1);
}

exit(id3_file_close(mp3file));
}

确在编译的过程中报错:
/cygdrive/c/Windows/TEMP/ccMRqE7f.o:test.c:(.text+0x3a): undefined reference to `_id3_file_open'
/cygdrive/c/Windows/TEMP/ccMRqE7f.o:test.c:(.text+0x66): undefined reference to `_id3_file_close'

前后尝试过一下几个命令,都一样出错:
gcc -lid3tag test.c -o test
gcc /usr/local/lib/libid3tag.a test.c -o test

不甘心,就又在vmware下的Ubuntu里面安装,编译一次,用第一个命令编译通过,当时就有些想不通了。当时已经发现Ubuntu上的安装比cygwin的安装多生成几个文件在/usr/local/lib下面,就是动态库.so文件,cygwin下面只有.a这种静态链接库。

尝试在cygwin下面重新编译libid3tag,还是一样的问题。就在几乎要放弃的时候,看到一个网页上的gcc命令行,忽然脑袋里面灵光一闪(好像之前也闪过一次),觉得是自己把libray和source文件顺序弄反了(因为之前有大概读过一本gcc入门的书)。抱着试一试的心情,打下 gcc test.c /usr/local/lib/libid3tag.a -o test 的命令,还是有错误,不过这次错误不同:
/usr/local/lib/libid3tag.a(util.o): In function `id3_util_compress':
/cygdrive/i/projects/id3tag/libid3tag-0.15.1b/util.c:106: undefined reference to `_compress2'
/usr/local/lib/libid3tag.a(util.o): In function `id3_util_decompress':
/cygdrive/i/projects/id3tag/libid3tag-0.15.1b/util.c:139: undefined reference to `_uncompress'

很好,至少不是id3tag的问题了,于是在命令行上加上了zlib
gcc test.c /usr/local/lib/libid3tag.a -lz -o test
这次没有任何报错,很顺利的通过了,oh yeah...

重新看回之前看过的gcc入门书,里面有一段关于link order的:

The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it. This includes libraries specified with the short-cut -l option

看来自己对于gcc的基本用法还是比较陌生啊,要加一把油。

No comments: