VS Code Linux Devcontainer中C项目(GoogleTest+CMake)构建错误排查
问题:CMake+GoogleTest构建C项目时出现未定义引用错误
项目背景
在VS Code的Linux开发容器(Devcontainer)中搭建集成GoogleTest与CMake的C项目,已将googletest仓库克隆到项目内的googletest文件夹中。
开发容器Dockerfile
FROM mcr.microsoft.com/devcontainers/cpp:0-ubuntu-22.04 ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="3.22.2" # Optionally install the cmake for vcpkg COPY ./reinstall-cmake.sh /tmp/ RUN if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then \ chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \ fi \ && rm -f /tmp/reinstall-cmake.sh # Add googletest and cmake RUN apt-get update && sudo apt-get update && sudo apt-get install -y build-essential libgtest-dev
CMakeLists.txt
cmake_minimum_required(VERSION 3.14) project(Piscine-42) # GoogleTest requires at least C++14 set(CMAKE_CXX_STANDARD 14) # set for C set(CMAKE_C_STANDARD 99) add_subdirectory(googletest) # add googletest subdirectory include_directories(googletest/include) # this is so we can #include <gtest/gtest.h> add_executable(test_return_one test_return_one.cpp) # add this executable target_link_libraries(test_return_one PRIVATE gtest) # link google test to this executable
被测代码
return_one.c
#include "return_one.h" int return_one(void) { return (1); }
return_one.h
#include "return_one.h" int return_one(void) { return (1); }
测试代码
test_return_one.cpp
#include "gtest/gtest.h" extern "C" { #include "return_one.h" } TEST(t_return_one, returns_1) { EXPECT_EQ(1,return_one()); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
构建错误信息
使用VS Code的CMake-tools扩展构建时出现以下错误:
[main] Building folder: Piscine-42 test_return_one [build] Starting build [proc] Executing command: /usr/local/bin/cmake --build /workspaces/Piscine-42/build --config Debug --target test_return_one -- [build] [1/1 100% :: 0.266] Linking CXX executable test_return_one [build] FAILED: test_return_one [build] : && /usr/bin/g++ -g CMakeFiles/test_return_one.dir/test_return_one.cpp.o -o test_return_one lib/libgtest.a && : [build] /usr/bin/ld: CMakeFiles/test_return_one.dir/test_return_one.cpp.o: in function `t_return_one_returns_1_Test::TestBody()': [build] /workspaces/Piscine-42/test_return_one.cpp:9: undefined reference to `return_one' [build] collect2: error: ld returned 1 exit status [build] ninja: build stopped: subcommand failed. [proc] The command: /usr/local/bin/cmake --build /workspaces/Piscine-42/build --config Debug --target test_return_one -- exited with code: 1 and signal: null [build] Build finished with exit code 1
解决方法
问题根源
- 链接阶段未找到
return_one函数的实现:当前CMake仅编译了测试代码test_return_one.cpp,未将被测的return_one.c加入构建目标,导致链接时缺失函数实现。 - 头文件循环引用:
return_one.h中包含自身,会引发重复定义问题。
具体修复步骤
- 修复头文件循环引用
修改return_one.h,添加头文件保护防止重复包含:
#ifndef RETURN_ONE_H #define RETURN_ONE_H int return_one(void); #endif
- 修改CMakeLists.txt,加入被测代码
将被测C代码编译为静态库,再与测试可执行文件链接,修改后的配置如下:
cmake_minimum_required(VERSION 3.14) project(Piscine-42) # GoogleTest requires at least C++14 set(CMAKE_CXX_STANDARD 14) set(CMAKE_C_STANDARD 99) # 添加googletest子目录 add_subdirectory(googletest) # 将被测代码编译为静态库 add_library(return_one_lib STATIC return_one.c) # 包含头文件目录 include_directories( googletest/include ${PROJECT_SOURCE_DIR} ) # 创建测试可执行文件 add_executable(test_return_one test_return_one.cpp) # 链接测试库与被测库 target_link_libraries(test_return_one PRIVATE gtest return_one_lib)
- 重新构建项目
在VS Code中执行CMake: Configure重新生成构建配置,再执行CMake: Build即可完成构建。
内容的提问来源于stack exchange,提问作者ThrowsError
相关产品推荐
相关产品推荐

