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

用Meson可构建简单项目,CMake构建双可执行文件遇main重定义问题

解决CMake中多个main()导致的“Multiple definition”错误

哦,这个坑我见太多了!你遇到的问题根本不是CMake的限制,而是你大概率写错了CMakeLists.txt的逻辑——把两个包含main()的源文件塞进了同一个可执行目标里,或者重复引用了某个带main的文件到多个目标中。Meson你能成功,肯定是因为你分开声明了两个独立的可执行目标,而CMake这边没做对。

先给你拆解下报错原因:链接器在生成可执行文件时,要求整个目标里只能有一个main()入口。如果你的CMake脚本把source1.cpp和test.cpp都加到同一个add_executable里,链接器就会看到两个main定义,直接抛出“Multiple definition”的错误,这完全符合预期。

正确的CMake写法

你需要为每个带main()的源文件单独创建一个可执行目标,目标名称必须唯一,具体步骤如下:

1. 基础版本(无共用代码)

如果source1.cpp和test.cpp是完全独立的(没有共用的其他源文件),直接写两个add_executable即可:

# 生成发布版可执行文件,对应source1.cpp里的main()
add_executable(MyApp source1.cpp)

# 生成测试版可执行文件,对应test.cpp里的main()
add_executable(MyAppTest test.cpp)

这样CMake会生成两个独立的可执行文件:MyApp(发布版)和MyAppTest(测试版),各自对应自己的main入口,完全不会冲突。

2. 进阶版本(有共用代码)

如果你的项目里有共用的工具类/函数(比如utils.cpp),不要把这些文件重复加到两个可执行目标里,而是把它们编译成一个库,再链接到两个目标:

# 把共用代码编译成静态库(STATIC也可以换成SHARED生成动态库,看需求)
add_library(MyAppCommon STATIC utils.cpp)

# 发布版:仅包含source1.cpp,链接共用库
add_executable(MyApp source1.cpp)
target_link_libraries(MyApp PRIVATE MyAppCommon)

# 测试版:仅包含test.cpp,链接共用库
add_executable(MyAppTest test.cpp)
target_link_libraries(MyAppTest PRIVATE MyAppCommon)

这种方式不仅避免了代码重复编译,还能让项目结构更清晰。

你可能踩的错误写法

对比一下,你之前的CMake脚本大概率是类似这样的错误写法:

# ❌ 错误!把两个带main的文件加到同一个目标里
add_executable(MyApp source1.cpp test.cpp)

这种写法会让CMake尝试把两个main()都打包进同一个可执行文件,链接器自然会报错。

额外优化:给不同版本设置专属编译选项

你还可以给发布版和测试版设置不同的编译参数,比如发布版开启优化,测试版开启调试信息:

# 发布版:开启O2优化
target_compile_options(MyApp PRIVATE -O2)

# 测试版:开启调试信息和警告
target_compile_options(MyAppTest PRIVATE -g -Wall -Wextra)

核心思路就是:每个可执行目标对应唯一的main入口源文件,目标名称不能重复,共用代码通过库来管理。按照这个逻辑写,CMake生成两个可执行文件和Meson一样轻松!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:10:18