【问题标题】:avoid using of .a for creation of .so避免使用 .a 创建 .so
【发布时间】:2012-07-27 10:45:24
【问题描述】:

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

在 socket.so 中使用libtest.so 时,我得到了error:undefined reference to 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.solibtest.a 文件都存在。好像我只使用libtest.a 它工作得很好。

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

如果我要评论LOCAL_LDFLAGS += libtest.a,那么我会收到error:undefined reference to function()

请任何人帮助我摆脱这个问题.......

【问题讨论】:

    标签: makefile android-ndk java-native-interface


    【解决方案1】:

    好像有点不干净。

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

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

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

    编辑:

    LOCAL_SRC_FILES := libtest.so 似乎是错误的。如果您想链接共享库,请将库传递给链接器而不是编译器:LOCAL_LDFLAGS += libtest.so,或者更好的是LOCAL_LDFLAGS += -L. -ltest

    【讨论】:

    • 在做 nm -a libxml2.so 我没有得到任何符号。但是当我完成 nm -a libxml2.a 后,我得到了它们......
    • nm -D 用于共享库,否则您将看不到任何内容。并且不要将-a 用于静态库,这将打印调试符号而不是普通符号。
    • 你能比较一下nm -D libxml2.sonm libxml2.a的输出吗?两者都包含您正在调用的函数符号吗?
    • 在这种情况下,不知道出了什么问题。接下来你可以尝试检查 ndk-build 输出,看看它是否真的链接到你的 .so。另外,尝试使用 -L。 -lxml2 而不是传递 libxml2.so。哦,不要把 .so 放在你的 SRC 列表中。它用于链接阶段,因此将其添加到 LOCAL_LDFLAGS。
    【解决方案2】:

    非常感谢@onitake。

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

    那么当我创建了一个合适的 libtest.so 时,

    注意:

    如果有人有正确的 .so 文件,但它仍然给出错误,那么可能有一些链接错误。所以只需删除该行:

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

    然后放

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-31
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      相关资源
      最近更新 更多