使用ndk编译protobuf成so

927 阅读1分钟

最近需要在安卓jni里集成protobuf,网上找了一圈没有现成的so,只能自已下源码编译。

源码 github

开始

# 下载源码
$ git clone https://github.com/protocolbuffers/protobuf.git

# 切成自已需要的版本
$ git checkout v3.5.1

# 新建文件夹
$ mkdir jni && cd jni

然后把src里面的所有文件复制到jni目录

在jni目录下新建Application.mk文件,内容如下:

APP_ABI := all
APP_STL := c++_static

在jni目录下新建Android.mk文件,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_CPPFLAGS += -fexceptions
LOCAL_CPPFLAGS += -frtti
LOCAL_CPPFLAGS += -lstdc++

LOCAL_MODULE    := libproto
LOCAL_SRC_FILES :=    google/protobuf/stubs/atomicops_internals_x86_gcc.cc         \
                      google/protobuf/stubs/atomicops_internals_x86_msvc.cc        \
                      google/protobuf/stubs/bytestream.cc                          \
                      google/protobuf/stubs/bytestream.h                           \
                      google/protobuf/stubs/common.cc                              \
                      google/protobuf/stubs/hash.h                                 \
                      google/protobuf/stubs/int128.cc                              \
                      google/protobuf/stubs/int128.h                               \
                      google/protobuf/stubs/io_win32.cc                            \
                      google/protobuf/stubs/io_win32.h                             \
                      google/protobuf/stubs/map_util.h                             \
                      google/protobuf/stubs/mathutil.h                             \
                      google/protobuf/stubs/once.cc                                \
                      google/protobuf/stubs/shared_ptr.h                           \
                      google/protobuf/stubs/status.cc                              \
                      google/protobuf/stubs/status.h                               \
                      google/protobuf/stubs/status_macros.h                        \
                      google/protobuf/stubs/statusor.cc                            \
                      google/protobuf/stubs/statusor.h                             \
                      google/protobuf/stubs/stringpiece.cc                         \
                      google/protobuf/stubs/stringpiece.h                          \
                      google/protobuf/stubs/stringprintf.cc                        \
                      google/protobuf/stubs/stringprintf.h                         \
                      google/protobuf/stubs/structurally_valid.cc                  \
                      google/protobuf/stubs/strutil.cc                             \
                      google/protobuf/stubs/strutil.h                              \
                      google/protobuf/stubs/time.cc                                \
                      google/protobuf/stubs/time.h                                 \
                      google/protobuf/arena.cc                                     \
                      google/protobuf/arenastring.cc                               \
                      google/protobuf/extension_set.cc                             \
                      google/protobuf/generated_message_util.cc                    \
                      google/protobuf/generated_message_table_driven_lite.h        \
                      google/protobuf/generated_message_table_driven_lite.cc       \
                      google/protobuf/message_lite.cc                              \
                      google/protobuf/repeated_field.cc                            \
                      google/protobuf/wire_format_lite.cc                          \
                      google/protobuf/io/coded_stream.cc                           \
                      google/protobuf/io/coded_stream_inl.h                        \
                      google/protobuf/io/zero_copy_stream.cc                       \
                      google/protobuf/io/zero_copy_stream_impl_lite.cc             \
                      google/protobuf/any.pb.cc                                    \
                      google/protobuf/api.pb.cc                                    \
                      google/protobuf/stubs/mathlimits.cc                          \
                      google/protobuf/stubs/mathlimits.h                           \
                      google/protobuf/any.cc                                       \
                      google/protobuf/descriptor.cc                                \
                      google/protobuf/descriptor_database.cc                       \
                      google/protobuf/descriptor.pb.cc                             \
                      google/protobuf/duration.pb.cc                               \
                      google/protobuf/dynamic_message.cc                           \
                      google/protobuf/empty.pb.cc                                  \
                      google/protobuf/extension_set_heavy.cc                       \
                      google/protobuf/field_mask.pb.cc                             \
                      google/protobuf/generated_message_reflection.cc              \
                      google/protobuf/generated_message_table_driven_lite.h        \
                      google/protobuf/generated_message_table_driven.cc            \
                      google/protobuf/map_field.cc                                 \
                      google/protobuf/message.cc                                   \
                      google/protobuf/reflection_internal.h                        \
                      google/protobuf/reflection_ops.cc                            \
                      google/protobuf/service.cc                                   \
                      google/protobuf/source_context.pb.cc                         \
                      google/protobuf/struct.pb.cc                                 \
                      google/protobuf/stubs/substitute.cc                          \
                      google/protobuf/stubs/substitute.h                           \
                      google/protobuf/text_format.cc                               \
                      google/protobuf/timestamp.pb.cc                              \
                      google/protobuf/type.pb.cc                                   \
                      google/protobuf/unknown_field_set.cc                         \
                      google/protobuf/wire_format.cc                               \
                      google/protobuf/wrappers.pb.cc                               \
                      google/protobuf/io/gzip_stream.cc                            \
                      google/protobuf/io/printer.cc                                \
                      google/protobuf/io/strtod.cc                                 \
                      google/protobuf/io/tokenizer.cc                              \
                      google/protobuf/io/zero_copy_stream_impl.cc                  \
                      google/protobuf/compiler/importer.cc                         \
                      google/protobuf/compiler/parser.cc                           \
                      google/protobuf/util/delimited_message_util.cc               \
                      google/protobuf/util/field_comparator.cc                     \
                      google/protobuf/util/field_mask_util.cc                      \
                      google/protobuf/util/internal/constants.h                    \
                      google/protobuf/util/internal/datapiece.cc                   \
                      google/protobuf/util/internal/datapiece.h                    \
                      google/protobuf/util/internal/default_value_objectwriter.cc  \
                      google/protobuf/util/internal/default_value_objectwriter.h   \
                      google/protobuf/util/internal/error_listener.cc              \
                      google/protobuf/util/internal/error_listener.h               \
                      google/protobuf/util/internal/expecting_objectwriter.h       \
                      google/protobuf/util/internal/field_mask_utility.cc          \
                      google/protobuf/util/internal/field_mask_utility.h           \
                      google/protobuf/util/internal/json_escaping.cc               \
                      google/protobuf/util/internal/json_escaping.h                \
                      google/protobuf/util/internal/json_objectwriter.cc           \
                      google/protobuf/util/internal/json_objectwriter.h            \
                      google/protobuf/util/internal/json_stream_parser.cc          \
                      google/protobuf/util/internal/json_stream_parser.h           \
                      google/protobuf/util/internal/location_tracker.h             \
                      google/protobuf/util/internal/mock_error_listener.h          \
                      google/protobuf/util/internal/object_location_tracker.h      \
                      google/protobuf/util/internal/object_source.h                \
                      google/protobuf/util/internal/object_writer.cc               \
                      google/protobuf/util/internal/object_writer.h                \
                      google/protobuf/util/internal/protostream_objectsource.cc    \
                      google/protobuf/util/internal/protostream_objectsource.h     \
                      google/protobuf/util/internal/protostream_objectwriter.cc    \
                      google/protobuf/util/internal/protostream_objectwriter.h     \
                      google/protobuf/util/internal/proto_writer.cc                \
                      google/protobuf/util/internal/proto_writer.h                 \
                      google/protobuf/util/internal/structured_objectwriter.h      \
                      google/protobuf/util/internal/type_info.cc                   \
                      google/protobuf/util/internal/type_info.h                    \
                      google/protobuf/util/internal/type_info_test_helper.cc       \
                      google/protobuf/util/internal/type_info_test_helper.h        \
                      google/protobuf/util/internal/utility.cc                     \
                      google/protobuf/util/internal/utility.h                      \
                      google/protobuf/util/json_util.cc                            \
                      google/protobuf/util/message_differencer.cc                  \
                      google/protobuf/util/time_util.cc                            \
                      google/protobuf/util/type_resolver_util.cc

