如何通过Android NDK构建协议缓冲区(Protocol Buffer)

14

我想构建Google协议缓冲库的本地版本。
我该如何做呢?


只是一个建议。首先用Java构建它,如果需要进一步优化,则转向NDK。至少在Java中,您将掌握基本协议。 - arunkumar
你尝试过使用谷歌提供的C++实现吗? - Marc Gravell
这是我的答案:https://stackoverflow.com/a/44773137/529442 - Eugene Gr. Philippov
2个回答

7

我使用了这个 Android.mk 文件并且构建成功。



    # Copyright (C) 2009 The Android Open Source Project
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    #

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    CC_LITE_SRC_FILES := \
        src/google/protobuf/stubs/common.cc                              \
        src/google/protobuf/stubs/once.cc                                \
        src/google/protobuf/stubs/hash.cc                                \
        src/google/protobuf/extension_set.cc                             \
        src/google/protobuf/generated_message_util.cc                    \
        src/google/protobuf/message_lite.cc                              \
        src/google/protobuf/repeated_field.cc                            \
        src/google/protobuf/wire_format_lite.cc                          \
        src/google/protobuf/io/coded_stream.cc                           \
        src/google/protobuf/io/zero_copy_stream.cc                       \
        src/google/protobuf/io/zero_copy_stream_impl_lite.cc


    COMPILER_SRC_FILES :=  \
        src/google/protobuf/descriptor.cc \
        src/google/protobuf/descriptor.pb.cc \
        src/google/protobuf/descriptor_database.cc \
        src/google/protobuf/dynamic_message.cc \
        src/google/protobuf/extension_set.cc \
        src/google/protobuf/extension_set_heavy.cc \
        src/google/protobuf/generated_message_reflection.cc \
        src/google/protobuf/generated_message_util.cc \
        src/google/protobuf/message.cc \
        src/google/protobuf/message_lite.cc \
        src/google/protobuf/reflection_ops.cc \
        src/google/protobuf/repeated_field.cc \
        src/google/protobuf/service.cc \
        src/google/protobuf/text_format.cc \
        src/google/protobuf/unknown_field_set.cc \
        src/google/protobuf/wire_format.cc \
        src/google/protobuf/wire_format_lite.cc \
        src/google/protobuf/compiler/code_generator.cc \
        src/google/protobuf/compiler/command_line_interface.cc \
        src/google/protobuf/compiler/importer.cc \
        src/google/protobuf/compiler/main.cc \
        src/google/protobuf/compiler/parser.cc \
        src/google/protobuf/compiler/plugin.cc \
        src/google/protobuf/compiler/plugin.pb.cc \
        src/google/protobuf/compiler/subprocess.cc \
        src/google/protobuf/compiler/zip_writer.cc \
        src/google/protobuf/compiler/cpp/cpp_enum.cc \
        src/google/protobuf/compiler/cpp/cpp_enum_field.cc \
        src/google/protobuf/compiler/cpp/cpp_extension.cc \
        src/google/protobuf/compiler/cpp/cpp_field.cc \
        src/google/protobuf/compiler/cpp/cpp_file.cc \
        src/google/protobuf/compiler/cpp/cpp_generator.cc \
        src/google/protobuf/compiler/cpp/cpp_helpers.cc \
        src/google/protobuf/compiler/cpp/cpp_message.cc \
        src/google/protobuf/compiler/cpp/cpp_message_field.cc \
        src/google/protobuf/compiler/cpp/cpp_primitive_field.cc \
        src/google/protobuf/compiler/cpp/cpp_service.cc \
        src/google/protobuf/compiler/cpp/cpp_string_field.cc \
        src/google/protobuf/compiler/java/java_enum.cc \
        src/google/protobuf/compiler/java/java_enum_field.cc \
        src/google/protobuf/compiler/java/java_extension.cc \
        src/google/protobuf/compiler/java/java_field.cc \
        src/google/protobuf/compiler/java/java_file.cc \
        src/google/protobuf/compiler/java/java_generator.cc \
        src/google/protobuf/compiler/java/java_helpers.cc \
        src/google/protobuf/compiler/java/java_message.cc \
        src/google/protobuf/compiler/java/java_message_field.cc \
        src/google/protobuf/compiler/java/java_primitive_field.cc \
        src/google/protobuf/compiler/java/java_service.cc \
        src/google/protobuf/compiler/javamicro/javamicro_enum.cc \
        src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc \
        src/google/protobuf/compiler/javamicro/javamicro_field.cc \
        src/google/protobuf/compiler/javamicro/javamicro_file.cc \
        src/google/protobuf/compiler/javamicro/javamicro_generator.cc \
        src/google/protobuf/compiler/javamicro/javamicro_helpers.cc \
        src/google/protobuf/compiler/javamicro/javamicro_message.cc \
        src/google/protobuf/compiler/javamicro/javamicro_message_field.cc \
        src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc \
        src/google/protobuf/compiler/python/python_generator.cc \
        src/google/protobuf/io/coded_stream.cc \
        src/google/protobuf/io/gzip_stream.cc \
        src/google/protobuf/io/printer.cc \
        src/google/protobuf/io/tokenizer.cc \
        src/google/protobuf/io/zero_copy_stream.cc \
        src/google/protobuf/io/zero_copy_stream_impl.cc \
        src/google/protobuf/io/zero_copy_stream_impl_lite.cc \
        src/google/protobuf/stubs/common.cc \
        src/google/protobuf/stubs/hash.cc \
        src/google/protobuf/stubs/once.cc \
        src/google/protobuf/stubs/structurally_valid.cc \
        src/google/protobuf/stubs/strutil.cc \
        src/google/protobuf/stubs/substitute.cc

    # C++ full library
    # =======================================================
    #include $(CLEAR_VARS)

    LOCAL_MODULE := libprotobuf
    LOCAL_MODULE_TAGS := optional

    LOCAL_CPP_EXTENSION := .cc

    LOCAL_SRC_FILES := \
        $(CC_LITE_SRC_FILES)                                             \
        src/google/protobuf/stubs/strutil.cc                             \
        src/google/protobuf/stubs/substitute.cc                          \
        src/google/protobuf/stubs/structurally_valid.cc                  \
        src/google/protobuf/descriptor.cc                                \
        src/google/protobuf/descriptor.pb.cc                             \
        src/google/protobuf/descriptor_database.cc                       \
        src/google/protobuf/dynamic_message.cc                           \
        src/google/protobuf/extension_set_heavy.cc                       \
        src/google/protobuf/generated_message_reflection.cc              \
        src/google/protobuf/message.cc                                   \
        src/google/protobuf/reflection_ops.cc                            \
        src/google/protobuf/service.cc                                   \
        src/google/protobuf/text_format.cc                               \
        src/google/protobuf/unknown_field_set.cc                         \
        src/google/protobuf/wire_format.cc                               \
        src/google/protobuf/io/gzip_stream.cc                            \
        src/google/protobuf/io/printer.cc                                \
        src/google/protobuf/io/tokenizer.cc                              \
        src/google/protobuf/io/zero_copy_stream_impl.cc                  \
        src/google/protobuf/compiler/importer.cc                         \
        src/google/protobuf/compiler/parser.cc

    LOCAL_C_INCLUDES := \
        $(LOCAL_PATH)/src

    LOCAL_C_INCLUDES := \
        $(LOCAL_PATH)/android \
        bionic \
        $(LOCAL_PATH)/src \
        $(JNI_H_INCLUDE)

    LOCAL_SHARED_LIBRARIES := \
        libz libcutils libutils
    LOCAL_LDLIBS := -lz
    # stlport conflicts with the host stl library
    ifneq ($(TARGET_SIMULATOR),true)
    LOCAL_C_INCLUDES += external/stlport/stlport
    LOCAL_SHARED_LIBRARIES += libstlport
    endif

    # Define the header files to be copied
    #LOCAL_COPY_HEADERS := \
    #    src/google/protobuf/stubs/once.h \
    #    src/google/protobuf/stubs/common.h \
    #    src/google/protobuf/io/coded_stream.h \
    #    src/google/protobuf/generated_message_util.h \
    #    src/google/protobuf/repeated_field.h \
    #    src/google/protobuf/extension_set.h \
    #    src/google/protobuf/wire_format_lite_inl.h
    #
    #LOCAL_COPY_HEADERS_TO := $(LOCAL_MODULE)

    LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI

    include $(BUILD_SHARED_LIBRARY)


