stlpor的特殊用法
stlport的主页是http://www.stlport.org/,以下讨论都是针对版本5.1.3。
首先介绍一下关键的目录,假设解压后的目录为stlport-5.1.3。stlport-5.1.3目录下的stlport目录提供了头文件,应用程序必须要将该目录放到头文件包含目录的最前面。stlport-5.1.3目录下的build/lib目录提供了生成不同平台下stlport库的配置文件。比如,在stlport-5.1.3/build/lib目录下运行“make -f gcc.mak dbg-static”即用gcc来编译debug版本的静态库,编译结果为obj/gcc/so_g/libstlportg.a,文件名中的g表示debug版本。
最终,只需要提供整个stlport-5.1.3/stlport头文件目录和库文件即可。
其他使用方法略,随便网上找找都可以找到。只需要记得必须将”-I …./stlport/stlprot/”放在编译参数的最前面,尽量将”-L…./libstlport.a”放在链接参数的最后面(如果使用linux的静态库的话),下面主要介绍在linux下的一些特殊用法。
在linux下,可能会碰到不同系统中libstd++.so的不匹配问题,那么,我们就需要使用静态库。可是,有些时候,libstdc++.a无法满足要求。因此,我们选择使用stlport库和libsupc++.a来共同提供libstdc++.a的功能;某些时候,我们也可以对源代码作些调整,可以只使用stlport静态库(和libc.a),而不包括supc++库。
以下的描述都是基于当前目录为stlport-5.1.3进行的讨论。
一.编译器选择
在build/Makefiles/gmake/gcc.mak文件的开头增加以下设置,即可不使用系统默认编译器。
CC := 。。。
CXX := 。。。
LD := 。。。
AR := 。。。
二.编译选项修改
这里只是一般性的描述,具体描述将在下面结合具体需求进行,但不保证具体例子中编译选项修改的绝对准确,如果有问题,可以在下述文件中自行修改。
build/lib/gcc.mak
build/lib/Makefile.inc (这个文件控制需要编译哪些源文件)
build/Makefiles/gmake/gcc.mak
一般的,可以在上述文件中增加一些宏定义,用来控制下面的修改启用与否。
为了达到一些目的,可以在build/Makefiles/gmake/gcc.mak 文件中为CXXFLAGS增加-fno-exceptions -fno-rtti选项。以及-g或者-O2等等。
三.避免使用exit、abort函数
使用exit、abort等函数会导致系统直接退出,在某些情况下是不允许的。
3.1 修改stlport/stl/_alloc.h的第55行,将exit退出修改为printf输出。
#ifndef __THROW_BAD_ALLOC
# if !defined(_STLP_USE_EXCEPTIONS)
# ifndef _STLP_INTERNAL_CSTDIO
# include <stl/_cstdio.h>
# endif
# define __THROW_BAD_ALLOC printf("!!!!out of memory, exit in stlport library\n")
# else
# define __THROW_BAD_ALLOC throw _STLP_STD::bad_alloc()
# endif
#endif
3.2 修改stlport/stl/config/features.h文件第203行,将abort退出修改为printf输出
#ifndef _STLP_ABORT
# define _STLP_ABORT() printf("!!!!!!!!!abort in stlport library")
#endif
四.取消使用exception
在一些底层应用中,不支持使用exception
4.1 在stlport/stl/_exception.h文件中增加定义:
#define _STLP_NO_UNCAUGHT_EXCEPT_SUPPORT
4.2 在stlport/stl/config/features.h文件中增加定义:
#define _STLP_HAS_NO_EXCEPTIONS
#define _STLP_DONT_USE_EXCEPTIONS
#define _STLP_NO_EXCEPTION_SPEC
#define _STLP_NO_UNCAUGHT_EXCEPT_SUPPORT
4.3 修改stlport/stl/_stdexcept_base.h文件中修改第68行,移除继承的基类_STLP_EXCEPTION_BASE
class _STLP_CLASS_DECLSPEC __Named_exception {
否则,当编译不链接stdlibc++库时,会提示找不到std::exception库
五.移除pthread库
对单线程的应用,并不需要pthread库,有些时候,也需要移除pthread的影响。
5.1 在stlport/stl/config/host.h文件第11行附近启用定义:
#define _NOTHREADS
#define _STLP_NO_THREADS
5.2 在build/Makefiles/gmake/gcc.mak文件中修改编译参数是否有-pthread/-D_REENTRANT(这两个选项应该或者同时存在,或者同时不存在,记得是这样的吧)
六.移除local本地化和宽字符
6.1 修改build/lib/gcc.mak文件,将宏-D_STLP_REAL_LOCALE_IMPLEMENTED调整为-D_STLP_NO_LOCALE_SUPPORT
6.2 将src/c_locale_glibc/c_locale_glibc2.c文件中的locale相关的字符函数strcoll_l, wcscoll_l换成字符函数strcmp, wcscmp。
6.3 删除src/iostream.cpp文件第310行开始的被#ifndef _STLP_NO_WCHAR_T包围的代码:
ptr_wcin->exceptions(0);
ptr_wcout->exceptions(0);
ptr_wcerr->exceptions(0);
ptr_wclog->exceptions(0);
delete ptr_wcin->rdbuf(0);
delete ptr_wcout->rdbuf(0);
delete ptr_wcerr->rdbuf(0);
delete ptr_wclog->rdbuf(0);
_Destroy(ptr_wcin);
_Destroy(ptr_wcout);
_Destroy(ptr_wcerr);
_Destroy(ptr_wclog);
6.4 删除src/iostream.cpp文件第253行开始的被#ifndef _STLP_NO_WCHAR_T包围的代码:
wistream* ptr_wcin = new(&wcin) wistream(0);
wostream* ptr_wcout = new(&wcout) wostream(0);
wostream* ptr_wcerr = new(&wcerr) wostream(0);
wostream* ptr_wclog = new(&wclog) wostream(0);
wfilebuf* win = _Stl_create_wfilebuf(stdin, ios_base::in);
wfilebuf* wout = _Stl_create_wfilebuf(stdout, ios_base::out);
wfilebuf* werr = _Stl_create_wfilebuf(stderr, ios_base::out);
wfilebuf* wlog = _Stl_create_wfilebuf(stderr, ios_base::out);
ptr_wcin->init(win);
ptr_wcout->init(wout);
ptr_wcerr->init(werr);
ptr_wclog->init(wlog);
ptr_wcin->tie(ptr_wcout);
ptr_wcerr->setf(ios_base::unitbuf);
6.5 删除src/locale_impl.cpp文件第617行被#ifndef _STLP_NO_WCHAR_T包围的代码:
new collate<wchar_t>(1),
new ctype<wchar_t>(1),
# ifndef _STLP_NO_MBSTATE_T
new codecvt<wchar_t, char, mbstate_t>(1),
# else
0,
# endif
new moneypunct<wchar_t, true>(1),
new moneypunct<wchar_t, false>(1),
new numpunct<wchar_t>(1),
new messages<wchar_t>(new _STLP_PRIV _Messages()),
new money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
0,
new money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
0,
new num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
0,
new num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
0,
new time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
0,
new time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
0,
七.考虑fpic选项
在32bit和64bit下,可能会有不同的需求,因此,可以通过修改build/Makefiles/gmake/gcc.mak文件来控制编译选项。
八.部分模拟libsupc++
在某些特殊需要的情况下,可以不链接libstdc++库和libsupc++库。
8.1 在build/lib/Makefile.inc文件中增加编译../../src/supc++.cpp
8.2 在src目录下新建文件supc++.cpp,其内容如下:
#include <stdlib.h>
void* operator new(size_t size)
{
void* p = malloc(size);
return p;
}
void* operator new[](size_t size)
{
void* p = malloc(size);
return p;
}
void operator delete(void* p)
{
free(p);
}
void operator delete[](void* p)
{
free(p);
}
extern "C"
void __cxa_pure_virtual()
{
return;
}
九.移除typeid
如果使用了-fno-rtti编译选项,那将导致src/facets_byname.cpp文件编译错误,因为该文件中用到了typeid函数,恰巧的是,这是和locale相关的部分,因为我们不需要locale支持,所以,简单的删除typeid函数或者修改为一个printf以防万一即可。
十.其他函数
10.1 比如fstat、fcntl等,由于某些限制,无法获取这些函数的支持,应该是和文件读写有关,那么只能是假设应用程序不用stl库进行文件操作。
10.2 在文件src/num_put_float.cpp中增加定义,主要用来处理一些浮点数相关函数。
#define USE_SPRINTF_INSTEAD
10.3 mktime函数,直接删除,改以printf进行输出监视。
经过以上修改后,最后得到的静态库中将只依赖c库函数和一些math库函数,除此,不再依赖其他函数库,可以解决某些情况下的某些问题。