include $(BUILD_SHARED_LIBRARY)

LOCAL_SRC_FILES需要填入参与编译的所有源码文件路径,不同版本源码不同配置不同,可以查看protobuf/src/Makefile.am文件,选择对应的源码

jni目录,使用以下命令开始编译,这个命令是你ndk的目录,里面有个ndk-build命令,需要替换成自已的ndk目录

$ /Users/xiaolin/Library/Android/sdk/ndk/24.0.8215888/ndk-build   

错误

No suitable threading library available

/Users/xiaolin/qtt/code/android/ndkbuild/app/src/main/jni/google/protobuf/stubs/common.cc:52:2: error: "No suitable threading library available."
#error "No suitable threading library available."

解决:在源码/google/stubs/common.h里添加如下代码,github有相关问题记录 Issues

#ifndef HAVE_PTHREAD
#define HAVE_PTHREAD 1
#endif

error: undefined symbol: __android_log_write

    ld: error: undefined symbol: __android_log_write
>>> referenced by common.cc:142 (google/protobuf/stubs/common.cc:142)
>>>               /Users/xiaolin/qtt/code/android/ndkbuild/app/src/main/obj/local/arm64-v8a/objs/proto/google/protobuf/stubs/common.o:(google::protobuf::internal::DefaultLogHandler(google::protobuf::LogLevel, char const*, int, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&))
>>> referenced by common.cc:150 (google/protobuf/stubs/common.cc:150)
>>>               /Users/xiaolin/qtt/code/android/ndkbuild/app/src/main/obj/local/arm64-v8a/objs/proto/google/protobuf/stubs/common.o:(google::protobuf::internal::DefaultLogHandler(google::protobuf::LogLevel, char const*, int, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&))
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

解决:全局搜索__android_log_write,把用到这个函数的地方注释掉,github有相关问题记录 Issues