Android NDK:.o 和.c 文件的多重定义
Android NDK: Multiple definition of .o and .c files
我想在 Android Studio 的应用程序项目中使用 java 和本机代码实现一个库。每次更改 c++ 代码时,我都必须重新编译 c++ 文件,以便更改在我的应用程序中生效。不幸的是 ndk-build 命令没有完全编译...
每次我 运行 这个命令,它编译所有的 c++ 文件,当它试图创建 .so-files 我得到很多看起来像这样的错误(只是与其他人 类).我所做的更改非常简单,没有添加任何 c++ include headers 等
/Users/jenny/appproject/libraryWithNativeCode/src/main/obj/local/armeabi/objs/libraryWithNativeCode-mobile-example-app/src/WorldPins/WorldPinMessage.o: In function `_STLP_alloc_proxy':
/Users/jenny/NDK/android-ndk-r10e/sources/cxx-stl/stlport/stlport/stl/_string.c:647: multiple definition of `ExampleApp::WorldPins::WorldPinMessage::FocussedModel() const'
/Users/jenny/appproject/libraryWithNativeCode/src/main/obj/local/armeabi/objs/libraryWithNativeCode-mobile-example-app/src/WorldPins/WorldPinMessage.o:/Users/jenny/NDK/android-ndk-r10e/sources/cxx-stl/stlport/stlport/stl/_string.c:647: first defined here
我的 Android.mk 和 Application.mk 如下所示
Android.mk
LOCAL_PATH := $(call my-dir)
$(info TARGET_ARCH_ABI is $(TARGET_ARCH_ABI))
$(info LOCAL_PATH is $(LOCAL_PATH))
PREBUILT_LIBS := $(LOCAL_PATH)/../libs/libraryWithNativeCode/prebuilt/android-$(TARGET_ARCH_ABI)
include $(CLEAR_VARS)
LOCAL_MODULE := libraryWithNativeCode-sdk-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libraryWithNativeCode-sdk.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := png-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libpng.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../libs/libraryWithNativeCode/png
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := curl-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libcurl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../libs/libraryWithNativeCode/curl/android-$(TARGET_ARCH_ABI)
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libssl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := crypto-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libcrypto.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := http-parser-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libhttp-parser.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../libs/libraryWithNativeCode/http-parser
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := jpeg-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libjpeg.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := turbojpeg-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libturbojpeg.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../libs/libraryWithNativeCode/jpeg-turbo
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libraryWithNativeCode-mobile-example-app
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2 -lz -lm
LOCAL_LDLIBS += -fuse-ld=bfd
LOCAL_STATIC_LIBRARIES := libraryWithNativeCode-sdk-lib png-lib curl-lib ssl-lib crypto-lib http-parser-lib jpeg-lib turbojpeg-lib android_native_app_glue ndk_helper
LOCAL_CFLAGS += -Wall -Wno-unknown-pragmas -Wno-sign-compare -Wno-format-security -Wno-reorder
#LOCAL_CFLAGS += -Werror
ifdef COMPILE_CPP_11
$(info Configured for C++11)
LOCAL_CPPFLAGS += -DCOMPILE_CPP_11=1 -std=c++11
else
$(info Configured for C++0x)
endif
os_name:=$(shell uname -s)
get_android_cpp_files_cmd := find $(LOCAL_PATH) -type f -iname "*.cpp"
get_android_includes_cmd := find $(LOCAL_PATH) -type d
get_shared_cpp_files_cmd := find $(LOCAL_PATH)/src -type f -iname "*.cpp"
get_shared_includes_cmd := find $(LOCAL_PATH)/src -type d
get_platform_includes_cmd := find $(LOCAL_PATH)/../libs/libraryWithNativeCode/platform -type d ! -path "*/OSX/*" ! -path "*/iOS/*"
ifeq ($(os_name),Darwin)
cppfiles := ${shell ${get_android_cpp_files_cmd}}
cppfiles += ${shell ${get_shared_cpp_files_cmd}}
includes := ${shell ${get_android_includes_cmd}}
includes += ${shell ${get_shared_includes_cmd}}
includes += ${shell ${get_platform_includes_cmd}}
else
# assume windows if not specified for now (due to no uname)
cppfiles := ${shell sh -c '${get_android_cpp_files_cmd}'}
cppfiles += ${shell sh -c '${get_shared_cpp_files_cmd}'}
includes := ${shell sh -c '${get_android_includes_cmd}'}
includes += ${shell sh -c '${get_shared_includes_cmd}'}
includes += ${shell sh -c '${get_platform_includes_cmd}'}
endif
LOCAL_SRC_FILES := $(cppfiles:$(LOCAL_PATH)/%=%)
LOCAL_C_INCLUDES := $(includes)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libs/libraryWithNativeCode/rapidjson
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libs/libraryWithNativeCode/rapidjson/internal
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
$(call import-module,android/ndk_helper)
Application.mk
APP_PLATFORM := android-12
APP_STL := stlport_shared
APP_ABI := armeabi,armeabi-v7a,arm64-v8a
有人知道如何解决这个问题吗?
我认为你的问题的根本原因是你多次包含相同的文件进行编译,因为 get_android_cpp_files_cmd (find $(LOCAL_PATH) -type f -iname "*.cpp"
) 已经在返回文件,这些文件将由 get_shared_cpp_files_cmd (find $(LOCAL_PATH)/src -type f -iname "*.cpp"
) 因为 find
是递归的。
此外,这与您的问题无关,但我想知道您为什么要针对 armeabi、armeabi-v7a、arm64-v8a 和目标 android-12+ 进行编译? honeycomb_mr1 是一个相当机密的版本,为什么不直接针对 kitkat+ 而将 x86 arch 包括在您的列表中?
如果你仍然遇到问题,即使在 ph0b 的解决方案之后,我也遇到了同样的情况。修复它的一种简单方法是在 Android Studio 中清理项目(Build -> Clean Project)。
更详细的解决方案,看我的回答here。
希望对您有所帮助!
我想在 Android Studio 的应用程序项目中使用 java 和本机代码实现一个库。每次更改 c++ 代码时,我都必须重新编译 c++ 文件,以便更改在我的应用程序中生效。不幸的是 ndk-build 命令没有完全编译...
每次我 运行 这个命令,它编译所有的 c++ 文件,当它试图创建 .so-files 我得到很多看起来像这样的错误(只是与其他人 类).我所做的更改非常简单,没有添加任何 c++ include headers 等
/Users/jenny/appproject/libraryWithNativeCode/src/main/obj/local/armeabi/objs/libraryWithNativeCode-mobile-example-app/src/WorldPins/WorldPinMessage.o: In function `_STLP_alloc_proxy':
/Users/jenny/NDK/android-ndk-r10e/sources/cxx-stl/stlport/stlport/stl/_string.c:647: multiple definition of `ExampleApp::WorldPins::WorldPinMessage::FocussedModel() const'
/Users/jenny/appproject/libraryWithNativeCode/src/main/obj/local/armeabi/objs/libraryWithNativeCode-mobile-example-app/src/WorldPins/WorldPinMessage.o:/Users/jenny/NDK/android-ndk-r10e/sources/cxx-stl/stlport/stlport/stl/_string.c:647: first defined here
我的 Android.mk 和 Application.mk 如下所示
Android.mk
LOCAL_PATH := $(call my-dir)
$(info TARGET_ARCH_ABI is $(TARGET_ARCH_ABI))
$(info LOCAL_PATH is $(LOCAL_PATH))
PREBUILT_LIBS := $(LOCAL_PATH)/../libs/libraryWithNativeCode/prebuilt/android-$(TARGET_ARCH_ABI)
include $(CLEAR_VARS)
LOCAL_MODULE := libraryWithNativeCode-sdk-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libraryWithNativeCode-sdk.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := png-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libpng.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../libs/libraryWithNativeCode/png
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := curl-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libcurl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../libs/libraryWithNativeCode/curl/android-$(TARGET_ARCH_ABI)
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libssl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := crypto-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libcrypto.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := http-parser-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libhttp-parser.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../libs/libraryWithNativeCode/http-parser
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := jpeg-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libjpeg.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := turbojpeg-lib
LOCAL_SRC_FILES := $(PREBUILT_LIBS)/libturbojpeg.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../libs/libraryWithNativeCode/jpeg-turbo
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libraryWithNativeCode-mobile-example-app
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2 -lz -lm
LOCAL_LDLIBS += -fuse-ld=bfd
LOCAL_STATIC_LIBRARIES := libraryWithNativeCode-sdk-lib png-lib curl-lib ssl-lib crypto-lib http-parser-lib jpeg-lib turbojpeg-lib android_native_app_glue ndk_helper
LOCAL_CFLAGS += -Wall -Wno-unknown-pragmas -Wno-sign-compare -Wno-format-security -Wno-reorder
#LOCAL_CFLAGS += -Werror
ifdef COMPILE_CPP_11
$(info Configured for C++11)
LOCAL_CPPFLAGS += -DCOMPILE_CPP_11=1 -std=c++11
else
$(info Configured for C++0x)
endif
os_name:=$(shell uname -s)
get_android_cpp_files_cmd := find $(LOCAL_PATH) -type f -iname "*.cpp"
get_android_includes_cmd := find $(LOCAL_PATH) -type d
get_shared_cpp_files_cmd := find $(LOCAL_PATH)/src -type f -iname "*.cpp"
get_shared_includes_cmd := find $(LOCAL_PATH)/src -type d
get_platform_includes_cmd := find $(LOCAL_PATH)/../libs/libraryWithNativeCode/platform -type d ! -path "*/OSX/*" ! -path "*/iOS/*"
ifeq ($(os_name),Darwin)
cppfiles := ${shell ${get_android_cpp_files_cmd}}
cppfiles += ${shell ${get_shared_cpp_files_cmd}}
includes := ${shell ${get_android_includes_cmd}}
includes += ${shell ${get_shared_includes_cmd}}
includes += ${shell ${get_platform_includes_cmd}}
else
# assume windows if not specified for now (due to no uname)
cppfiles := ${shell sh -c '${get_android_cpp_files_cmd}'}
cppfiles += ${shell sh -c '${get_shared_cpp_files_cmd}'}
includes := ${shell sh -c '${get_android_includes_cmd}'}
includes += ${shell sh -c '${get_shared_includes_cmd}'}
includes += ${shell sh -c '${get_platform_includes_cmd}'}
endif
LOCAL_SRC_FILES := $(cppfiles:$(LOCAL_PATH)/%=%)
LOCAL_C_INCLUDES := $(includes)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libs/libraryWithNativeCode/rapidjson
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libs/libraryWithNativeCode/rapidjson/internal
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
$(call import-module,android/ndk_helper)
Application.mk
APP_PLATFORM := android-12
APP_STL := stlport_shared
APP_ABI := armeabi,armeabi-v7a,arm64-v8a
有人知道如何解决这个问题吗?
我认为你的问题的根本原因是你多次包含相同的文件进行编译,因为 get_android_cpp_files_cmd (find $(LOCAL_PATH) -type f -iname "*.cpp"
) 已经在返回文件,这些文件将由 get_shared_cpp_files_cmd (find $(LOCAL_PATH)/src -type f -iname "*.cpp"
) 因为 find
是递归的。
此外,这与您的问题无关,但我想知道您为什么要针对 armeabi、armeabi-v7a、arm64-v8a 和目标 android-12+ 进行编译? honeycomb_mr1 是一个相当机密的版本,为什么不直接针对 kitkat+ 而将 x86 arch 包括在您的列表中?
如果你仍然遇到问题,即使在 ph0b 的解决方案之后,我也遇到了同样的情况。修复它的一种简单方法是在 Android Studio 中清理项目(Build -> Clean Project)。
更详细的解决方案,看我的回答here。
希望对您有所帮助!