I have simple project that mixes C and C++ (wrapping a C lib into a C++ class and making it easy to use in C++ project). The project was build with VisualStudio and I'm under Linux or Mac so I'd like to convert it in a CMake project.
The VS project content is full of
<ClInclude Include="a_file.h" />
so I think the file are just included without any complex build system. Here is my 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}
)
I know that is not a good rule to follow, but I just need a quick and dirty way to use this code.
Now, if I make with this test main.cpp:
#include <iostream>
int main(int argc, char *argv[]) {
std::cout << "main > ." << std::endl;
return 0;
}
I get a duplicate symbol error for 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)
As far as I get this CMakeCCompilerId.c file is something that cmake add for dealing with C...
So, here my question: what is the cmake-auto-added CMakeCCompilerId.c ? How can I compile a project with a main function that contains bot C and C++?
I resolved the problem just using
project(${PROJECTNAME} CXX)
instead of
project(${PROJECTNAME} C CXX)
But I'm curious anyway to understand it and how CMake mixes the two languages
The file(GLOB_RECURSE ${PROJECTNAME}_SOURCES ${CMAKE_SOURCE_DIR}/*.c) might be the reason of your issue.
CMake runs some checks on the compiler, and to do so, it generates some .c files and saves them in the build directory
If the build directory is a subdirectory of the main one, the second time that the GLOB_RECURSE runs, it will descend in the build directory, and therefore will add these cmake files in the ${PROJECTNAME}_SOURCES variable.
If your sources are all in the "src" directory, and your headers in the "header" directory, you can use
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)
And this should fix the issue, because it will not try to recurse in the build directory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With