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

时间:2017-06-12 19:59:32

标签: windows cmake libuv

我试图将libuv导入我的CMake项目,以便我可以链接它。我从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中得到未定义的符号错误:

Error message

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

2 个答案:

答案 0 :(得分:1)

切勿在CMake中硬编码这样的库路径或名称。

而是使用find_library命令,如果提供的库出现问题,它可以提前通知您。

特别是在Windows上,由于没有库位于系统上的默认位置(类似于* nix系统上的/usr/local/lib),您可能希望为库提供额外的自定义点&#39的位置。我个人喜欢为此使用环境变量,但正常的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,导入的目标最有效。手动编写导入的目标在额外的复杂性方面通常不值得。

答案 1 :(得分:1)

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

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

如果有人知道为什么会出现此错误,请发表评论,以便日后帮助其他人更好地定位错误原因。