首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android :带有CLang错误的静态编译

Android :带有CLang错误的静态编译
EN

Stack Overflow用户
提问于 2015-03-13 16:16:27
回答 1查看 4.5K关注 0票数 1

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

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

对于GCC来说,静态链接到libC的编译工作得很好,但我无法让它使用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:

代码语言:javascript
复制
#include <jni.h>
jstring Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv* env, jobject thiz) {
return (*env)->NewStringUTF(env, "hello world");
}

makefile android.mk是:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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

如果你们中的任何人能帮我,我将非常感激!

干杯

EN

回答 1

Stack Overflow用户

发布于 2015-03-15 19:39:18

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

要构建共享库,必须将选项-shared传递给链接器(ld)。链接命令显示您没有这样做。如果没有,链接器假设您正在尝试构建一个可执行程序。如果您想要构建一个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选项:

代码语言:javascript
复制
-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

两人显然是联合在一起的:

代码语言:javascript
复制
-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

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29037105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档