【问题标题】:Building Protocol Buffers with Standalone NDK toolchain使用独立 NDK 工具链构建协议缓冲区
【发布时间】:2012-04-28 18:32:42
【问题描述】:

我在使用通过 $NDK/build/tools/make-standalone-toolchain.sh 脚本创建的独立 NDK 工具链构建 Android 协议缓冲区时遇到问题。我遇到的问题是:

libtool: link: g++ -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -O2 -g -DNDEBUG -o protoc main.o  ./.libs/libprotobuf.a ./.libs/libprotoc.a /home/sizeak/AudioFingerprinting/ProtoBuf/jni/src/.libs/libprotobuf.a -lz -lc
./.libs/libprotoc.a(plugin.pb.o): In function `GoogleOnceInit':
/home/sizeak/AudioFingerprinting/ProtoBuf/jni/src/./google/protobuf/stubs/once.h:115: undefined reference to `pthread_once'

这似乎意味着缺少 pthreads 库,但是 sysroot 是由 ndk 脚本创建的,因此应该包含所有内容,对吧?我在某处读到,使用独立工具链时无需显式链接 pthread。我使用的配置命令是:

./configure --host=arm-eabi --with-sysroot=$SYSROOT CC=$CC --enable-cross-compile --with-protoc=protoc LIBS="-lc"

环境变量设置为指向脚本创建的 sysroot。

我在网上的许多页面上都看到过这个问题,但似乎没有人发布答案。有人可以帮忙吗?

【问题讨论】:

  • 是您的 Android 应用程序的 ProtoBuf,您是否正在尝试创建一个共享库并在此 android 应用程序中使用它。您是否在 android.mk 文件中提到了 pthread 选项?
  • ProtoBuf 是一个在我发现独立工具链选项之前尝试使用 ndk-build 构建库的项目。

标签: android android-ndk protocol-buffers


【解决方案1】:

我设法使用 ndk-build 方法构建它,使用此处找到的信息:How to build protocol buffer by Android NDK

为了设置配置脚本,我运行了以下命令:

export CFLAGS="-march=armv7-a -mfloat-abi=softfp -DGOOGLE_PROTOBUF_NO_RTTI"
export CC=arm-linux-androideabi-gcc
export SYSROOT=$NDK/platforms/android-9/arch-arm
./configure --host=arm-eabi --with-sysroot=$SYSROOT CC=$CC --enable-cross-compile --with-protoc=protoc LIBS="-lc"

这是我使用的 Application.mk:

APP_STL := gnustl_static
APP_ABI := armeabi-v7a armeabi
APP_PROJECT_PATH := ./
APP_BUILD_SCRIPT := ./Android.mk

以及使用的 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/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/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-lite
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)

要将构建的库包含在我正在使用 Protocol Buffers 的其他 NDK 项目中,我必须使用该库将该库复制到项目的 jni 文件夹中,并修改其 Android.mk 以添加对它的引用:

...
...
LOCAL_LDLIBS := -llog -lOpenSLES -lGLESv2 jni/libprotobuf-lite.so   
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := protobuf-lite
LOCAL_SRC_FILES := libprotobuf-lite.so 

include $(PREBUILT_SHARED_LIBRARY)

我想就是这样,希望有人觉得它有用。

