Android NDK:CLang错误的静态编译

时间:2015-03-13 16:16:27

标签: android android-ndk clang

我目前正在使用NDK和JNI为Android应用程序开发一个C / C ++模块。

我需要用CLang编译这个C模块并使用静态链接来删除对libc的依赖。

使用静态链接到libC的编译与GCC一起工作正常但我无法使用CLang。我收到以下错误:

D:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/../lib\crtbegin_static.o:crtbrand.c:function _start: error: undefined reference to 'main'

下面的示例是在Windows上,但问题在linux上是一样的。

通过一个非常简单的hello世界来演示问题:

您好-jni.c:

#include <jni.h>
jstring Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv* env, jobject thiz) {
return (*env)->NewStringUTF(env, "hello world");
}

makefile android.mk是:

LOCAL_PATH := $(call my-dir)

ifndef NDK_PATH
    NDK_PATH = C:/dev/android-ndk-r10d/
endif

SDK_VERSION = 21

include $(CLEAR_VARS)
LOCAL_MODULE    := LibC 
LOCAL_SRC_FILES := $(NDK_PATH)platforms/android-$(SDK_VERSION)/arch- $(TARGET_ARCH)/usr/lib/libc.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := libhello
LOCAL_SRC_FILES := hello-jni.c

LOCAL_STATIC_LIBRARIES := LibC 
LOCAL_CFLAGS += -nostdlib
LOCAL_LDFLAGS := -static -v

include $(BUILD_SHARED_LIBRARY)

和application.mk:

APP_ABI := armeabi-v7a
NDK_TOOLCHAIN_VERSION := clang3.5

如果它有任何用处,为LDFLAGS设置-v标志会给我:

"D:/tools/android-ndk-r10d/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin\ld.exe" --sysroot=D:/tools/android-ndk-r10d/platforms/android-21/arch-arm -X -m armelf_linux_eabi -Bstatic -dynamic-linker /system/bin/linker -o ./obj/local/armeabi-v7a/libhello.so "D:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/../lib\\crtbegin_static.o" -LD:/tools/android-ndk-r10d/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.8 -LD:/tools/android-ndk-r10d/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/lib/../lib -LD:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/../lib -LD:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/arm-linux-androideabi/../../lib-LD:/tools/android-ndk-r10d/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/lib -LD:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib -soname libhello.so ./obj/local/armeabi-v7a/objs-debug/hello/hello-jni.o D:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/libc.a -lgcc --fix-cortex-a8 --no-undefined -z noexecstack -z relro -z now -lc -lm -lstdc++ -lm --start-group -lgcc -lc --end-group "D:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/../lib\\crtend_so.o" D:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/../lib\crtbegin_static.o:crtbrand.c:function _start: error: undefined reference to 'main' clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation) make.exe: *** [obj/local/armeabi-v7a/libhello.so] Error 1

如果有人能帮助我,我将非常感激!

干杯

1 个答案:

答案 0 :(得分:2)

显然,您正在尝试构建共享库libhello.so

要构建共享库,必须将选项-shared传递给链接器(ld)。 您的链接命令显示tyou没有这样做。 如果不这样做,链接器会假定您正在尝试构建可执行程序。你呢 如果正在尝试构建C可执行文件,那么它必须具有main函数 执行将开始的int main(int argc, char *argv[])。如果你不这样做, 然后你会得到你看到的连锁错误。 hello-jni.c 不包含任何main函数,因为它应该构建为库, 不是一个程序。

因此,将LOCAL_LDFLAGS更改为-shared -static。 (或者可能更符合 构建的组织,将-shared添加到链接器标记,无论它们在何处 在include $(BUILD_SHARED_LIBRARY)内设置。您 可能会认为-shared-static是相互矛盾的选择,但它们不是。 -shared表示构建共享库-static表示不链接任何共享库 无论正在建造什么

此外,如果您要构建共享库,则必须传递选项-fPIC, 在编译源文件时生成与位置无关的目标代码。 我们看不到任何编译命令,但您需要-fPIC才能出现 在您传递给编译器的CFLAGS中。据我们所知 makefile,您只传递-nostdlib

我不清楚为什么要将-nostlib传递给编译器。它是一个链接器 选项,对编译没有影响,我们在你的链接命令中没有看到它, 它会产生一些影响。

顺便说一下,似乎有一个潜藏在某处的空间 您构建的看不见的解剖学。在那个详细的链接命令中,怪物-L 选项:

-LD:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/arm-linux-androideabi/../../lib-LD:/tools/android-ndk-r10d/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/lib

显然是两个连在一起的:

-LD:/tools/android-ndk-r10d/platforms/android-21/arch-arm/usr/lib/arm-linux-androideabi/../../lib
-LD:/tools/android-ndk-r10d/toolchains/arm-linux-androideabi-4.8/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/lib

我希望这会让链接器尝试搜索怪物不存在的路径 两个较短的路径,但可能连接只是一个印刷错误。