3

我使用 Eclipse 成功地使用链接到这个问题的方向来构建 Botan ,但是,Android Studio 应该取代 Eclipse 进行 Android 开发,所以我现在正试图让它在 Android Studio 中构建,但它失败了缺少头文件<iosfwd>。我收到以下错误:

Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
    /Users/User1/Development/android-ndk-r10d/ndk-build NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/Users/User1/application1/android/workspace/app/build/intermediates/ndk/debug/Android.mk APP_PLATFORM=android-19 NDK_OUT=/Users/User1/application1/android/workspace/app/build/intermediates/ndk/debug/obj NDK_LIBS_OUT=/Users/User1/application1/android/workspace/app/build/intermediates/ndk/debug/lib APP_ABI=all
  Error Code:
    2
  Output:
    In file included from /Users/User1/application1/android/workspace/app/src/main/jni/botan/botan_all.cpp:8:0:
    /Users/User1/application1/android/workspace/app/src/main/jni/botan/botan_all.h:11:18: fatal error: iosfwd: No such file or directory
     #include <iosfwd>
                      ^
    compilation terminated.
    make: *** [/Users/User1/application1/android/workspace/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/app//Users/User1/application1/android/workspace/app/src/main/jni/botan/botan_all.o] Error 1

我应该<iosfwd>从哪里获取头文件以及如何指示 Android Studio 找到它?


更新

我找到了以下生成文件: .../workspace/app/src/main/jni/botan/Android.mk

# jni/botan/Android.mk:
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := botan
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SRC_FILES := botan_all.cpp
LOCAL_CPPFLAGS := -DBOTAN_USE_GCC_INLINE_ASM=0

include $(BUILD_SHARED_LIBRARY)

我尝试在之后添加该行LOCAL_CPPFLAGS

LOCAL_C_INCLUDES := $(ANDROID_STL_INC)

但是构建似乎不受影响,我得到了同样的错误,所以我尝试编辑LOCAL_CPPFLAGS为:

LOCAL_CPPFLAGS := SEE_IF_THIS_BREAKS_THE_BUILD

看看我的编辑是否被看到,但同样,在 header 上完全相同的原始失败iosfwd。所以看来我的编辑不是构建的一部分。

如何让 Android Studio 提供更多信息,以便弄清楚它是如何进入失败的构建步骤的。目前,当我构建时,它会暂停,然后给出带有错误消息的窗口,但没有显示所有中间步骤来获得它,这可能会显示哪些 makefile 得到了它。

4

1 回答 1

1

我应该从哪里获取头文件以及如何指示 Android Studio 找到它?

C++ 运行时包括在内,--sysroot因为它取决于您要使用的 C++ 运行时。

$ cd /opt/android-ndk-r10
$ find . -name iosfwd
./sources/cxx-stl/gnu-libstdc++/4.6/include/iosfwd
./sources/cxx-stl/gnu-libstdc++/4.8/include/iosfwd
./sources/cxx-stl/llvm-libc++/libcxx/include/iosfwd
./sources/cxx-stl/stlport/stlport/iosfwd
./sources/cxx-stl/stlport/stlport/using/iosfwd

我使用 STLport 是因为 GNU 有有毒的许可条款。下面是 STLport 从命令行和 Eclipse 中的外观(我知道您的问题是关于 Android Studio,但这显示了您必须如何处理 C++ 运行时)。

因此,我为 Botan(我实际上已经在 Android 上构建并测试过)和 Crypto++ 等库构建了以下脚本:

# If more than one library is using STLport, then all libraries in the
# APK ***must*** use the shared version.
# STLPORT_LIB=libstlport_static.a
STLPORT_LIB=libstlport_shared.so

if [ "$_ANDROID_ARCH" == "arch-arm" ]; then
  if [ "$_ANDROID_ARMV7A" -ne 0 ]; then
      STLPORT_ABI=armeabi-v7a
  else
      STLPORT_ABI=armeabi
  fi
elif [ "$_ANDROID_ARCH" == "arch-x86" ]; then
  STLPORT_ABI=x86
elif [ "$_ANDROID_ARCH" == "arch-mips" ]; then
  STLPORT_ABI=mips
fi

export ANDROID_STL_INC="$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/stlport/"
export ANDROID_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/libs/$STLPORT_ABI/$STLPORT_LIB"

稍后,Makefile使用脚本中设置的环境变量:

# Android cross-compile configuration. Works in conjunction with IS_CROSS_COMPILE.
#   See http://www.cryptopp.com/wiki/Android_(Command_Line).
ifeq ($(IS_ANDROID),1)
  # CPP, CXX, AR, RANLIB, LD, etc are set in 'setenv-android.sh'
  CXXFLAGS = -DNDEBUG -g2 -Os -pipe -fPIC
  CXXFLAGS += -DCRYPTOPP_DISABLE_ASM $(ANDROID_FLAGS)
  CXXFLAGS += --sysroot=$(ANDROID_SYSROOT) -I$(ANDROID_STL_INC)
  LDLIBS += $(ANDROID_STL_LIB)
endif

下面是它在 Eclipse 下的样子:Compile native C++ shared object with Android NDK。答案显示了提供我的 C++ 共享对象、依赖于 Crypto++ 共享对象并Application.mk使用.Android.mklibstlport_shared.so


...我如何指示 Android Studio 找到它...

我真的没有答案,因为我不使用 Android Studio。但是将以下内容添加到您的构建文件中可能会有所帮助。这似乎是在 Android Studio 下指定 C++ 运行时的标准方式:

ndk {
    moduleName "MyNativeModule"
    stl "stlport_shared"
    ldLibs "log", "z", "m"
    cFlags "-I/some/include/path"
}

另请参阅以下内容:


一个重要的注意事项(根据我对 Android 进行交叉编译的经验)。确保-mfloat-abi=softfp是 ARMv7a 目标的编译器选项;并且-msoft-float是 ARMv7 目标的编译器选项。这对于 ABI 兼容性很重要。

如果-mfloat-abi=softfp省略,则浮点数将错误传递,Botan(或其他库)接收的浮点值将为0.0f. OpenSSL 有这个缺陷——Java 调用者的所有熵估计都是0.0f.

于 2015-01-11T03:03:10.973 回答