【讨论】:

  • 感谢分享。这个 ./Configuration 文件包含什么,你提到设置配置脚本。
  • 另外,在执行提及过程时,我得到 No rule to make target `jni/src/google/protobuf/stubs/common.cc..' 错误。如果我错过了什么,有什么建议!
  • 好的...忘记添加 lib 源文件...现在它开始构建但很快就会以消息 jni/./src/google/protobuf/stubs/common 响应失败。 cc:51:2: error: #error "没有合适的线程库可用。任何建议!
  • ./configure 将运行当前目录中的配置脚本,说明假设您在协议缓冲区源的根目录中打开了终端。您需要在运行 ndk-build 之前配置构建,因为需要在协议缓冲区源中配置一些自动生成的标头等。这可能就是您收到有关缺少线程库的错误的原因。我希望这就是你要问的!
  • 谢谢西蒙..它工作得很好。但是当我包含 Proto.h 文件时,它会返回以下错误“google/protobuf/stubs/common.h”。此外,当我构建源文件时,它会生成 libgnustl_shared.so 而不是 libprotobuf-lite.so 。我在这里遗漏了什么吗,请提出建议。
【解决方案2】:

我很难在 Windows 上使用 ndk-build 为 android 构建 Protobuf,但设法使用: - 赛格温 - android-ndk-r12b

这些步骤适用于 protobuf 3.6.1。 脚步: - 克隆 protobuf 存储库 - 在 repo 的根目录下,创建一个名为“jni”的新文件夹 (/path/to/repo/protobuf/jni) - 创建一个名为 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)

IGNORED_WARNINGS := -Wno-sign-compare -Wno-unused-parameter -Wno-sign-promo -Wno-error=return-type

COMPILER_SRC_FILES := \
    ../src/google/protobuf/arena.cc \
    ../src/google/protobuf/arenastring.cc \
    ../src/google/protobuf/extension_set.cc \
    ../src/google/protobuf/generated_message_table_driven_lite.cc \
    ../src/google/protobuf/generated_message_util.cc \
    ../src/google/protobuf/implicit_weak_message.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 \
    ../src/google/protobuf/message_lite.cc \
    ../src/google/protobuf/repeated_field.cc \
    ../src/google/protobuf/stubs/bytestream.cc \
    ../src/google/protobuf/stubs/common.cc \
    ../src/google/protobuf/stubs/int128.cc \
    ../src/google/protobuf/stubs/io_win32.cc \
    ../src/google/protobuf/stubs/status.cc \
    ../src/google/protobuf/stubs/statusor.cc \
    ../src/google/protobuf/stubs/stringpiece.cc \
    ../src/google/protobuf/stubs/stringprintf.cc \
    ../src/google/protobuf/stubs/structurally_valid.cc \
    ../src/google/protobuf/stubs/strutil.cc \
    ../src/google/protobuf/stubs/time.cc \
    ../src/google/protobuf/wire_format_lite.cc \
    ../src/google/protobuf/any.cc \
    ../src/google/protobuf/any.pb.cc \
    ../src/google/protobuf/api.pb.cc \
    ../src/google/protobuf/compiler/importer.cc \
    ../src/google/protobuf/compiler/parser.cc \
    ../src/google/protobuf/descriptor.cc \
    ../src/google/protobuf/descriptor.pb.cc \
    ../src/google/protobuf/descriptor_database.cc \
    ../src/google/protobuf/duration.pb.cc \
    ../src/google/protobuf/dynamic_message.cc \
    ../src/google/protobuf/empty.pb.cc \
    ../src/google/protobuf/extension_set_heavy.cc \
    ../src/google/protobuf/field_mask.pb.cc \
    ../src/google/protobuf/generated_message_reflection.cc \
    ../src/google/protobuf/generated_message_table_driven.cc \
    ../src/google/protobuf/io/gzip_stream.cc \
    ../src/google/protobuf/io/printer.cc \
    ../src/google/protobuf/io/strtod.cc \
    ../src/google/protobuf/io/tokenizer.cc \
    ../src/google/protobuf/io/zero_copy_stream_impl.cc \
    ../src/google/protobuf/map_field.cc \
    ../src/google/protobuf/message.cc \
    ../src/google/protobuf/reflection_ops.cc \
    ../src/google/protobuf/service.cc \
    ../src/google/protobuf/source_context.pb.cc \
    ../src/google/protobuf/struct.pb.cc \
    ../src/google/protobuf/stubs/mathlimits.cc \
    ../src/google/protobuf/stubs/substitute.cc \
    ../src/google/protobuf/text_format.cc \
    ../src/google/protobuf/timestamp.pb.cc \
    ../src/google/protobuf/type.pb.cc \
    ../src/google/protobuf/unknown_field_set.cc \
    ../src/google/protobuf/util/delimited_message_util.cc \
    ../src/google/protobuf/util/field_comparator.cc \
    ../src/google/protobuf/util/field_mask_util.cc \
    ../src/google/protobuf/util/internal/datapiece.cc \
    ../src/google/protobuf/util/internal/default_value_objectwriter.cc \
    ../src/google/protobuf/util/internal/error_listener.cc \
    ../src/google/protobuf/util/internal/field_mask_utility.cc \
    ../src/google/protobuf/util/internal/json_escaping.cc \
    ../src/google/protobuf/util/internal/json_objectwriter.cc \
    ../src/google/protobuf/util/internal/json_stream_parser.cc \
    ../src/google/protobuf/util/internal/object_writer.cc \
    ../src/google/protobuf/util/internal/proto_writer.cc \
    ../src/google/protobuf/util/internal/protostream_objectsource.cc \
    ../src/google/protobuf/util/internal/protostream_objectwriter.cc \
    ../src/google/protobuf/util/internal/type_info.cc \
    ../src/google/protobuf/util/internal/type_info_test_helper.cc \
    ../src/google/protobuf/util/internal/utility.cc \
    ../src/google/protobuf/util/json_util.cc \
    ../src/google/protobuf/util/message_differencer.cc \
    ../src/google/protobuf/util/time_util.cc \
    ../src/google/protobuf/util/type_resolver_util.cc \
    ../src/google/protobuf/wire_format.cc \
    ../src/google/protobuf/wrappers.pb.cc \

include $(CLEAR_VARS)

LOCAL_MODULE := libprotobuf
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := $(COMPILER_SRC_FILES)

LOCAL_C_INCLUDES := \
    $(LOCAL_PATH)/../android \
    $(LOCAL_PATH)/../src

LOCAL_CFLAGS := -frtti -DHAVE_PTHREAD $(IGNORED_WARNINGS)

LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../src

LOCAL_CPPFLAGS := -std=c++11
LOCAL_C_INCLUDES += ${ANDROID_NDK}sources/cxx-stl/gnu-libstdc++/4.9/include
LOCAL_C_INCLUDES += ${ANDROID_NDK}sources/cxx-stl/gnu-libstdc++/4.9/libs/$(APP_ABI)/include
LOCAL_C_INCLUDES += ${ANDROID_NDK}platforms/${APP_PLATFORM}/arch-$(TARGET_ARCH)/usr/include
LOCAL_LDLIBS += -lz -llog
LOCAL_STATIC_LIBRARIES += -lpthread
LOCAL_EXPORT_LDLIBS += -lz
LOCAL_EXPORT_CFLAGS := $(LOCAL_CFLAGS)
LOCAL_EXPORT_CPPFLAGS := $(LOCAL_CPPFLAGS)
include $(BUILD_SHARED_LIBRARY)
  • 创建一个名为 Application.mk 的文件并在其中粘贴以下代码
APP_STL := gnustl_static
APP_ABI := armeabi-v7a
APP_PLATFORM:=android-27
  • 启动 cygwin 并导航到 protobuf 存储库。
  • 运行./Configure(如果失败,可能是因为您缺少cygwin中的一些工具。安装它们)
  • 导出指向 ndk 文件夹根目录的 ANDROID_NDK 环境变量
  • 在PATH环境变量中添加ndk-build工具的路径
  • 运行ndk-build

应为您在 application.mk 中指定的架构使用 libprotobuf.so 创建一个“libs”文件夹

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-22
    • 2014-06-27
    • 2012-03-04
    • 2011-10-31
    • 2012-01-20
    • 1970-01-01
    • 2013-07-17
    • 2019-03-02
    相关资源
    最近更新 更多