mingw32-make 使用"MinGW Makefiles"生成器跟踪 CMAKE 无法将可执行文件链接到对象库

mingw32-make following cmake with "MinGW Makefiles" generator fails to link executable to object library

本文关键字:可执行文件 链接 对象 跟踪 Makefiles MinGW 使用 mingw32-make CMAKE      更新时间:2023-10-16

我正在使用CMake来促进C++项目的跨平台构建。使用相同的CMakeLists.txt文件,我成功完成了Linux(生成Unix Makefiles以使用g ++编译(,OSX(生成Unix Makefiles以使用clang++编译(和Windows(为Visual Studio 16 2019生成(的构建。

最近,我一直在Windows上使用MinGW Makefiles生成器测试构建过程。CMake 生成生成文件没有任何问题。但是,当我在生成 Makefile 的目录中调用mingw32-make时,我开始遇到问题。我能够将多个源文件编译到一个对象库中,但是当我尝试将print_graphs可执行文件链接到此对象库时,我收到对象库的第一个源文件中方法的大量multiple definition错误,如下所示:

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
CMakeFilesprint_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x6833): multiple definition of `roaring_bitmap_get_copy_on_write'
CMakeFilesprint_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
CMakeFilesprint_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x6850): multiple definition of `roaring_bitmap_set_copy_on_write'
CMakeFilesprint_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
CMakeFilesprint_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'
CMakeFilesprint_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x65a1): first defined here
CMakeFilesprint_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'
CMakeFilesprint_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x660e): first defined here
CMakeFilesprint_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'
CMakeFilesprint_graphs.dir/objects.a(roaring.c.obj):roaring.c:(.text+0x688e): first defined here
CMakeFilesprint_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'
CMakeFilesprint_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]: *** [srcCMakeFilesprint_graphs.dirbuild.make:104: src/print_graphs.exe] Error 1
mingw32-make[1]: *** [CMakeFilesMakefile2:933: src/CMakeFiles/print_graphs.dir/all] Error 2
mingw32-make: *** [Makefile:94: all] Error 2

在我的 src/目录中的 CMakeLists.txt 文件中,我有以下基本代码:

# 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)

我是CMake的新手,所以我敢打赌这个问题是我在CMakeLists.txt文件中的糟糕形式。但是由于当我使用其他生成器时,CMake 能够毫无问题地构建所有内容,因此我不确定问题是什么。有谁知道可能导致MinGW制作文件生成器出现问题的原因?

好的,我发现了这个问题,正如预期的那样,这是我在 CMake 中的形式不好。在我的代码部分

# Combine the object source files into an object library:
add_library(objects OBJECT ${SOURCES} ${HEADERS})

没有必要引用${HEADERS},因为在接下来的几行中明确地建立了这种连接:

# Point the build targets to their include directories:
target_include_directories(objects PRIVATE ${HEADERS_DIR})

在初始add_library调用中包含对头文件的引用似乎会导致头文件重复(或至少重复对它们的引用(。

我仍然不确定为什么其他构建工具没有被这个问题绊倒,而mingw32-make是,但无论如何维护正确的语法都是很好的,而且现在事情正在按预期工作。