I'm using CMake to facilitate cross-platform builds of a C++ project. Using the same CMakeLists.txt files, I'm successfully completing builds on Linux (generating Unix Makefiles to compile with g++), OSX (generating Unix Makefiles to compile with clang++), and Windows (generating for Visual Studio 16 2019).
Most recently, I've been testing the build process using the MinGW Makefiles generator on Windows. CMake generates the Makefile without any problems. When I call mingw32-make
in the directory where the Makefile is generated, however, I start to run into problems. I'm able to compile several source files into an object library, but when I try to link the print_graphs executable to this object library, I get a flood of multiple definition
errors for methods in the first source file of the object library, as follows:
Scanning dependencies of target print_graphs
[ 52%] Building CXX object src/CMakeFiles/print_graphs.dir/print_graphs.cpp.obj
[ 57%] Linking CXX executable print_graphs.exe
CMakeFiles\print_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x6833): multiple definition of `roaring_bitmap_get_copy_on_write'
CMakeFiles\print_graphs.dir/objects.a(print_graphs.cpp.obj):print_graphs.cpp:(.text$roaring_bitmap_get_copy_on_write[roaring_bitmap_get_copy_on_write]+0x0): first defined here
CMakeFiles\print_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x6850): multiple definition of `roaring_bitmap_set_copy_on_write'
CMakeFiles\print_graphs.dir/objects.a(print_graphs.cpp.obj):print_graphs.cpp:(.text$roaring_bitmap_set_copy_on_write[roaring_bitmap_set_copy_on_write]+0x0): first defined here
CMakeFiles\print_graphs.dir/objects.a(set_cover_solver.cpp.obj):set_cover_solver.cpp:(.text$ra_get_index[ra_get_index]+0x0): multiple definition of `ra_get_index'
CMakeFiles\print_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x65a1): first defined here
CMakeFiles\print_graphs.dir/objects.a(set_cover_solver.cpp.obj):set_cover_solver.cpp:(.text$ra_get_container_at_index[ra_get_container_at_index]+0x0): multiple definition of `ra_get_container_at_index'
CMakeFiles\print_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x660e): first defined here
CMakeFiles\print_graphs.dir/objects.a(set_cover_solver.cpp.obj):set_cover_solver.cpp:(.text$roaring_bitmap_add_range[roaring_bitmap_add_range]+0x0): multiple definition of `roaring_bitmap_add_range'
CMakeFiles\print_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x688e): first defined here
CMakeFiles\print_graphs.dir/objects.a(set_cover_solver.cpp.obj):set_cover_solver.cpp:(.text$roaring_bitmap_contains[roaring_bitmap_contains]+0x0): multiple definition of `roaring_bitmap_contains'
CMakeFiles\print_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x690a): first defined here
collect2.exe: error: ld returned 1 exit status
mingw32-make[2]: *** [src\CMakeFiles\print_graphs.dir\build.make:104: src/print_graphs.exe] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:933: src/CMakeFiles/print_graphs.dir/all] Error 2
mingw32-make: *** [Makefile:94: all] Error 2
In the CMakeLists.txt file in my src/ directory, I have the following basic code:
# Add header files:
set(HEADERS
${HEADERS_DIR}/cxxopts.h
${HEADERS_DIR}/roaring.h
${HEADERS_DIR}/roaring.hh
${HEADERS_DIR}/pugiconfig.h
${HEADERS_DIR}/pugixml.h
...
)
# Add object source files:
set(SOURCES
roaring.c
pugixml.cpp
...
)
# Combine the object source files into an object library:
add_library(objects OBJECT ${SOURCES} ${HEADERS})
# Point the build targets to their include directories:
target_include_directories(objects PRIVATE ${HEADERS_DIR})
# Add all executable scripts to be generated:
add_executable(program1 $<TARGET_OBJECTS:objects> program1.cpp )
# Point the build targets to their include directories:
target_include_directories(program1 PRIVATE ${HEADERS_DIR})
# Make sure the build targets are compiled with C++11:
target_compile_features(program1 PRIVATE cxx_std_11)
I'm new to CMake, so I'm willing to bet that the issue is bad form on my part in the CMakeLists.txt file. But since CMake is able to build everything without problems when I use other generators, I'm not sure what the issue is. Does anyone know what might be causing the issue with the MinGW Makefiles generator in particular?
target_link_libraries(program1 objects)
to link object files? - arrowdVERBOSE=1
option tomingw32-make
for see actual command line used for linking. Check that this command line actually contains duplicate object files. - Tsyvarevmingw32-make
with theVERBOSE=1
option, and I got the following commands before the multiple definition errors: - Joey McCollum"C:\Program Files\CMake\bin\cmake.exe" -E remove -f CMakeFiles\print_graphs.dir/objects.a
C:\ProgramData\chocolatey\bin\ar.exe cr CMakeFiles\print_graphs.dir/objects.a @CMakeFiles\print_graphs.dir\objects1.rsp
C:\ProgramData\chocolatey\bin\g++.exe -Wl,--whole-archive CMakeFiles\print_graphs.dir/objects.a -Wl,--no-whole-archive -o print_graphs.exe -Wl,--out-implib,libprint_graphs.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\print_graphs.dir\linklibs.rsp
The only thing that strikes me is that the path toar
andg++
is through chocolatey, not mingw. - Joey McCollumobjects.a
gets built, and then it is referenced for linking. - Joey McCollum