即使库已链接,CMake 可执行链接器错误

CMake executable linker error even though the libraries are linked

我是 CMake 的新手,但我已经遇到了一个我不明白的错误。

出于给定的原因,我有以下 C++ 设置:我有两个自己的静态库、多个外部静态库和一个可执行文件。我自己的库 a 定义了通用内容,所有外部库都被 link 编入其中。我的图书馆 b 定义了更多特殊的东西,并且有图书馆 a link 编入其中。最后,b 被 link 编辑到我的可执行文件 c 中。 bc都使用了不同外部库的函数,应该可以通过a.

看到

我有以下 CMakeLists.txt,我通过仅使用一个外部库来减少问题:ZeroC Ice。

根目录CMakeLists.txt

cmake_minimum_required (VERSION 3.3.0)
project (myproject)

# some settings
if (CMAKE_COMPILER_IS_GNUCC)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
endif (CMAKE_COMPILER_IS_GNUCC)
if (CMAKE_COMPILER_IS_GNUCXX)
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmessage-length=0")
endif (CMAKE_COMPILER_IS_GNUCXX)
set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})

# ZeroC Ice
find_package (Ice 3.6.0 REQUIRED COMPONENTS Ice IceUtil)
include_directories (${Ice_INCLUDE_DIRS})

# libraries and executable
add_subdirectory (a)
add_subdirectory (b)
add_subdirectory (c)

CMakeLists.txt 对于 a

set (a_FILES
    stuff.cpp
)
add_library (a STATIC ${a_FILES})

# link to third-party libraries
target_link_libraries (a PUBLIC
    ${Ice_LIBRARIES}
)

CMakeLists.txt 对于 b

set (b_FILES
    more_stuff.cpp
)
add_library (b STATIC ${b_FILES})

# link to a
target_link_libraries (b PUBLIC
    a
)

CMakeLists.txt 对于 c

set (c_FILES
    main.cpp
)
add_executable (c ${c_FILES})

# link to b
target_link_libraries (c PUBLIC
    b
)

在此示例中,stuff.cppmore_stuff.cppmain.cpp 使用 Ice 库中的 类。 a 甚至 b 编译和 link 都没有任何问题。只有 c 会抛出很多类似的 linker 错误:

C:/PROGRA~2/ZeroC/ICE-36~1.0/include/Ice/FactoryTableInit.h:27: undefined reference to `_imp___ZN11IceInternal16FactoryTableInitD1Ev'

对我来说,CMakeLists.txt 设置看起来很好,用谷歌搜索了好几天也没有任何改变。如果有任何帮助,我将不胜感激!

我正在使用 CMake 3.3.1 和 CMake Generator "Eclipse CDT4 - MinGW Makefiles"(g++ 版本 4.8.1)开发 Windows 10。

提前致谢! :)

编辑:

c 的 g++ linker 输出显示它试图 link 反对 liba.a libb.a C:/.../ice.lib C:/.../iceutil.lib,这对我来说似乎很好。无论如何,undefined reference linker 错误发生在 类 在 ice.lib 内部实现的头文件中,所以我不知道这里出了什么问题...

ab 是静态库,它们只是带有用于外部引用的符号的归档对象,没有 linking 发生。 c 是最终解析这些符号和 link 依赖关系的可执行文件。它看起来不像 CMake 向上传输 Ice 库 link,你可以尝试只 link 她的可执行文件。

我自己找到了一个"workaround":使用另一个CMake生成器。通过使用 Visual Studio 作为底层编译器和链接器,问题不会出现。问题似乎是混淆了 .lib.a 库。由于 windows 上的默认 Ice 安装仅提供 .lib 文件,我最终切换到 VS,一切正常。