背景
c工程使用cmake编译,明明工程之中只有一个mian函数,但是编译报错提示:
multiple definition of `main’,
整体报错如下:
CMakeFiles/train_class.dir/main.cpp.obj: In function `main':
D:/all_projects/opencv_projects/opencv_learn/lesson_11_train_class/main.cpp:15: multiple definition of `main'
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
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
出现该问题是因为使用了cmake指令file(GLOB_RECURSE 文件名集合变量 文件路径)
,在cmake编译中,使用GLOB_RECURSE宏,会递归遍历所有符合条件的文件,cmake编译生成的文件也会被搜索纳入文件名集合中,导致main重复定义问题。而我的 CMakeLists.txt 里面刚好就有这个指令
# 多目录编译,编译根目录和子目录下的文件
file (GLOB_RECURSE files *.cpp *.h) # 创建变量files
add_executable(${PROJECT_NAME} ${files})
经过以上报错信息可以解析出: main.cpp 的第15行已经有一个main函数了,在 CMakeCXXCompilerId.cpp 的第831 行还有一个main函数,其中 CMakeCXXCompilerId.cpp 是有cmake生成的;
# 第一个main函数所在位置
D:/all_projects/opencv_projects/opencv_learn/lesson_11_train_class/main.cpp:15
# 第二个main函数所在位置
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文件编写相对复杂。
# 多目录编译,编译根目录和子目录下的文件
file (GLOB files *.cpp *.h) # 创建变量files
add_executable(${PROJECT_NAME} ${files})
方案2、从文件名集合中剔除cmake编译生成的文件名
使用 list 的 REMOVE_ITEM 指令
# 表示将 REMOVE_CMAKE 从 files 文件名集合中剔除
list(REMOVE_ITEM files ${REMOVE_CMAKE})
改完后的 CMakeLists.txt 部分内容如下,因为我用cmake生成的 目录名为:cmake-build-debug,所以我剔除这个就行了;
# 多目录编译,编译根目录和子目录下的文件
file (GLOB_RECURSE files *.cpp *.h) # 创建变量files
# 剔除 cmake-build-debug 目录下的所有文件,
file(GLOB_RECURSE REMOVE_CMAKE "${CMAKE_CURRENT_SOURCE_DIR}/cmake-build-debug/*")
list(REMOVE_ITEM files ${REMOVE_CMAKE})
add_executable(${PROJECT_NAME} ${files})