这个有点过时了。对于protobuf 2.4.1,hash.cc不存在,因此应该将其删除。如果升级到protobug 2.5.0,则需要做同样的处理,并且还需要添加src/google/protobuf/stubs/stringprintf.cc。 - gkanwar
1
@gkanwar 当我进行您建议的编辑后,库编译成功,但是当我尝试调用依赖于protobuf库的方法时,出现以下错误: Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1306]: 37 cannot locate 'strtof'...使用“nm”命令,我注意到strtof方法被列出,但旁边有一个“U”。是否有一些必须包含的库才能使protobuf正常工作? - Michael Nguyen
你是怎么构建的?我遇到了很多错误。我正在尝试基于标签2.6.1进行构建,但我遇到诸如“/ src / google / protobuf /stubs / hash.h:172:55:错误:在'<'符号之前预期'{'”的错误。为什么普通的C++可以编译,但是针对Android就不行呢? - David T.
1
好的,我终于成功构建了。请使用这个链接代替:https://android.googlesource.com/platform/external/protobuf/ 你需要大量修改Android.mk文件才能让它正常工作。 - David T.
@DavidT. 有没有可能把你所用的步骤放在答案中?不一定是你对 Android.mk 文件所做的修改(虽然那会很棒),但至少包括任何导出的内容,你运行了什么等等。 - Sagar
显示剩余3条评论

