CMake Imported Library Target 在 Windows 上提供未定义的未定义符号

CMake Imported Library Target giving undefined giving undefined symbols on Windows

我正在尝试将 libuv 导入到我的 CMake 项目中,这样我就可以 link 它了。我从 here 安装了 libuv 1.12.0 并将它放在 C:\Program Files\libuv\.

project(tls-server LANGUAGES C)
set(LIBUV_ROOT_DIR "C:\Program Files\libuv")
add_library(libuv SHARED IMPORTED)
set_property(TARGET libuv PROPERTY IMPORTED_LOCATION "${LIBUV_ROOT_DIR}\libuv.dll")
set_property(TARGET libuv PROPERTY IMPORTED_IMPLIB "${LIBUV_ROOT_DIR}\libuv.lib")
add_executable(tls-server "${CMAKE_SOURCE_DIR}/src/main.c")
target_link_libraries(tls-server libuv)

但是,鉴于上面的代码,我仍然在 Visual Studio:

中遇到未定义的符号错误

我该如何解决这个问题?我相信路径都是正确的。我也在使用 Windows 10.

切勿在 CMake 中对库路径或名称进行硬编码。

而是使用 find_library 命令,如果提供的库出现问题,它会尽早通知您。

特别是在 Windows 上,因为系统上没有库所在的默认位置(类似于 *nix 系统上的 /usr/local/lib),您可能需要提供额外的自定义指向图书馆的位置。我个人喜欢为此使用环境变量,但普通的 CMake 选项也可以:

project(tls-server LANGUAGES C)

find_library(LIBUV_LIBRARIES NAMES uv libuv 
     HINTS $ENV{LIBUV_ROOT})

add_executable(tls-server ${PROJECT_SOURCE_DIR}/src/main.c)
target_link_libraries(tls-server ${LIBUV_LIBRARIES})

请注意,CMake 通常不会将运行时依赖项复制到正确的位置!也就是说,如果 libuv 是作为 .dll 构建的,您必须确保 运行 程序时 .dll 位于正确的路径中。

您当然可以在 CMake 中手动插入一个复制命令,以将所有 dll 放置到位,但这可能非常麻烦。不幸的是,目前没有更舒适的解决方案来解决这个问题。

在这里使用导入的目标是可能的,但只有在您需要将更复杂的属性传递给依赖目标时才真正有回报。根据我的经验,如果依赖项提供 fully-fledged package config file,则导入的目标效果最好。就额外的复杂性而言,手动编写导入的目标通常不值得麻烦。

我终于解决了问题。

首先,我从目标库 (libuv) 重新安装了二进制文件。然后,我确保我的 cmake 正在使用 cmake -G "Visual Studio 14 2015 Win64" 生成 x64 项目文件。这足以消除未定义的符号错误。然后我需要做的就是将 libuv.dll 文件复制到与可执行文件相同的目录,一切 运行 都很好。

如果有人知道为什么会出现这个错误,请发表评论,以便您以后可以帮助其他人更好地找出错误的原因。