排查错误:undefined reference to `libmsvcrt_a_iname'

在移植Cyrus sasl(cyrus-sasl-2.1.23)库时碰到如下问题(使用mingw编译):

fu000001.o:(.idata$2+0xc): undefined reference to `libmsvcrt_a_iname'
fu000004.o:(.idata$2+0xc): undefined reference to `libmsvcrt_a_iname'
fu000006.o:(.idata$2+0xc): undefined reference to `libmsvcrt_a_iname'
fu000008.o:(.idata$2+0xc): undefined reference to `libmsvcrt_a_iname'
nmth000000.o:(.idata$4+0x0): undefined reference to `_nm___iob'
collect2: ld returned 1 exit status
mingw32-make[2]: *** [debug\libsasl.dll] Error 1
mingw32-make[1]: *** [debug] Error 2
mingw32-make: *** [sub-lib-make_default-ordered] Error 2
The process "E:\QtSDK\mingw\bin\mingw32-make.exe" exited with code 2.

下面描述一下解决过程:

1)首先是上网搜索:看他人是怎么解决的。有数十个有关这个问题的帖子,绝大多数没有说是什么原因,不了了之。有人说是链接库的顺序问题,我调整了半天链接库顺序,均没有效果。另外添加了各种可能的库还是无效。

win32: {
#    LIBS += -lws2_32 -ladvapi32 -lmingw32
    LIBS += -lmsvcrt -ladvapi32 -lws2_32
}
2)看来只好做加减法找出问题代码位置了。由于这个函数库依赖性很强,无法通过去掉某个.c文件的方式来定位问题所在。于是只好找最可能出问题的文件依次去掉函数的实现代码,然后再尝试编译直到上述链接问题消失。在问题消失后再依次恢复去掉的代码,再次编译,从而定位问题所在。在若干次尝试后终于找到了问题所在:

        fprintf(stderr, "%s", prompt); (void) fflush(stderr);
        for (p=pbuf; (c = _getch())!=13 && c!=EOF;) {
                if (p < &pbuf[sizeof(pbuf)-1])
                        *p++ = (char) c;
        }
        *p = '\0';
        fprintf(stderr, "\n"); (void) fflush(stderr);

是因为符号 stderr的问题。查看其定义为:

#define stderr (&__iob_func()[2])
尽然在VS2005的stdio.h文件中,难怪要与msvcrt沾边。 具体到我这里的问题,没有再纠结stderr,临时用perror函数替代了fprintf函数及stderr的使用。即:

#ifdef WIN32
        perror(prompt);
#else
        fprintf(stderr, "%s", prompt); (void) fflush(stderr);
#endif
        for (p=pbuf; (c = _getch())!=13 && c!=EOF;) {
                if (p < &pbuf[sizeof(pbuf)-1])
                        *p++ = c;
        }
        *p = '\0';
#ifdef WIN32
        perror("\n");
#else
        fprintf(stderr, "\n"); (void) fflush(stderr);
#endif
此链接问题消失。

需要说明的是:这个库用VS编译没有问题(我没有使用该库自带的NTMakefile文件,而是在QtCreator下创建.pro用VS2005编译成功)。由于我的另一个项目用到了pthread,是用mingw编译的,因此这个库也需要mingw编译。

遗留问题:尚不明确mingw为何会使用VS的stdio.h文件,以及如何避免引用VS的头文件,有兴趣的朋友可以研究一下。若解决的话,不妨反馈一下。


你可能感兴趣的:(c,reference)