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

使用CMake编译C++代码时遭遇链接错误2,请求协助排查

CMake编译C++代码时出现重复定义错误

最近我尝试用CMake编译一段简单的C++代码,结果踩了个坑,相关的代码、CMake配置以及make时的错误信息我整理出来了:

涉及的代码文件

test.cpp

#ifndef _IOSTREAM_
#include<iostream>
#endif
#include"test1.cpp"
using namespace std;
int main() {
 printing("hello");
 return 0;
}

test1.cpp

#ifndef _IOSTREAM_
#include<iostream>
#endif
#include<string>
void printing(const string& msg) {
    cout << msg << endl;
}

CMakeLists.txt配置

cmake_minimum_required(VERSION 3.10)
project(TestProject)

add_executable(test test.cpp test1.cpp)

make时的错误信息

/usr/bin/ld: CMakeFiles/test.dir/test.cpp.o:/home/user/test/test1.cpp:8: multiple definition of `printing(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&)'; CMakeFiles/test.dir/test1.cpp.o:/home/user/test/test1.cpp:8: first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test.dir/build.make:104: test] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/test.dir/all] Error 1
make: *** [Makefile:84: all] Error 1

问题分析

这个错误的核心原因是直接在源文件中包含另一个.cpp文件:

  • 当test.cpp包含test1.cpp时,编译test.cpp会把test1.cpp的内容全部展开,导致test.cpp.o中包含了printing函数的定义;
  • 同时CMakeLists.txt里又把test1.cpp作为单独的源文件加入编译,生成的test1.cpp.o中也有printing函数的定义;
  • 链接阶段,两个目标文件里的同一个函数定义冲突,就报了重复定义的错误。

解决方法

1. 调整代码结构,使用头文件+源文件的标准写法

  • 创建test1.h头文件,用于声明函数:
#ifndef TEST1_H
#define TEST1_H
#include<string>

// 函数声明
void printing(const std::string& msg);

#endif // TEST1_H
  • 修改test1.cpp,只保留函数实现,并包含对应的头文件:
#include "test1.h"
#include <iostream>

// 函数实现
void printing(const std::string& msg) {
    std::cout << msg << std::endl;
}
  • 修改test.cpp,改为包含头文件test1.h而非源文件test1.cpp:
#include <iostream>
#include "test1.h"

using namespace std;
int main() {
    printing("hello");
    return 0;
}

2. 保持CMakeLists.txt的正确配置(无需修改)

原来的CMake配置是正确的,它会编译两个源文件并链接成可执行文件:

cmake_minimum_required(VERSION 3.10)
project(TestProject)

add_executable(test test.cpp test1.cpp)

3. 重新编译执行

清理之前的构建文件,重新编译:

rm -rf build && mkdir build && cd build
cmake ..
make
./test

这样就能正常编译运行,输出hello了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:13:21