在網路上有很多人使用Android NDK compile ffmpeg,目前遇到最多問題都是在最後要link libffmpeg.so。而一般大家都是遇到檔案大小只有1599bytes,即差不多1.6k。若使用ndk-build -j8 V=1,就可以看到在最後link的時候其實是有試圖將所有需要的static library link在一起,但在NDK裡,以build/toolchains/arm-eabi-4.4.0/setup.mk為例:
define cmd-build-shared-library
$(TARGET_CC) \
-nostdlib -Wl,-soname,$(notdir $@) \
-Wl,-shared,-Bsymbolic \
$(PRIVATE_OBJECTS) \
-Wl,--whole-archive \
$(PRIVATE_WHOLE_STATIC_LIBRARIES) \
-Wl,--no-whole-archive \
$(PRIVATE_STATIC_LIBRARIES) \
$(TARGET_LIBGCC) \
$(PRIVATE_SHARED_LIBRARIES) \
$(PRIVATE_LDFLAGS) \
$(PRIVATE_LDLIBS) \
-o $@
endef
從上面的setup.mk可以看到,其實有加入link的參數--whole-archive,但檢查build/core/build-binary.mk,裡面卻沒有定義PRIVATE_WHOLE_STATIC_LIBRARIES這個變數出來,而只有定義PRIVATE_STATIC_LIBRARIES,也因此在Android.mk裡,若將需要的static libraries都寫到LOCAL_STATIC_LIBRARIES時,最後都是會放到-Wl,--no-whole-archive $(PRIVATE_STATIC_LIBRARIES)裡面。也造成了沒有使用到的static library,並不會被輸出到libffmpeg.so裡。但看build/core/clear-vars.mk裡面其實是有定義LOCAL_STATIC_WHOLE_LIBRARIES,只是目前NDK r4b版本內build-binary.mk並沒有定義出來。為了解決這個問題:
1、先加入下面藍色的部份到NDK裡的build/core/build-binary.mk:
LOCAL_STATIC_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_LIBRARIES))
LOCAL_STATIC_WHOLE_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_WHOLE_LIBRARIES))
...
static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))
static_whole_libraries := $(call map,static-library-path,$(LOCAL_STATIC_WHOLE_LIBRARIES))
...
$(call module-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_LIBRARIES))
$(call module-add-static-depends,$(LOCAL_MODULE),$(LOCAL_STATIC_WHOLE_LIBRARIES))
...
$(LOCAL_BUILT_MODULE): $(static_libraries) $(static_whole_libraries) $(shared_libraries)
...
$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)
$(LOCAL_BUILT_MODULE): PRIVATE_WHOLE_STATIC_LIBRARIES := $(static_whole_libraries)
2、接著再將最外層ffmpeg/Android.mk裡面的LOCAL_STATIC_LIBRARIES改成LOCAL_STATIC_WHOLE_LIBRARIES
接著就是去build library,這樣就大功告成,可以順利build出完整的libffmpeg.so了。
PS. 2010/12/7 Android 2.3版同步發佈的NDK r5有加了LOCAL_WHOLE_STATIC_LIBRARIES,但加入了似乎還是不能使用。