我有一个简单的项目,它混合使用C和C ++(将C lib包装到C ++类中,并使其易于在C ++项目中使用)。该项目是使用VisualStudio构建的,我在Linux或Mac下,所以我想在CMake项目中进行转换。
VS项目内容已满
<ClInclude Include="a_file.h" />
所以我认为该文件只是包含在内而没有任何复杂的构建系统。这是我的CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
# project
set(PROJECTNAME "Test")
project(${PROJECTNAME} C CXX)
set (CMAKE_CXX_FLAG "-Wall")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "./")
include_directories(${CMAKE_CURRENT_BINARY_DIR})
find_package(OpenCV REQUIRED)
file(GLOB_RECURSE ${PROJECTNAME}_HEADERS ${CMAKE_SOURCE_DIR}/*.h)
file(GLOB_RECURSE ${PROJECTNAME}_SOURCES ${CMAKE_SOURCE_DIR}/*.cpp)
file(GLOB_RECURSE ${PROJECTNAME}_SOURCES ${CMAKE_SOURCE_DIR}/*.c)
include_directories (include)
include_directories (src)
SET(${PROJECTNAME}_SOURCES
main.cpp
${${PROJECTNAME}_SOURCES}
)
ADD_EXECUTABLE(${PROJECTNAME}
${${PROJECTNAME}_SOURCES}
${${PROJECTNAME}_HEADERS}
)
我知道这不是一个好的规则,但我只需要一种快速而肮脏的方式来使用这段代码。
现在,如果我使用此测试main.cpp:
#include <iostream>
int main(int argc, char *argv[]) {
std::cout << "main > ." << std::endl;
return 0;
}
我收到CMakeCCompilerId.c的重复符号错误
duplicate symbol _main in:
CMakeFiles/Test.dir/main.cpp.o
CMakeFiles/Test.dir/CMakeFiles/2.8.12.2/CompilerIdC/CMakeCCompilerId.c.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
据我所知,这个CMakeCCompilerId.c文件是cmake为处理C而添加的...
所以,我的问题是:什么是cmake-auto-added CMakeCCompilerId.c?如何使用包含bot C和C ++的main函数编译项目?
我只是使用
解决了这个问题project(${PROJECTNAME} CXX)
而不是
project(${PROJECTNAME} C CXX)
但无论如何我很好奇理解它以及CMake如何混合两种语言
答案 0 :(得分:2)
file(GLOB_RECURSE ${PROJECTNAME}_SOURCES ${CMAKE_SOURCE_DIR}/*.c)
可能是您遇到问题的原因。
CMake对编译器运行一些检查,为此,它会生成一些.c文件并将它们保存在构建目录中
如果构建目录是主目录的子目录,第二次GLOB_RECURSE
运行,它将下降到构建目录中,因此会在$ {PROJECTNAME} _SOURCES变量中添加这些cmake文件
如果你的资源都在“src”目录中,而你的标题在“header”目录中,你可以使用
file(GLOB_RECURSE ${PROJECTNAME}_HEADERS ${CMAKE_SOURCE_DIR}/include/*.h)
file(GLOB_RECURSE ${PROJECTNAME}_SOURCES ${CMAKE_SOURCE_DIR}/src/*.cpp)
file(GLOB_RECURSE ${PROJECTNAME}_SOURCES ${CMAKE_SOURCE_DIR}/src/*.c)
这应该可以解决这个问题,因为它不会尝试在构建目录中进行递归。