在CMake中混合C和C ++,CMakeCCompilerId.c是什么以及如何丢弃它

时间:2014-02-12 18:55:30

标签: c++ c cmake

我有一个简单的项目,它混合使用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如何混合两种语言

1 个答案:

答案 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)

这应该可以解决这个问题,因为它不会尝试在构建目录中进行递归。