ld: error: undefined symbol: did you mean: extern “C“

碰到个问题,先看报错:

FAILURE: Build completed with 2 failures.

1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':shotsync:externalNativeBuildDebug'.
> Build command failed.
  Error while executing process D:\Android\AndroidSdk\cmake\3.10.2.4988404\bin\ninja.exe with arguments {-C E:\work\projects\CameraShotSync\shotsync\.cxx\cmake\debug\armeabi-v7a shotsync socket stcrpc yyjson}
  ninja: Entering directory `E:\work\projects\CameraShotSync\shotsync\.cxx\cmake\debug\armeabi-v7a'
  [1/2] Building CXX object CMakeFiles/shotsync.dir/SyncClient.cpp.o
  [2/2] Linking CXX shared library E:\work\projects\CameraShotSync\shotsync\build\intermediates\cmake\debug\obj\armeabi-v7a\libshotsync.so
  FAILED: E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/debug/obj/armeabi-v7a/libshotsync.so
  cmd.exe /C "cd . && D:\Android\AndroidSdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi19 --gcc-toolchain=D:/Android/AndroidSdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=D:/Android/AndroidSdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security  -std=c++11 -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libshotsync.so -o E:\work\projects\CameraShotSync\shotsync\build\intermediates\cmake\debug\obj\armeabi-v7a\libshotsync.so CMakeFiles/shotsync.dir/shotsync.cpp.o CMakeFiles/shotsync.dir/SyncServer.cpp.o CMakeFiles/shotsync.dir/SyncClient.cpp.o  E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/debug/obj/armeabi-v7a/libsocket.so E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/debug/obj/armeabi-v7a/libstcrpc.so -llog -latomic -lm && cd ."
  ld: error: undefined symbol: rpc_alloc()
  >>> referenced by SyncClient.cpp:27 (E:/work/projects/CameraShotSync/shotsync/src/main/cpp\SyncClient.cpp:27)
  >>>               CMakeFiles/shotsync.dir/SyncClient.cpp.o:(ClientInit)
  >>> did you mean: extern "C" rpc_alloc
  >>> defined in: E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/debug/obj/armeabi-v7a/libstcrpc.so
  clang++: error: linker command failed with exit code 1 (use -v to see invocation)
  ninja: build stopped: subcommand failed.
 


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================

2: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':shotsync:externalNativeBuildRelease'.
> Build command failed.
  Error while executing process D:\Android\AndroidSdk\cmake\3.10.2.4988404\bin\ninja.exe with arguments {-C E:\work\projects\CameraShotSync\shotsync\.cxx\cmake\release\armeabi-v7a shotsync socket stcrpc yyjson}
  ninja: Entering directory `E:\work\projects\CameraShotSync\shotsync\.cxx\cmake\release\armeabi-v7a'
  [1/2] Building CXX object CMakeFiles/shotsync.dir/SyncClient.cpp.o
  [2/2] Linking CXX shared library E:\work\projects\CameraShotSync\shotsync\build\intermediates\cmake\release\obj\armeabi-v7a\libshotsync.so
  FAILED: E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/release/obj/armeabi-v7a/libshotsync.so
  cmd.exe /C "cd . && D:\Android\AndroidSdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi19 --gcc-toolchain=D:/Android/AndroidSdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=D:/Android/AndroidSdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security  -std=c++11 -Oz -DNDEBUG  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libshotsync.so -o E:\work\projects\CameraShotSync\shotsync\build\intermediates\cmake\release\obj\armeabi-v7a\libshotsync.so CMakeFiles/shotsync.dir/shotsync.cpp.o CMakeFiles/shotsync.dir/SyncServer.cpp.o CMakeFiles/shotsync.dir/SyncClient.cpp.o  E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/release/obj/armeabi-v7a/libsocket.so E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/release/obj/armeabi-v7a/libstcrpc.so -llog -latomic -lm && cd ."
  ld: error: undefined symbol: rpc_alloc()
  >>> referenced by SyncClient.cpp:27 (E:/work/projects/CameraShotSync/shotsync/src/main/cpp\SyncClient.cpp:27)
  >>>               CMakeFiles/shotsync.dir/SyncClient.cpp.o:(ClientInit)
  >>> did you mean: extern "C" rpc_alloc
  >>> defined in: E:/work/projects/CameraShotSync/shotsync/build/intermediates/cmake/release/obj/armeabi-v7a/libstcrpc.so
  clang++: error: linker command failed with exit code 1 (use -v to see invocation)
  ninja: build stopped: subcommand failed.
 


* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================

* Get more help at https://help.gradle.org

BUILD FAILED in 918ms
41 actionable tasks: 2 executed, 39 up-to-date

其实cmake模块依赖啥的写得没问题,问题就在源码里,对C库的头文件引用,是直接写在了C++文件里,并且没有加extern "C",把C库的头文件引用扔到对应的头文件里,并且包含里在extern "C"里就好了,像这样:

#ifndef CAMERASHOTSYNC_SYNCCLIENT_H
#define CAMERASHOTSYNC_SYNCCLIENT_H
#ifdef __cplusplus
extern "C"{
#endif
#include "libstc-rpc/include/stc_rpc.h"

namespace client {

    int ClientInit(char *host, char const *port = "55555");

    int ClientDestroy();
}


#ifdef __cplusplus
}
#endif
#endif //CAMERASHOTSYNC_SYNCCLIENT_H

而不是像这样:

#include "SyncClient.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "libstc-rpc/include/stc_rpc.h"

namespace client {

    int sfd;

    int ClientInit(char *host, char const *port) {
        int ret;

        rpc_t* rpc = rpc_alloc();

        return 0;
    }


    int ClientDestroy() {
        int ret;

        return 0;
    }

}

可以参考文章:

extern "C"的用法_fatshaw的博客-优快云博客

https://www.youkuaiyun.com/tags/NtTaAg4sMjAtYmxvZwO0O0OO0O0O.html

