开发一个跨平台的项目的时候,大部分时候都是在VS下进行编码,所以也就使用了VS的解决方案来管理项目。

因为要跨平台,当时网上看scons这个工具不错,所以在linux下就使用了scons来作为编译脚本。

linux(gcc)下与windows(vs)下的对于链接这一步稍有不同。当目标文件是一个(共享)库的时候,VS会在链接的时候就去解析所有用到的符号,而gcc则不会,只有在生成最终可执行程序的时候才会去解析。

所以在VS下,一直都没有问题。linux下进行测试的时候也没有问题(因为不是所有的代码都被调用了)。

这几天在一次移植过程中出现了如下的问题

/a.out: symbol lookup error: ./uds_file_storage_module.so: undefined symbol: _ZN8unispace13us_ini_config9from_fileERKNS_10us_ustringEPS0_

错误很简单,就是us_ini_config::from_file这个函数没有找到,说明没有将其添加到动态导出符号表中。(uds_file_storage_module.so是运行时动态加载的,所以编译的时候没有提示错误)

VC中导出符号需要使用到dllexport,而gcc下则默认是不需要。所以这个问题很是疑惑。

考虑用的gcc版本比较高,是不是它将-fvisibility的参数默认设置为hidden呢?查看了gnu的wiki之后也没有发现这个。

https://gcc.gnu.org/wiki/Visibility

这里还是有收获的,看到一段好的跨平台代码。

#if defined _WIN32 || defined __CYGWIN__
#ifdef BUILDING_DLL
#ifdef __GNUC__
#define DLL_PUBLIC __attribute__ ((dllexport))
#else
#define DLL_PUBLIC __declspec(dllexport) // 注记:实际上gcc似乎也支持这种语法。
#endif
#else
#ifdef __GNUC__
#define DLL_PUBLIC __attribute__ ((dllimport))
#else
#define DLL_PUBLIC __declspec(dllimport) // 注记:实际上gcc似乎也支持这种语法。
#endif
#endif
#define DLL_LOCAL
#else
#if __GNUC__ >= 4
#define DLL_PUBLIC __attribute__ ((visibility ("default")))
#define DLL_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define DLL_PUBLIC
#define DLL_LOCAL
#endif
#endif extern "C" DLL_PUBLIC void function(int a);
class DLL_PUBLIC SomeClass
{
int c;
DLL_LOCAL void privateMethod(); // Only for use within this DSO
public:
Person(int _c) : c(_c) { }
static void foo(int a);
};

然后添加了__attribute__((visibility("default")))进行修饰,发现编译的结果没有改变(md5sun判断)。

然后又在链接的时候添加-rdynamic参数,将所有符号都添加到动态符号表,编译结果也没有变。

在仔细查看了SConstruct脚本之后,发现问题在于没有将对应的源文件添加到脚本中。也就是编译的时候完全就没有编译us_ini_config::from_file所在的源文件。

这样问题就很清晰明了了,修改脚本之后重新编译就可以了。


说到这里,就该反思一下了。

这个项目早期确实是直接写的Makefile来进行编译的,使用SOURCES = $(shell find $(SRC_DIR)$(PROJECT)/ -name "*.cpp")来自动发现cpp文件,这本来是很好的。对于贸然使用自己不熟悉的scons,又没有进行有效的学习,这是很不好的。

对于这个项目,还是直接使用qmake来做跨平台的编译脚本比较好。

