最近使用新的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
答案 0 :(得分:2)
函数确实出现在库中,因此它们应该可供链接器使用:
$ nm -s /usr/local/lib/liblux.so | grep LuxInstance
000000000008c440 t CreateLuxInstance
000000000008c4d0 t DestroyLuxInstance
不,他们不。 t
符号是 local (不能在定义它们的库之外使用)。您需要T
(全局)符号。
如果这些符号由lux_api.h
(它们看起来是)导出,则表示库尚未正确构建。打开发布的错误。