【问题标题】:AOSP - error: undefined reference to <function-name> during buildAOSP - 错误:在构建期间未定义对 <function-name> 的引用
【发布时间】:2020-04-25 09:51:46
【问题描述】:

我需要另一个有眼光的人来告诉我我做错了什么。

我不得不在我的设备上升级 U-boot 引导加载程序,自然我不得不让一切重新适应。但目前我无法像以前那样构建我的 AOSP 系统。我将从错误消息开始,写下我的思考过程:

target Symbolic: fw_printenv (out/target/product/board/symbols/system/bin/fw_printenv)
target Strip: fw_printenv (out/target/product/board/obj/EXECUTABLES/fw_printenv_intermediates/fw_printenv)
Install: out/target/product/board/system/bin/fw_printenv
target Executable: test_executer (out/target/product/board/obj/EXECUTABLES/test_executer_intermediates/LINKED/test_executer)
external/utils/production/set_display_orientation.cpp:81: error: undefined reference to 'fw_printenv(int, char**, int, env_opts*)'
external/utils/production/set_display_orientation.cpp:57: error: undefined reference to 'fw_setenv(int, char**, env_opts*)'
external/utils/production/set_display_orientation.cpp:65: error: undefined reference to 'fw_printenv(int, char**, int, env_opts*)'
collect2: error: ld returned 1 exit status

所以是链接器错误。而且我的代码找不到另一个模块中定义的函数。那么让我们看看负责set_display_orientation.cppAndroid.mk文件。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := test_executer
LOCAL_SRC_FILES := test_executer.cpp \
        TestSequences.cpp \
        buzzer_test.cpp \
        rtc_test.cpp \
        AudioTests.cpp \
        rs485_test.cpp \
        rs232.cpp \
        set_display_orientation.cpp \
        gpio.cpp \
        gpio_helper.c \
        ping.cpp \
        usb.cpp \
        mmc.cpp \
        display.cpp \
        touchscreen.cpp \
        productionSector.cpp \
        psoc_uart3.cpp \
        ../../tslib/tests/fbutils.c

LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_LIBRARIES += libfw libeeprom libpsoc_helper

LOCAL_SHARED_LIBRARIES += libts libc libcutils

LOCAL_C_INCLUDES += bootable/bootloader/uboot-imx/tools/env \
                    external/tslib \
                    external/tslib/tests \
                    external/tslib/src \
                    external/utils/eeprom \
                    external/utils/PSoCUpdate
ifneq ($(PTEST_VERSION),)
LOCAL_CFLAGS := -DPTEST_VERSION=$(PTEST_VERSION)
endif


LOCAL_CFLAGS += -DUSE_HOSTCC \
                -DANDROID \
                -isystem bootable/bootloader/uboot-imx/include/ \
                -isystem bootable/bootloader/uboot-imx/arch/arm/include/

include $(BUILD_EXECUTABLE)

现在错误消息表明存在对 fw_printenv()、fw_setenv() 和 fw_printenv() 的未定义引用。但是这些函数是在 bootable/bootloader/uboot-imx/tools/env 中定义的,它们包含在LOCAL_C_INCLUDES += bootable/bootloader/uboot-imx/tools/env 中,它们是LOCAL_STATIC_LIBRARIES += libfw 的一部分。为了完整起见,我还将包含负责 libfwAndroid.mk 文件,该文件是 U-Boot 的一部分。

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := fw_printenv

LOCAL_SRC_FILES :=  fw_env_main.c

LOCAL_C_INCLUDES += fw_env.h
LOCAL_STATIC_LIBRARIES := libfw

LOCAL_CFLAGS := -DUSE_HOSTCC \
                -DANDROID \
                -isystem$(LOCAL_PATH)/../../include/ \
                -isystem$(LOCAL_PATH)/../../arch/arm/include/


include $(BUILD_EXECUTABLE)

include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= libfw


LOCAL_SRC_FILES :=  fw_env.c \
                    ctype.c \
                    crc32.c \
                    env_attr.c \
                    env_flags.c \
                    aes.c
#since alot of duplicated Header files exist in uboot-imx/include/ we use -isystem here
#to search for the correct Headers in bionic first
LOCAL_CFLAGS := -DUSE_HOSTCC \
                -DANDROID \
                -isystem$(LOCAL_PATH)/../../include/ \
                -isystem$(LOCAL_PATH)/../../arch/arm/include/

LOCAL_C_INCLUDES += fw_env.h \
                    external/mtd-utils/new-utils/include/

include $(BUILD_STATIC_LIBRARY)

有人可以指出我在哪里出错了。我已经浏览了在线文档(https://developer.android.com/ndk/guides/android_mk),以及上下stackoverflow。我真的迷路了。

【问题讨论】:

  • 如何在代码中包含 libfw 的标头?看来您的代码是 C++ 而 libfw 是 C?您是否使用 extern "C" { } 来避免名称混淆问题? (参见例如stackoverflow.com/questions/67894/…
  • 我刚刚学到了一些新东西,你解决了我的问题。各方面的胜利!谢谢。
  • 太棒了。我会将其转换为完整答案,以便将问题标记为已回答。

标签: c++ linker android-source android.mk


【解决方案1】:

从 libfw 的Android.mk 可以看出,它是一个 C 库,而您的代码是 C++。 C 和 C++ 具有不同的 ABI,因此链接器无法将您在 C++ 代码中调用的函数与 C 库中定义的函数进行匹配。为防止出现此问题,请使用以下标头:

extern "C" {
#include "header_from_libfw.h"
}

这将指示 C++ 编译器为此头文件中定义的函数使用 C-ABI,以便在链接期间可以将它们与 C 库中定义的函数进行匹配。具体来说,这会禁用 C++ 样式的名称修改 (reference)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多