Ubuntu升级后链接到库的问题

时间:2012-05-04 13:30:01

标签: gcc ubuntu linker

最近使用新的Ubuntu安装(11.04,现在是12.04)后,我的项目似乎无法正确链接。我尝试链接到LuxRender的API,这是一个开源渲染库。我的代码是用C ++编写的,用g ++编译。

我已经在这个问题上花了很多时间,遇到了一些解决类似症状问题的方法。但是,我还没有找到解决方案,所以我来这里寻求帮助。

示例代码testmain.cc:

#include <lux_api.h>

int main (int argc, char* argv[]) {
    lux_instance* lux = CreateLuxInstance("Test");
    DestroyLuxInstance(lux);

    return 0;
}

问题

$ g++ -c -o testmain.o testmain.cc -Wall -g -pedantic -I/home/taz/lux/lux-build/lux/cpp_api -I/home/taz/lux/lux-build/lux/core -I/home/taz/lux/lux-build/lux/core/queryable
$ g++ -o testmain testmain.o -llux
testmain.o: In function `main':
/home/taz/Documents/msc/test/testmain.cc:4: undefined reference to `CreateLuxInstance'
/home/taz/Documents/msc/test/testmain.cc:5: undefined reference to `DestroyLuxInstance'
collect2: ld returned 1 exit status

首先请注意,虽然自Ubuntu 11.10以来其他人都有链接问题,但链接顺序正确(-llux之后testmain.o),所以这不是问题。

其次,使用lux_api.h中的C样式命名(带extern "C")导出CreateLuxInstance和DestroyLuxInstance函数。我把头文件包含在这里,所以编译器应该知道它,对吧? (使用g++ -E检查预处理器输出。)函数确实出现在库中,以便链接器可以使用它们:

$ nm -s /usr/local/lib/liblux.so | grep LuxInstance
000000000008c440 t CreateLuxInstance
000000000008c4d0 t DestroyLuxInstance

第三,我使用维护者的cmake文件从源代码编译(并在升级,重新编译之后)这个库。但即使我从他们的网站上获取编译版本,我也会遇到同样的问题。在这两种情况下,库都与包含的标题匹配。

最后,我知道通过-Wl,--verbose传递正确的库文件来查看链接器实际使用的库文件。

我在这里缺少什么?

某些版本:

$ ld --version
GNU ld (GNU Binutils for Ubuntu) 2.22
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ uname -a
Linux linuxtaz 3.2.0-24-generic #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

$ lsb_release -irc
Distributor ID: Ubuntu
Release:    12.04
Codename:   precise

编辑:

在构建luxShared(与Lux api一起使用的共享库)时,问题最终出现在de LuxRender发行版中。为什么在Ubuntu升级之后出现这个问题对我来说仍然是一个谜,但对于其他正在努力解决这个问题的人来说,这是我的“解决方案”:

我想要构建的发行版是v1.0-RC1。在文件cpp_api/export_defs.h中,我添加了以下行:

#ifdef LUX_DLL
 #define CPP_API __attribute__ ((visibility ("default")))
#endif

编译器抱怨CPP_API被双重声明但我忽略了。现在,该库使用公开的API函数构建:

$ nm ./liblux.so | grep LuxInstance
000000000008c6c0 T CreateLuxInstance
000000000008c750 T DestroyLuxInstance

1 个答案:

答案 0 :(得分:2)

  

函数确实出现在库中,因此它们应该可供链接器使用:

$ nm -s /usr/local/lib/liblux.so | grep LuxInstance
000000000008c440 t CreateLuxInstance
000000000008c4d0 t DestroyLuxInstance

不,他们t符号是 local (不能在定义它们的库之外使用)。您需要T(全局)符号。

如果这些符号由lux_api.h(它们看起来是)导出,则表示库尚未正确构建。打开发布的错误。