<think> 首先,用户在询问如何解决一个特定的链接错误:解决ld.lld报错‘undefined symbol: auxadc_get_voltage’。用户提到了引用[1]、[2]、和[3],这些都是关于linker错误的例子,比如不同符号的未定义引用。 关键错误是:undefined symbol: auxadc_get_voltage。 根据引用[1],类似错误是undefined symbol: android::hardware::details::return_status::~return_status(),并给出了位置:ledcontrol.cpp:88。 引用[2]是关于undefined symbol: __aarch64_swp8_acq_rel。 引用[3]是关于undefined symbol: __strlen_chk。 用户的问题是:如何解决ld.lld报告的undefined symbol: auxadc_get_voltage的错误。 我需要基于这些引用和常见问题解决方法来提供帮助。 步骤分析链接错误: 1. **理解错误**:链接器ld.lld报告未定义的符号"auxadc_get_voltage"。这意味着在链接过程中,链接器找不到这个符号的定义。这可能是因为: - 需要的库没有被链接。 - 函数声明但没有定义。 - 符号名称错位或不匹配。 - 缺少必要的源文件或对象文件。 2. **常见解决方法**: - **检查函数定义**:确保auxadc_get_voltage这个函数在某个源文件或库中被定义。 - **链接正确的库**:如果这个函数在外部库中定义,确保链接器能找到并链接这个库。例如,在Android构建系统中,这可能涉及修改Android.mk或CMakeLists.txt文件。 - **检查头文件和声明**:确认在使用的源文件中包含了正确的头文件,并且声明与定义匹配。 - **符号可见性**:检查符号是否被正确导出或可见。 - **构建系统配置**:在Makefile、Android.bp或其他构建脚本中添加必要的依赖。 - **路径和位置**:确保所有需要的路径都被包含。 3. **基于用户提供的引用分析**: - 引用[1]:错误在ledcontrol.cpp:88,并且提到了vendor/rockchip/packages/LedJniDemo/jni/libjniled/android_arm64_armv8-a_cortex-a55_shared/obj/vendor/rockchip/packages/LedJniDemo/jni/ledcontrol.o。这表明错误发生在编译ledcontrol.cpp文件时。 - 引用[2]:提到了UE5.1Android Quest 2,涉及SDK管理。 - 引用[3]:关于__strlen_chk错误,指出可能调用了错误的string.h文件。 但这些是针对不同符号的错误。所以,我需要推广到auxadc_get_voltage。 4. **特定符号分析**:auxadc_get_voltage听起来像是一个与ADC(Analog-to-Digital Converter)相关的函数,可能用于读取电压值。在Android或嵌入式上下文中,它可能是一个硬件抽象层(HAL)函数或特定平台的库函数。 - 在Rockchip平台上(如引用[1]提到),auxadc_get_voltage可能定义在rockchip特定的库中。 5. **解决方法建议**: - **添加库依赖**:在链接器命令中,添加包含auxadc_get_voltage定义的库。例如,在Android构建中,可能需要添加类似libhardware、libhardware_legacy或特定于供应商的库。 - **检查源代码**:确保在代码中正确声明了auxadc_get_voltage。查看错误报告的文件和行号(类似于引用[1]中的ledcontrol.cpp:88),以确定哪里使用了这个符号。 - **搜索定义**:在源代码树中搜索auxadc_get_voltage的定义,确认它存在并且被编译。 - **构建系统修改**:对于Android NDK或类似构建,修改Android.mk或Android.bp添加LOCAL_SHARED_LIBRARIES或类似指令。 - **查看文档或社区**:如果这是特定硬件相关的,参考Rockchip文档或社区论坛。 6. **结构化回答**: - 解释错误:先简要解释什么是undefined symbol错误。 - 提供步骤:一步步指导如何解决。 - 参考引用:自然地引用提供的引用,但用户的引用是关于其他符号的,所以类比使用。 - 生成相关问题:根据系统级指令,在末尾生成相关问题。 7. **生成相关问题**:系统指令要求生成相关问题。例如: - 如何添加库依赖到Android构建系统? - auxadc_get_voltage函数在哪里定义? - 其他常见的ld.lld错误如何解决? 确保响应使用中文,因为指令要求使用中文回答。 最后,响应结构: 1. 解释错误。 2. 提供解决方法步骤。 3. 添加相关问题。 使用正确的LaTeX格式用于数学表达式,但这个问题不涉及数学,所以可能不需要LaTeX。 </think> ### 解决 ld.lld 报错 "undefined symbol: auxadc_get_voltage" 的方法 您遇到的链接错误 `ld.lld: error: undefined symbol: auxadc_get_voltage` 表明链接器 (`ld.lld`) 在编译过程中无法找到符号 `auxadc_get_voltage` 的定义。这种错误通常发生在以下场景: - `auxadc_get_voltage` 是硬件相关函数(例如 ADC 电压读取),定义在特定库或源文件中,但未被正确链接。 - 符号声明与定义不匹配,或构建系统配置错误(如缺少库依赖)。 - 路径问题导致链接器无法定位定义(类似于引用[3]中提到的 `string.h` 调用错误)[^3]。 基于类似错误(如引用[1]中的 `return_status` 未定义问题)[^1],以下是系统的解决方法步骤。我将从简单到复杂逐步指导您解决。 #### 步骤 1: 确认符号定义来源 `auxadc_get_voltage` 通常是 Rockchip 或其他嵌入式平台的硬件抽象层(HAL)函数,用于读取模拟数字转换器(ADC)电压值。 - **搜索定义位置**: - 在源代码树中搜索 `auxadc_get_voltage` 的定义。例如,在 Android 项目中运行: ```bash grep -r "auxadc_get_voltage" vendor/rockchip/ # Rockchip 特定路径 grep -r "auxadc_get_voltage" hardware/ # 通用 HAL 路径 ``` - 预期结果:函数可能定义在 `libhardware` 或供应商库(如 `librk_auxadc.so`)中。如果找不到定义,可能是缺少依赖源码或 SDK。 - **检查错误位置**:类似引用[1](指向 `ledcontrol.cpp:88`)[^1],找出编译错误的具体文件和行号(例如 `your_file.cpp:line`)。这将帮助定位调用点,确保头文件声明正确。 #### 步骤 2: 检查头文件和声明 - **确保正确包含头文件**:在调用 `auxadc_get_voltage` 的源文件(如 `.cpp` 文件)顶部添加正确头文件。例如: ```cpp // 示例:添加 Rockchip HAL 头文件 #include <hardware/auxadc_interface.h> // 或 vendor-specific header ``` - 如果头文件路径错误(类似引用[3]中的 `string.h` 问题)[^3],使用绝对路径或调整编译器包含路径。 - **验证声明一致性**:确保函数声明与定义匹配。例如: - 声明应为:`extern "C" uint32_t auxadc_get_voltage(void);`(如果使用 C++,需要注意名称修饰问题)。 #### 步骤 3: 添加库依赖到构建系统 这是最常见原因。`auxadc_get_voltage` 通常在预编译库中定义,需在构建脚本中显式链接。 - **Android NDK 项目(基于 Makefile)**: - 修改 `Android.mk` 或 `CMakeLists.txt`: ```makefile # Android.mk 示例 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := your_module LOCAL_SRC_FILES := your_source.cpp # 包含调用 auxadc_get_voltage 的文件 LOCAL_SHARED_LIBRARIES := libhardware # 添加依赖库,可能为 libhardware 或 vendor lib include $(BUILD_SHARED_LIBRARY) ``` - 如果 `libhardware` 不包含该符号,查找供应商库(如 `librk_auxadc`),并将其添加到 `LOCAL_SHARED_LIBRARIES`。 - **CMake 项目**: ```cmake # CMakeLists.txt 示例 find_library(HARDWARE_LIB hardware) # 查找库 target_link_libraries(your_target PRIVATE ${HARDWARE_LIB}) ``` - **通用链接器命令**:在命令行中添加库链接标志: ```bash clang++ -o output your_source.cpp -lhardware # -l 后跟库名 ``` #### 步骤 4: 更新 SDK 和工具链 引用[2]中提到 SDK 管理问题(如 Quest 2 的 r25b 更新)[^2],确保工具链兼容: - **检查 Android SDK/NDK 版本**: - 运行 `sdkmanager --list` 查看已安装版本。 - 更新 NDK:`sdkmanager --install "ndk;version"` - Rockchip 平台可能需要特定补丁。 - **验证架构兼容性**:`auxadc_get_voltage` 可能仅支持特定架构(如 ARM64)。在构建脚本中指定目标: ```makefile # Android.mk 示例 LOCAL_CFLAGS += -march=armv8-a # 针对 ARM64 ``` #### 步骤 5: 调试与验证 - **使用链接器诊断工具**: ```bash ld.lld --verbose --trace-symbol=auxadc_get_voltage your_object.o -lhardware ``` 这会显示链接器如何解析符号,帮助识别路径问题。 - **检查符号导出**: - 运行 `nm -D libhardware.so | grep auxadc_get_voltage` 确认符号在库中导出。 - 如果未导出,可能需要重新编译库或添加导出宏(如 `__attribute__((visibility("default")))`)。 - **回退代码**:如果符号缺失,添加临时空实现(仅用于测试): ```cpp uint32_t auxadc_get_voltage() { return 0; } // 在源文件中定义,验证是否消除错误 ``` #### 潜在根本原因总结 - **硬件库缺失**:Rockchip HAL 库未正确包含(类似引用[1]中的 LedJniDemo 问题)[^1]。 - **工具链不兼容**:NDK 版本过旧或架构不匹配(引用[2]相关)[^2]。 - **路径冲突**:头文件或库路径优先级错误(类似引用[3])[^3]。 如果以上步骤无效,提供更多上下文(如错误位置文件、构建系统类型),我将进一步分析。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值