You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C项目中Boost单元测试因函数未定义引用致链接失败求助

问题

编译Boost单元测试时出现链接错误,提示未定义对add(int, int)的引用,错误信息如下:

/usr/bin/ld: CMakeFiles/MyTest.dir/test_main.cpp.o: in function `test_add::test_method()':
test_main.cpp:(.text+0x1dedb): undefined reference to `add(int, int)'
/usr/bin/ld: test_main.cpp:(.text+0x1e004): undefined reference to `add(int, int)'
collect2: error: ld returned 1 exit status
make[2]: *** [tests/CMakeFiles/MyTest.dir/build.make:105: tests/MyTest] Error 1
make[1]: *** [CMakeFiles/Makefile2:190: tests/CMakeFiles/MyTest.dir/all] Error 2
make: *** [Makefile:103: all] Error 2

注释掉单元测试的CMake配置后,主程序可正常编译运行。项目目录结构:

.
├── CMakeLists.txt
├── include
│   └── my_functions.h
├── src
│   ├── CMakeLists.txt
│   ├── main.c
│   └── my_functions.c
└── tests
    ├── CMakeLists.txt
    └── test_main.cpp

相关文件内容

my_functions.h

#ifndef MY_FUNCTIONS_H
#define MY_FUNCTIONS_H

int add(int a, int b);

#endif // MY_FUNCTIONS_H

my_functions.c

#include "my_functions.h"

int add(int a, int b) {
    return a + b;
}

main.c

#include "my_functions.h"
#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    printf("Sum of 3 and 4 is %d\n", add(3, 4));
    return 0;
}

test_main.cpp

#define BOOST_TEST_MODULE MyTest
#include <boost/test/included/unit_test.hpp>
#include "../include/my_functions.h"

// dummy unit test
BOOST_AUTO_TEST_CASE(test_dummy) {
    BOOST_CHECK(true);
}

BOOST_AUTO_TEST_CASE(test_add) {
    BOOST_CHECK(add(2, 3) == 5);
    BOOST_CHECK(add(0, 0) == 0);
}

根目录CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(MyProject VERSION 1.0)

# Set C standard
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED True)

# Include directories
include_directories(include)

# Create a library target for your functions
add_library(my_functions_lib src/my_functions.c)

# Add subdirectories
add_subdirectory(src)
add_subdirectory(tests)

src目录CMakeLists.txt

# Add executable
add_executable(MyProject main.c)

# Link the library with your executable
target_link_libraries(MyProject my_functions_lib)

tests目录CMakeLists.txt

# Find Boost
find_package(Boost REQUIRED COMPONENTS unit_test_framework)

# Add test executable
add_executable(MyTest test_main.cpp)

# Link Boost libraries and your function library to the test executable
target_link_libraries(MyTest
    Boost::unit_test_framework
    my_functions_lib
)

# Include directories
target_include_directories(MyTest PRIVATE ../include)

注释掉add函数引用后,虚拟测试可正常运行,需解决如何在test_main.cpp中正确引用add函数的问题。

解决方案

核心原因

问题源于C和C++的名称修饰规则差异:

  • my_functions.c是C代码,编译后函数名保留原始的add符号;
  • test_main.cpp是C代码,编译时会对add进行C风格的名称修饰(比如生成_Z3addii这类符号);
  • 链接时,C++代码找不到C语言编译出的add原始符号,因此抛出未定义引用错误。

修复步骤

修改my_functions.h,添加C/C兼容的编译指令,让C代码以C语言的规则解析头文件中的函数声明:

#ifndef MY_FUNCTIONS_H
#define MY_FUNCTIONS_H

#ifdef __cplusplus
extern "C" {
#endif

int add(int a, int b);

#ifdef __cplusplus
}
#endif

#endif // MY_FUNCTIONS_H

原理说明

  • __cplusplus是C编译器自动定义的宏,当C代码包含该头文件时,会触发extern "C"块;
  • extern "C"告诉C编译器,块内的函数采用C语言的名称规则,不进行C风格的名称修饰;
  • 这样C++代码编译后会使用原始的add符号,就能和C语言编译出的库成功链接。

验证操作

修改完头文件后,重新执行编译:

mkdir build && cd build
cmake ..
make
./tests/MyTest

测试将正常运行,不再出现链接错误。


内容的提问来源于stack exchange,提问作者BhanuKiran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:37:04