AOSP - error: undefined reference to <function-name> during build
AOSP - error: undefined reference to <function-name> during build
我需要另一个有眼力的人来告诉我我做错了什么。
我不得不升级我设备上的 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.cpp.
的Android.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()[=32= 的 未定义引用].但是这些函数在 bootable/bootloader/uboot-imx/tools/env 中定义,它们包含在 LOCAL_C_INCLUDES += bootable/bootloader/uboot-imx/tools/env
中,它们是 LOCAL_STATIC_LIBRARIES += libfw
的一部分。为了完整起见,我还将包括负责 libfw 的 Android.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),并在 Whosebug 上上下下。我真的迷失了这一点。
从libfw的Android.mk
可以看出,它是一个C-library,而你的代码是C++。 C 和 C++ 具有不同的 ABI,因此链接器无法将您在 C++ 代码中调用的函数与 C 库中定义的函数进行匹配。为防止此问题包括 headers 使用:
extern "C" {
#include "header_from_libfw.h"
}
这将指示 C++ 编译器将 C-ABI 用于此 header 中定义的函数,以便它们可以在链接期间与 C-library 中定义的函数匹配.具体来说,这会禁用 C++ 风格的 name-mangling (reference).
我需要另一个有眼力的人来告诉我我做错了什么。
我不得不升级我设备上的 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.cpp.
的Android.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()[=32= 的 未定义引用].但是这些函数在 bootable/bootloader/uboot-imx/tools/env 中定义,它们包含在 LOCAL_C_INCLUDES += bootable/bootloader/uboot-imx/tools/env
中,它们是 LOCAL_STATIC_LIBRARIES += libfw
的一部分。为了完整起见,我还将包括负责 libfw 的 Android.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),并在 Whosebug 上上下下。我真的迷失了这一点。
从libfw的Android.mk
可以看出,它是一个C-library,而你的代码是C++。 C 和 C++ 具有不同的 ABI,因此链接器无法将您在 C++ 代码中调用的函数与 C 库中定义的函数进行匹配。为防止此问题包括 headers 使用:
extern "C" {
#include "header_from_libfw.h"
}
这将指示 C++ 编译器将 C-ABI 用于此 header 中定义的函数,以便它们可以在链接期间与 C-library 中定义的函数匹配.具体来说,这会禁用 C++ 风格的 name-mangling (reference).