由一次 symbol lookup error 引发的思考的更多相关文章

  1. mysql: symbol lookup error: /usr/local/lib/libreadline.so.6: undefined symbol: UP

    Error Symptom: when you run $mysql -u root -p command in the linux you get an error message ” mysql: ...

  2. centos perl: symbol lookup error: /usr/local/lib64/perl5/auto/DBD/mysql/mysql.so: undefined symbol: mysql_init

    之前在安装天兔数据库监控工具lepus的时候,运行时一直报perl: symbol lookup error: /usr/local/lib64/perl5/auto/DBD/mysql/mysql. ...

  3. fastDfs V5.02 升级到 V5.08版本后,启动报错:symbol lookup error: /usr/bin/fdfs_trackerd: undefined symbol: g_current_time

    /libfastcommon-1.0.36 # ./make.sh cc -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -g -O3 -c -o hash.o ...

  4. ldd "symbol lookup error"问题解决

    http://www.linuxquestions.org/questions/slackware-14/symbol-lookup-error-usr-lib-libgtk-x11-2-0-so-0 ...

  5. 写动态库时遇到了symbol lookup error问题

    之前写TLPI上的代码一直是手动进行错误处理,感觉代码冗余量很大,最后还是决定使用书上的tlph_hdr.h,顺便回顾下动态库的创建/使用. 参考很久之前的一篇博客 linux上静态库和动态库的编译和 ...

  6. symbol lookup error *** , undefined symbol 错误

    在重装samba过程后遇到一些问题,使用 gdb 时产生报错: gdb: symbol lookup error: gdb: undefined symbol: PyUnicodeUCS2_FromE ...

  7. gpg: symbol lookup error

    今天使用sudo apt-get 安装包的时候,出现gpg错误,如下: gpg: symbol lookup error: /usr/local/lib/libreadline.so.6: undef ...

  8. symbol lookup error

    今天编译代码时出现这样的错误提示: “./test: symbol lookup error: ./test: undefined symbol: ……” 问题原因是:test使用的动态库和makef ...

  9. symbol lookup error /usr/lib/x86_64-linux-gnu/libstdc++.so.6错误的解决办法

    当出现 $ apt-get: symbol lookup error: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: undefined symbol: _ZNS ...

随机推荐

  1. 解读SSD中的Default box(Prior Box)

    1:SSD更具体的框架如下: 2: Prior Box 缩进在SSD中引入了Prior Box,实际上与anchor非常类似,就是一些目标的预选框,后续通过softmax分类+bounding box ...

  2. 【ContestHunter】【弱省胡策】【Round7】

    Prufer序列+高精度+组合数学/DP+可持久化线段树 Magic 利用Prufer序列,我们考虑序列中每个点是第几个插进去的,再考虑环的连接方式,我们有$$ans=\sum_{K=3}^n N^{ ...

  3. 修改visual studio2010 的快捷键,使用ctrl+W 关闭当前文档

    废话不多说,打开visualstudio 的菜单 [工具]->[选项].定位到 环境->键盘. 找到光口.关闭文档窗口.把默认的ctrl+F4移除,因为这两个组合键按起来太麻烦,太累了.再 ...

  4. 样条之Akima光滑插值函数

    核心代码: ////////////////////////////////////////////////////////////////////// // Akima光滑插值 // t - 存放指 ...

  5. VS2010新建Web网站与新建Web应用程序的区别 (转)

    在Visual Studio 2010中,除了可以使用“创建Web应用程序”的方式来构建自己的Web项目之外,还可以通过创建“Web网站”的方式来构建Web项其中,Web网站的创建方法:打开Visua ...

  6. 魅族推送 简介 集成 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. nginx配置目录列表访问权限

    我们知道apache httpd默认情况下会显示访问目录的文件列表,但是nginx访问时如果目录下面没有默认首页,那么会返回403 Forbidden的错误,表示没有权限访问,比如根目录就是nginx ...

  8. ElasticSearch 5.X 搜索并用高亮显示

    public List<WOSearchModel> searchOrder(OrderSearchReqVO request) throws Exception{List<WOSe ...

  9. PDO 增删改查封装的类

    Selecting Data 你在mysql_*中是这样做的 <?php $result = mysql_query('SELECT * from table') or die(mysql_er ...

  10. Python编程工具pycharm的使用

    简介 俗话说工欲善其事必先利其器,所以对于程序员来说,使用python编程必须有一个强大的Python编程工具,这款工具就是pycharm. PyCharm是一种Python IDE,带有一整套可以帮 ...