开发一个跨平台的项目的时候,大部分时候都是在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. SQLSERVER系统视图 sql server系统表详细说明

    参考 https://www.cnblogs.com/luluping/archive/2012/11/05/2754639.html https://www.cnblogs.com/litubin/ ...

  2. DLL文件实现窗体的模板模式

    机房合作版中第一次使用了模板方法,实现了类似窗体的界面和代码的复用..窗体继承有两种方法,一种是通过继承选择器从已编译的程序集合里选择,另一种则是通过DLL文件的方式继承.个人觉得DLL还是比较方便的 ...

  3. JQuery Ajax 在asp.net中使用总结

    自从有了JQuery,Ajax的使用变的越来越方便了,但是使用中还是会或多或少的出现一些让人短时间内痛苦的问题.本文暂时总结一些在使用JQuery Ajax中应该注意的问题,如有不恰当或者不完善的地方 ...

  4. Unique Paths leetcode java

    题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). ...

  5. 【Spark】SparkStreaming-如何使用checkpoint

    SparkStreaming-如何使用checkpoint sparkstreaming checkpoint 默认_百度搜索 spark streaming中使用checkpoint - HarkL ...

  6. Redis2.2.2源码学习——Server&Client链接的建立以及相关Event

    Redis中Server和User建立链接(图中的client是服务器端用于描述与客户端的链接相关的信息) Redis Server&Client链接的建立时相关Event的建立(图中的cli ...

  7. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(一)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网。

    使用VMW安装四台CentOS-7-x86_64-DVD-1804.iso虚拟机: 计划配置三台centos虚拟机: master:192.168.0.120 slave1:192.168.0.121 ...

  8. c/c++ 变量作用域

    在程序的不同位置,可能会声明各种不同类型(这里指静态或非静态)的变量.然而,声明的位置不同.类型不同导致每个变量在程序中可以被使用的范围不同.我们把变量在程序中可以使用的有效范围称为变量的作用域. 任 ...

  9. Python操作记录

    1.写入中文出错,需要执行 reload(sys) sys.setdefaultencoding('utf8') 2.json.dump中文写入为\xxxx ensure_ascii=False

  10. MFC对话框:模态对话框及其弹出过程

    From: http://www.jizhuomi.com/school/c/160.html 加法计算器对话框程序大家照着做一遍后,相信对基于对话框的程序有些了解了,有个好的开始对于以后的学习大有裨 ...