CMake导入的库目标在Windows上提供未定义的给定未定义的符号

CMake导入的库目标在Windows上提供未定义的给定未定义的符号,windows,cmake,libuv,Windows,Cmake,Libuv,我正在尝试将libuv导入到我的CMake项目中,以便链接它。我已从安装了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导入到我的CMake项目中,以便链接它。我已从安装了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中硬编码库路径或名称

相反,使用命令,如果所提供的库出现问题,它可以很早通知您

特别是在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中手动插入一个copy命令,以使所有DLL就位,但这可能非常麻烦。不幸的是,目前没有更舒适的解决方案


在这里使用导入的目标是可能的,但只有当您需要将更复杂的属性传递给依赖的目标时,才会真正获得回报。根据我的经验,如果依赖项提供了。由于额外的复杂性,手动编写导入的目标通常不值得费心。

我终于设法解决了这个问题

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


如果有人知道发生此错误的原因,请发表评论,以便将来帮助其他人更好地找到错误原因。

您不能在MinGW上使用
.lib
文件
.lib
用于Visual Studio编译器和链接器,但MinGW及其gcc需要
.a
(或
.dll.a
)。使用纯C语言,可以从
.def
文件创建
.a
。@Tsyvarev我明白了。然而,我在使用VisualStudioGenerator时遇到了同样的错误。这篇文章如何帮助解决这个问题(“未定义的引用”)?改进问题中的代码是一个良好的意图,但这并不是本文的主要目的。最近我在meta上看到了相关问题。@Tsyvarev未定义的引用未被检测到,因为CMake不检查硬编码路径。通过改进代码,底层的is问题作为副作用得到了解决,这比痛苦地调试问题,同时保持损坏的CMake不变要好得多。StackOverflow不是一个免费的调试服务。实际上,您的代码与问题帖子中的代码做的是相同的(至少对于Visual Studio是这样)。指定提示或路径只是硬编码路径的跨平台方式:这只允许自动选择库的前缀/后缀。(假设您没有安装库的系统)
StackOverflow不是免费的调试服务。
-这适用于“没有任何注释的代码束”的情况。事实上,我猜90%以上的问题都是关于检测现有代码中的问题。@Tsyvarev好吧,它确实消除了我们意外混合使用MinGW和VS工具链的情况,以及库文件不在硬编码位置的情况。在那之后,没有太多仍然会出错的问题,当然也没有什么可以不借助一些猜测来解决的问题。
。。。如果不进行大量的猜测,就无法解决任何问题。
-您可以在问题帖子的评论中要求提供更多信息。当然,在有些问题上,请求额外信息不是一个选项,因此我们关闭它们。但在给定的问题中,作者能够(不知何故他熟悉他使用的工具)并希望(已经有一些额外的信息)提供目前缺失的信息。顺便说一句,一些问题的许多有效答案实际上是“猜测”的结果。