由於android系統目前沒有將boost加入,這裡面使用了大量的STL及C++的一些語言特性,導致編譯出現令人非常頭痛的問題。
1、出現類似的異常函數錯誤
boost/exception/detail/exception_ptr.hpp:382: error: expected ';' before 'catch'
boost/exception/detail/exception_ptr.hpp:387: error: expected primary-expression before 'catch
boost/date_time/constrained_value.hpp:110: error: invalid initialization of reference of type 'const std::exception&' from expression of type 'boost::CV::simple_exception_policy<short unsigned int, 1u, 366u, boost::gregorian::bad_day_of_year>::exception_wrapper'
boost/throw_exception.hpp:48: error: in passing argument 1 of 'void boost::throw_exception(const std::exception&)'
解決方案:
此問題的出現是編譯器的異常異常捕獲被禁用了,需要在Android.mk文件中開啟。
在Android.mk文件中添加:LOCAL_CPPFLAGS += -fexceptions就可以了。
或者在Application.mk文件中添加APP_CPPFLAGS += -fexceptions也是可以的(eclipse下編譯)
並且android平台提供了一個最小化的C++運行庫(/system/lib/libstdc++)以及與之對應的頭文件。
原因:
只有異常安全的代碼才應該用-fexceptions編譯吧(這在編譯C++的時候是默認選項)。
絕大部分C代碼都不是異常安全的,如果沒加-fexceptions,異常經過的時候程序會直接退出,加了-fexceptions以後,萬一它調用的某個函數拋出了異常,
也會直接經過這段代碼,弄不好會出現內存洩漏之類的問題而不報錯吧。
所以對於try{}catch{}的關鍵字使用時需要加上 -fexceptions
-frtti:
打開rtti(runtime type identification)?這樣編譯器會為每個有虛函數的類添加一些信息以支持rtti特性,例如dynamic_cast typeid之類.
可以使用-fno-rtti來關閉這個特性節約空間
2、STL模塊函數找不到,鏈接失敗
stdc++/include/bits/stl_list.h:466: error: undefined reference to '__cxa_end_catch
stdc++/include/bits/stl_list.h:469: error: undefined reference to '__cxa_rethrow'
nal_baseD1Ev+0x0): error: undefined reference to '__gxx_personality_v0'
這些函數在 libsupc++.a庫中,加上即可
ist.h:1424: error: undefined reference to 'std::_List_node_base::unhook()'
stdc++/include/bits/list.tcc:101: error: undefined reference to 'std::_List_node_base::hook(std::_List_node_base*)
這些函數在 libstdc++.a庫中,加上即可
在android4.2系統中如此使用:
prebuilt_stdcxx_PATH := prebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++
LOCAL_C_INCLUDES := \
$(prebuilt_stdcxx_PATH)/include \
$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI)/include/ \
LOCAL_CPPFLAGS += -fexceptions -frtti
LOCAL_LDFLAGS += -L$(prebuilt_stdcxx_PATH)/libs/$(TARGET_CPU_ABI) -lgnustl_static -lsupc++
對於頭文件的引用及庫加上,基本上可以完全解決STL庫的函數
對於stl庫,其頭文件及庫在android4.1版本及以上才將所有函數實現完全,所有如果還碰鏈接某個函數失敗的話,那麼可以下載一個android4.1或4.2版本,將android-4.2_r1\prebuilts\ndk\current\sources下面的的代碼打包放到prebuilt\ndk下面,在android.mk中對於prebuilt_stdcxx_PATH進行重定義即可。
3、預編譯靜態庫:
build/core/base_rules.mk:81: * Each module must use a LOCAL_MODULE_TAGS in its
build/core/base_rules.mk:82: * Android.mk. Possible tags declared by a module:
build/core/base_rules.mk:83: *
build/core/base_rules.mk:84: * optional, debug, eng, tests, samples
修改build\core下的文件definitions.mk
define include-prebuilt
include $$(CLEAR_VARS)
LOCAL_SRC_FILES := $(1)
LOCAL_BUILT_MODULE_STEM := $(1)
LOCAL_MODULE_SUFFIX := $$(suffix $(1))
LOCAL_MODULE := $$(basename $(1))
LOCAL_MODULE_CLASS := $(2)
LOCAL_MODULE_TAGS := optional // 加上這句話即可
include $$(BUILD_PREBUILT)
endef
預編譯靜態庫指令:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) www.2cto.com
$(call add-prebuilt-files, STATIC_LIBRARIES, libboost_filesystem.a)
$(call add-prebuilt-files, STATIC_LIBRARIES, libboost_system.a)
$(call add-prebuilt-files, STATIC_LIBRARIES, libboost_thread.a)