【问题标题】:Android NDK linking, "undefined reference" When linking with a Static LibAndroid NDK 链接,“未定义的引用”与静态库链接时
【发布时间】:2015-01-24 08:17:20
【问题描述】:

环境

  • android-ndk-r10c
  • VisualGDB
  • Windows x64

用例 1

  • ADB Cmdline 可执行文件(无 Java / APK)由多个 C++ 文件组成
  • 编译的可执行文件在 Application.mk 中具有“APP_STL := gnustl_static”
  • 可执行文件已成功编译并运行

用例 2

  • 用例 1 的 ADB 工具分为两个独立的项目
    • 封装通用功能的静态库
    • ADB 工具减去移出静态库的功能
  • 可执行和静态 Lib 编译时在 Application.mk 中具有“APP_STL := gnustl_static”
  • ADB Exe 编译时具有 LOCAL_LDLIBS := -L$(PATH_TO_STATIC_LIB) -lstaticlib
  • 编译失败,出现“未定义的对 `std::terminate()' 的引用”链接器错误

手头的问题

将所有 CPP 文件编译为一个项目时一切正常,没有链接器错误。
当将逻辑吐出到一个瘦可执行文件和一个静态库(可执行文件链接到)中时,我得到一个“未定义的对 `std::terminate()' 的引用”链接器错误。

在我看来,尽管“APP_STL := gnustl_static”被指定,但“gnustl_static”似乎没有与可执行文件链接......

我在这里缺少什么?有什么方法可以强制“gnustl_static”链接?

参考的make文件:

Makefile,其中所有文件都属于同一可执行文件(WORKING)

应用程序.mk

APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := ScreenCapSvc
LOCAL_SRC_FILES := ScreenCapSvc.cpp SnapshotController.cpp SimpleTCPStream.cpp SocketsServer.cpp uuids.cpp
LOCAL_C_INCLUDES := 
LOCAL_STATIC_LIBRARIES := 
LOCAL_SHARED_LIBRARIES := 
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS := 
LOCAL_CPPFLAGS := 
LOCAL_LDFLAGS := 
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_EXECUTABLE)

生成文件,其中文件被拆分为静态库和链接到该库的可执行文件 (不工作)

可执行应用程序.mk

APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9

可执行的Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := ScreenCapSvc
LOCAL_SRC_FILES := ScreenCapSvc.cpp SnapshotController.cpp
LOCAL_C_INCLUDES := 
LOCAL_STATIC_LIBRARIES := 
LOCAL_SHARED_LIBRARIES := 
LOCAL_LDLIBS := -llog -L$(PATH_TO_STATIC_LIB) -lCollections_statis
LOCAL_CFLAGS := 
LOCAL_CPPFLAGS := 
LOCAL_LDFLAGS := 
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_EXECUTABLE)

静态库应用程序.mk

APP_STL := gnustl_static
APP_ABI := all
APP_CFLAGS := -std=gnu++11
APP_CPPFLAGS := -std=gnu++11
NDK_TOOLCHAIN_VERSION := 4.9
APP_MODULES := Collections-static Collections-shared

静态库 Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := Collections-shared
LOCAL_SRC_FILES := SimpleTCPStream.cpp SocketsServer.cpp uuids.cpp
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS :=
LOCAL_CPPFLAGS :=
LOCAL_LDFLAGS :=
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := Collections-static
LOCAL_SRC_FILES :=  $(COMMON_SRC_FILES)
include $(BUILD_STATIC_LIBRARY)

【问题讨论】:

    标签: android makefile android-ndk


    【解决方案1】:

    这不是 NDK 构建系统中的错误,而是您如何使用它的问题。

    如果您运行ndk-build V=1,您会看到它尝试执行的实际命令,并且您会看到它已经尝试在 gnustl_static 中进行链接,但它会在链接到您自己的静态库之前先将其链接。链接器仅按照链接器命令行中指定的顺序尝试库,这意味着它不会尝试使用之前指定的 gnustl_static 库来解析来自后续库的未定义引用。

    这里正确的解决方案是不要使用LOCAL_LDLIBS 来强制链接到静态库,而是使用 NDK 提供的基础设施来链接到静态库。也就是说,像这样更改您的可执行 Android.mk:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE           := ScreenCapSvc
    LOCAL_SRC_FILES        := ScreenCapSvc.cpp SnapshotController.cpp
    LOCAL_STATIC_LIBRARIES := Collections_static
    LOCAL_LDLIBS           := -llog
    include $(BUILD_EXECUTABLE)
    
    include $(CLEAR_VARS)
    LOCAL_MODULE    := Collections_static
    LOCAL_SRC_FILES := $(PATH_TO_STATIC_LIB)/libCollections_static.a
    include $(PREBUILT_STATIC_LIBRARY)
    

    这样,无论静态库是作为同一构建的一部分构建的,还是预构建的库,您都可以以相同的方式将静态库包含到可执行文件的构建中。

    此语法还允许您在静态库的部分中添加LOCAL_EXPORT_C_INCLUDES,以便在构建可执行文件时添加正确的包含路径,而无需手动将其添加到可执行文件的部分。

    【讨论】:

      【解决方案2】:

      看来,虽然“APP_STL := gnustl_static”在可执行文件的 Application.mk 中严格指定,但它并没有真正链接,为了强制 gnustl_static 链接我已将以下内容添加到 Android.mk 的 LOCAL_LDLIBS

      LOCAL_LDLIBS += -L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/$(TARGET_ARCH_ABI) -lgnustl_static
      

      在我看来像是 NDK 构建系统中的一个错误...

      【讨论】:

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