Makefile 避免使用.a创建.so

Makefile 避免使用.a创建.so,makefile,android-ndk,java-native-interface,Makefile,Android Ndk,Java Native Interface,我已经创建了一个android应用程序,这里我的大部分代码都是c语言,所以我使用jni创建了它。我必须创建socket.so文件,其中必须使用libtest.so 在socket.so中使用libtest.so时,我得到错误:未定义对function()的引用。。my function()存在于libtest.so中。为了避免这个问题,我创建了我的Android.mk,如下所示: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_

我已经创建了一个android应用程序,这里我的大部分代码都是c语言,所以我使用jni创建了它。我必须创建
socket.so
文件,其中必须使用
libtest.so

在socket.so中使用
libtest.so
时,我得到
错误:未定义对function()的引用。
。my function()存在于
libtest.so中。为了避免这个问题,我创建了我的Android.mk,如下所示:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libtest
LOCAL_SRC_FILES := libtest.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := socket
LOCAL_SHARED_LIBRARIES += libtest
LOCAL_SRC_FILES := source/interface.c source/file.c
LOCAL_LDFLAGS += libtest.a  
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../libtest/jni/include
include $(BUILD_SHARED_LIBRARY)
但是它需要同时存在
libtest.so
libtest.a
文件。好像我只使用了
libtest.a
它工作得非常好

因为我的要求是创建libtest.so并将其包含在socket.so中,所以请任何人告诉我如何避免依赖.a文件来创建.so文件

如果我将注释
LOCAL\u LDFLAGS+=libtest.a
,那么我将得到
错误:未定义对function()的引用

任何人都可以帮我摆脱这个问题……

看起来有点不干净

共享库(.so)和存档(.a)都应该包含相同的代码,但实际上可能不是。你应该做的第一件事是检查。so是否真的有所有的符号。链接器可能已经优化了一些。为此,请使用
nm
实用程序或
objdump

您还可以发布ndk build正在执行的命令的控制台转储吗

您也可以尝试避免您正在做的事情,因为NDK并不是真正用来生成相互依赖的共享库。当然,这是可能的,但推荐的方法是将lib填充到静态归档中,并将它们直接链接到生成的JNI中

编辑:

LOCAL\u SRC\u FILES:=libtest。因此
似乎是错误的。如果要链接共享库,请将库传递给链接器而不是编译器:
LOCAL\u LDFLAGS+=libtest。因此
或者更好的是,
LOCAL\u LDFLAGS+=-L.-ltest
似乎有点不干净

共享库(.so)和存档(.a)都应该包含相同的代码,但实际上可能不是。你应该做的第一件事是检查。so是否真的有所有的符号。链接器可能已经优化了一些。为此,请使用
nm
实用程序或
objdump

您还可以发布ndk build正在执行的命令的控制台转储吗

您也可以尝试避免您正在做的事情,因为NDK并不是真正用来生成相互依赖的共享库。当然,这是可能的,但推荐的方法是将lib填充到静态归档中,并将它们直接链接到生成的JNI中

编辑:


LOCAL\u SRC\u FILES:=libtest。因此
似乎是错误的。如果要链接共享库,请将库传递给链接器而不是编译器:
LOCAL\u LDFLAGS+=libtest。因此
或者更好的是,
LOCAL\u LDFLAGS+=-L.-ltest

非常感谢@onitake

这里有一个简单的错误是libtest.so不正确(由有bug的代码创建)

然后当我创建了一个合适的libtest.so

注:

如果有人使用了正确的.so文件,但仍然给出了错误,那么可能存在一些链接错误。因此,jst删除该行:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../libtest/jni/include

LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH)/../../libtest/jni/include 

上述两种说法都是一样的,但有时是有效的。

非常感谢@onitake

这里有一个简单的错误是libtest.so不正确(由有bug的代码创建)

然后当我创建了一个合适的libtest.so

注:

如果有人使用了正确的.so文件,但仍然给出了错误,那么可能存在一些链接错误。因此,jst删除该行:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../libtest/jni/include

LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH)/../../libtest/jni/include 

上述两个语句都是相同的,但有时是有效的。

在执行nm-a libxml2时。因此,我没有得到任何符号。但是,当我完成nm-a libxml2.a时,我得到了它们…….使用
nm-D
作为共享库,否则您将看不到任何东西。不要对静态库使用
-a
,因为静态库将打印调试符号而不是普通符号。您能比较
nm-D libxml2.so
nm libxml2.a
的输出吗?这两个函数都包含您正在调用的函数符号吗?在这种情况下,不知道出了什么问题。接下来,您可以尝试检查ndk构建输出,看看它是否真的链接到了您的.so。另外,尝试使用-L.-lxml2而不是传递libxml2.so。哦,不要把。所以在你的SRC列表中。它是用于链接阶段的,所以将其添加到LOCAL_LDFLAGS中。让我们在执行nm-a libxml2时使用它。因此,我没有得到任何符号。但是,当我完成nm-a libxml2.a时,我得到了它们…….使用
nm-D
作为共享库,否则您将看不到任何东西。不要对静态库使用
-a
,因为静态库将打印调试符号而不是普通符号。您能比较
nm-D libxml2.so
nm libxml2.a
的输出吗?这两个函数都包含您正在调用的函数符号吗?在这种情况下,不知道出了什么问题。接下来,您可以尝试检查ndk构建输出,看看它是否真的链接到了您的.so。另外,尝试使用-L.-lxml2而不是传递libxml2.so。哦,不要把。所以在你的SRC列表中。这是为链接阶段准备的,所以请将其添加到本地标志中