4

上面提到的Android.mk很好用,非常感谢。

我想描述构建protobuf for android的所有步骤。

  • Configure sources for android. Use the following script (got it here: http://habrahabr.ru/post/119693/):

    PREBUILT=/Users/user/android-ndk-r7b/toolchains/arm-linux-androideabi-4.4.3

    PLATFORM=/Users/user/android-ndk-r7b/platforms/android-3/arch-arm/

    export CC="/Users/user/android-ndk-r7b/toolchains/arm-linux-androideabi- 4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gcc"

    export CFLAGS="-fPIC -DANDROID -nostdlib"

    export ANDROID_ROOT="/Users/user/android-ndk-r7b"

    export LDFLAGS="-Wl,-rpath-link=$ANDROID_ROOT/platforms/android-3/arch-arm/usr/lib/ -L$ANDROID_ROOT/platforms/android-3/arch-arm/usr/lib/"

    export CPPFLAGS="-I$ANDROID_ROOT/platforms/android-3/arch-arm/usr/include/"

    export LIBS="-lc "

    ./configure --host=arm-eabi

  • Delete the following lines from mentioned above Android.mk file:

    src/google/protobuf/stubs/strutil.cc             \
    src/google/protobuf/stubs/substitute.cc                          \
    src/google/protobuf/stubs/structurally_valid.cc                  \
    src/google/protobuf/descriptor.cc                                \
    src/google/protobuf/descriptor.pb.cc                             \
    src/google/protobuf/descriptor_database.cc                       \
    src/google/protobuf/dynamic_message.cc                           \
    src/google/protobuf/extension_set_heavy.cc                       \
    src/google/protobuf/generated_message_reflection.cc              \
    src/google/protobuf/message.cc                                   \
    src/google/protobuf/reflection_ops.cc                            \
    src/google/protobuf/service.cc                                   \
    src/google/protobuf/text_format.cc                               \
    src/google/protobuf/unknown_field_set.cc                         \
    src/google/protobuf/wire_format.cc                               \
    src/google/protobuf/io/gzip_stream.cc                            \
    src/google/protobuf/io/printer.cc                                \
    src/google/protobuf/io/tokenizer.cc                              \
    src/google/protobuf/io/zero_copy_stream_impl.cc                  \
    src/google/protobuf/compiler/importer.cc                         \
    src/google/protobuf/compiler/parser.cc
    

    It is needed for building lite version of library. Unfortunately full version of the lib works just from Android 2.3. I tested lite version for Android 1.6, 2.1, 2.3.

  • build the library using ndk-build.
  • for generating c++ files (using protoc compiler) for the lite library it is needed to include: option optimize_for = LITE_RUNTIME; in .proto file.

当我删除了提到的那些行,编译时出现了错误。你确定那些行需要被删除吗? - Michael Nguyen
你似乎忘记在CPPFLAGS中设置sysroot了:`export SYSROOT=$NDK_ROOT/platforms/android-9/arch-arm` `export CPPFLAGS="--sysroot=$SYSROOT"` `./configure options` - Eugene Gr. Philippov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接