前言:上次很興奮,因為在Ubuntu上交叉編譯了libevent的靜態庫,可是悲劇的是拿到windows上,用cygwin做連結的時候死活過不去,報event_init等一堆的未實現,可是靜態庫明明就在obj/local/armeabi目錄下,並且開啟靜態庫,也能找到對應的到處函數,為啥就是報找不到呢?反正我暫時還未搞懂,但是後來用cygwin編譯出來的版本,貌似靜態庫有點區別,因為NDK的編譯我還沒搞清楚,在Ubuntu上我是指明了platforms和對應的編譯器,不知道是否是不匹配造成的,不然NDK的目錄裡面也沒必要有那麼多gcc和ld的版本。由於才接觸非windows平台的程式編譯,總之就是糊裡糊塗的,但是至少後來還是找了個辦法在win7下使用cygwin編譯出了cocos2dx能用的android版本的libevent。
編譯前準備我把我這裡的編譯方式和方法盡量說得詳細點,至少我還未找到相關的文章,當然也可能是太簡單了,而我坑得比較厲害的緣故。編譯環境
| 作業系統 |
Win7 64bit |
| 輔助編譯環境 |
cygwin 1.7.14 |
| 編譯器 |
NDK r8e |
| libevent版本 |
2.0.21-stable(for Android) |
這些都要自己準備好(包括下載,安裝,對應的路徑匯出等等),去網上搜下即可,libevent的版本,後面會有,直接下載後面那個即可,先不要下載官方的版本。
libevent for Android 原始碼準備
這裡比較特殊的是用的是git上對應專門的for Android版本的libevent,這裡有:https://github.com/ventureresearch/libevent/archive/patches-2.0.zip
這裡需要注意,如果是在cygwin上,編譯會有問題,貌似是cygwin下執行NDK,不支援linux下的軟串連,而openssl裡面的inlcude目錄下的openssl目錄中的所有標頭檔都是軟串連。所以,如果要支援openssl,我這裡還沒轍(也許到linux下可行也不一定)。對應的libevent壓縮包解開後,放到cocos2dx目錄下,我這裡建立項目是通過tools中的python指令碼實現的,所以所有的項目都會在cocos2dx的project目錄下。然後編輯Android.mk檔案,把支援openssl的源檔案以及目錄路徑都刪掉(不要簡單用#注釋,因為會把後面的反斜線一起注釋的,這樣就導致剩下的大部分源檔案都被注釋了,這樣編譯出來的靜態庫會少很多函數)。檔案內容我這裡羅列一份:
##################################### Build libevent as separate libraryLOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_ARM_MODE:= armLOCAL_MODULE:= event_staticLOCAL_MODULE_TAGS:= optional# bufferevent_openssl.c LOCAL_SRC_FILES := \ buffer.c \ bufferevent.c \ bufferevent_filter.c \ bufferevent_pair.c \ bufferevent_ratelim.c \ bufferevent_sock.c \ epoll.c \ epoll_sub.c \ evdns.c \ event.c \ event_tagging.c \ evmap.c \ evrpc.c \ evthread.c \ evthread_pthread.c \ evutil.c \ evutil_rand.c \ http.c \ listener.c \ log.c \ poll.c \ select.c \ signal.c \ strlcpy.c# external/openssl/includeLOCAL_C_INCLUDES := \ $(LOCAL_PATH) \ $(LOCAL_PATH)/android \ $(LOCAL_PATH)/includeLOCAL_CFLAGS := -DHAVE_CONFIG_H -DANDROID -fvisibility=hiddeninclude $(BUILD_STATIC_LIBRARY)#include $(BUILD_SHARED_LIBRARY)
好了,這裡是告訴NDK如何編譯libevent,並且產生對應的靜態庫名稱為libevent_static.a。編譯到自己的項目以上都準備好以後,可以開啟自己的項目Android.mk,加入下面的語句:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \... $(LOCAL_PATH)/../../../../libevent \ $(LOCAL_PATH)/../../../../libevent/include \ $(LOCAL_PATH)/../../../../libevent/android...LOCAL_WHOLE_STATIC_LIBRARIES += event_static...$(call import-module,libevent)
中間的...就不要複製過去了。稍微解釋下:
- 因為使用libevent,所以要告訴編譯器對應的libevent的標頭檔在什麼地方,比如這裡的LOCAL_C_INCLUDES的設定,這裡增加了libevent、libevent/include、以及libevent/android三個放標頭檔的目錄,我的libevent目錄是直接在cocos2dx目錄下的,和project目錄同層級。
- LOCAL_WHOLE_STATIC_LIBRARIES這裡就是告訴編譯器,要連結那個靜態庫,也就是libevent_staitc.a。
- 最後的語句,表示告訴NDK,需要編譯外部的模組,找ibevent目錄下的Android.mk
好了,這樣就可以編譯出自己要的libevent_staitc.a靜態庫了。在Android上測試可以用。