近日整理安装包,觉得根目录下那几个libxxx.dll真是有些碍眼,为啥人家osg的插件在plugins里,插件的依赖库却在外面,不合美感啊。
遂想把这些osg的这些插件依赖库都改成静态编译,直接整到插件里。
首先拿libtiff库下手,翻看了一下,之前编的时候直接动态库和静态库都编译出来了,心想这就好办了,重新指定一下osgDB_tiff的依赖库,再编一下,不就OK了,太简单了。
结果大出意料,一堆编译错误扑面而来:
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFClose,该符号在函数 "public: enum osgDB::ReaderWriter::WriteResult::WriteStatus __thiscall ReaderWriterTIFF::writeTIFStream(class std::basic_ostream<char,struct std::char_traits<char> > &,class osg::Image const &)const " (?writeTIFStream@ReaderWriterTIFF@@QBE?AW4WriteStatus@WriteResult@ReaderWriter@osgDB@@AAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABVImage@osg@@@Z) 中被引用
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFWriteScanline,该符号在函数 "public: enum osgDB::ReaderWriter::WriteResult::WriteStatus __thiscall ReaderWriterTIFF::writeTIFStream(class std::basic_ostream<char,struct std::char_traits<char> > &,class osg::Image const &)const " (?writeTIFStream@ReaderWriterTIFF@@QBE?AW4WriteStatus@WriteResult@ReaderWriter@osgDB@@AAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABVImage@osg@@@Z) 中被引用
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFSetField,该符号在函数 "public: enum osgDB::ReaderWriter::WriteResult::WriteStatus __thiscall ReaderWriterTIFF::writeTIFStream(class std::basic_ostream<char,struct std::char_traits<char> > &,class osg::Image const &)const " (?writeTIFStream@ReaderWriterTIFF@@QBE?AW4WriteStatus@WriteResult@ReaderWriter@osgDB@@AAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABVImage@osg@@@Z) 中被引用
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFClientOpen,该符号在函数 "public: enum osgDB::ReaderWriter::WriteResult::WriteStatus __thiscall ReaderWriterTIFF::writeTIFStream(class std::basic_ostream<char,struct std::char_traits<char> > &,class osg::Image const &)const " (?writeTIFStream@ReaderWriterTIFF@@QBE?AW4WriteStatus@WriteResult@ReaderWriter@osgDB@@AAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABVImage@osg@@@Z) 中被引用
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFReadScanline,该符号在函数 "unsigned char * __cdecl simage_tiff_load(class std::basic_istream<char,struct std::char_traits<char> > &,int &,int &,int &,unsigned short &)" (?simage_tiff_load@@YAPAEAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAH11AAG@Z) 中被引用
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFScanlineSize,该符号在函数 "unsigned char * __cdecl simage_tiff_load(class std::basic_istream<char,struct std::char_traits<char> > &,int &,int &,int &,unsigned short &)" (?simage_tiff_load@@YAPAEAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAH11AAG@Z) 中被引用
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFGetField,该符号在函数 "unsigned char * __cdecl simage_tiff_load(class std::basic_istream<char,struct std::char_traits<char> > &,int &,int &,int &,unsigned short &)" (?simage_tiff_load@@YAPAEAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAH11AAG@Z) 中被引用
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFSetWarningHandler,该符号在函数 "unsigned char * __cdecl simage_tiff_load(class std::basic_istream<char,struct std::char_traits<char> > &,int &,int &,int &,unsigned short &)" (?simage_tiff_load@@YAPAEAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAH11AAG@Z) 中被引用
1>ReaderWriterTIFF.obj : error LNK2019: 无法解析的外部符号 __imp__TIFFSetErrorHandler,该符号在函数 "unsigned char * __cdecl simage_tiff_load(class std::basic_istream<char,struct std::char_traits<char> > &,int &,int &,int &,unsigned short &)" (?simage_tiff_load@@YAPAEAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAH11AAG@Z) 中被引用
打开libtiff.lib搜了一翻,还真没有以__imp__开头的。
问了下同事,说可能是某个宏得改一下(这也太不具体了。。。什么宏啊)
还是放狗搜比较好,一翻搜索后,发现一篇有点干货。
根据这篇文章,如果是动态库的话,会用 __declspec(dllimport) 来作函数导出,而静态库的话,则不需要这句了。
这时再结合libtiffio.h里的定义:
#if (defined __WIN32__) || (defined _WIN32) # ifdef BUILD_LIBTIFF_DLL # define LIBTIFF_DLL_IMPEXP __DLL_EXPORT__ # elif defined(LIBTIFF_STATIC) # define LIBTIFF_DLL_IMPEXP # elif defined (USE_LIBTIFF_DLL) # define LIBTIFF_DLL_IMPEXP __DLL_IMPORT__ # elif defined (USE_LIBTIFF_STATIC) # define LIBTIFF_DLL_IMPEXP # else /* assume USE_LIBTIFF_DLL */ # define LIBTIFF_DLL_IMPEXP __DLL_IMPORT__ # endif #else /* __WIN32__ */ # define LIBTIFF_DLL_IMPEXP #endif
如果在windows下,预编译宏里啥都不写的话,最后会使用这句:
define LIBTIFF_DLL_IMPEXP __DLL_IMPORT__
再看看其他几个定义,就知道如果想用静态库的话,就得在vs的预编译里添加一句:
USE_LIBTIFF_STATIC
应该就没问题了。
果然,添加完后,再编译plugins tiff项目,一次OK。