解决 multiple definition of `main' 多重定义

发布时间:2024-07-10 11:33:43 作者:yexindonglai@163.com 阅读(48)

背景

c工程使用cmake编译,明明工程之中只有一个mian函数,但是编译报错提示:

multiple definition of `main’,

整体报错如下:

  1. CMakeFiles/train_class.dir/main.cpp.obj: In function `main':
  2. D:/all_projects/opencv_projects/opencv_learn/lesson_11_train_class/main.cpp:15: multiple definition of `main'
  3. CMakeFiles/train_class.dir/CMakeFiles/3.27.8/CompilerIdCXX/CMakeCXXCompilerId.cpp.obj:D:/all_projects/opencv_projects/opencv_learn/lesson_11_train_class/cmake-build-debug/CMakeFiles/3.27.8/CompilerIdCXX/CMakeCXXCompilerId.cpp:831: first defined here
  4. collect2.exe: error: ld returned 1 exit status
  5. ninja: build stopped: subcommand failed.

出现该问题是因为使用了cmake指令file(GLOB_RECURSE 文件名集合变量 文件路径),在cmake编译中,使用GLOB_RECURSE宏,会递归遍历所有符合条件的文件,cmake编译生成的文件也会被搜索纳入文件名集合中,导致main重复定义问题。而我的 CMakeLists.txt 里面刚好就有这个指令

  1. # 多目录编译,编译根目录和子目录下的文件
  2. file (GLOB_RECURSE files *.cpp *.h) # 创建变量files
  3. add_executable(${PROJECT_NAME} ${files})

经过以上报错信息可以解析出: main.cpp 的第15行已经有一个main函数了,在 CMakeCXXCompilerId.cpp 的第831 行还有一个main函数,其中 CMakeCXXCompilerId.cpp 是有cmake生成的;

  1. # 第一个main函数所在位置
  2. D:/all_projects/opencv_projects/opencv_learn/lesson_11_train_class/main.cpp:15
  3. # 第二个main函数所在位置
  4. D:/all_projects/opencv_projects/opencv_learn/lesson_11_train_class/cmake-builddebug/CMakeFiles/3.27.8/CompilerIdCXX/CMakeCXXCompilerId.cpp:831

解决

方案1、

解决方法1:去掉GLOB_RECURSE,改为 GLOB

此方法将不能遍历子文件夹,如果工程庞大且代码目录结构复杂,需要逐个追加源代码目录,cmake文件编写相对复杂。

  1. # 多目录编译,编译根目录和子目录下的文件
  2. file (GLOB files *.cpp *.h) # 创建变量files
  3. add_executable(${PROJECT_NAME} ${files})

方案2、从文件名集合中剔除cmake编译生成的文件名

使用 list 的 REMOVE_ITEM 指令

  1. # 表示将 REMOVE_CMAKE 从 files 文件名集合中剔除
  2. list(REMOVE_ITEM files ${REMOVE_CMAKE})

改完后的 CMakeLists.txt 部分内容如下,因为我用cmake生成的 目录名为:cmake-build-debug,所以我剔除这个就行了;

  1. # 多目录编译,编译根目录和子目录下的文件
  2. file (GLOB_RECURSE files *.cpp *.h) # 创建变量files
  3. # 剔除 cmake-build-debug 目录下的所有文件,
  4. file(GLOB_RECURSE REMOVE_CMAKE "${CMAKE_CURRENT_SOURCE_DIR}/cmake-build-debug/*")
  5. list(REMOVE_ITEM files ${REMOVE_CMAKE})
  6. add_executable(${PROJECT_NAME} ${files})

关键字CMake