4

我遇到的麻烦比我想象的要让 CMakesqlite3.dll在 Windows 7 上找到库(如果重要的话是 64 位)要多。我已经下载并放置了最新的sqlite3.dllsqlite3.def文件到C:\Windows\System32. 我正在使用FindSqlite3.cmake下面的模块:

IF( SQLITE3_INCLUDE_DIR AND SQLITE3_LIBRARY_RELEASE AND SQLITE3_LIBRARY_DEBUG )
    SET(SQLITE3_FIND_QUIETLY TRUE)
ENDIF( SQLITE3_INCLUDE_DIR AND SQLITE3_LIBRARY_RELEASE AND SQLITE3_LIBRARY_DEBUG )

FIND_PATH( SQLITE3_INCLUDE_DIR sqlite3.h )

FIND_LIBRARY(SQLITE3_LIBRARY_RELEASE NAMES sqlite3 )

FIND_LIBRARY(SQLITE3_LIBRARY_DEBUG NAMES sqlite3 sqlite3d HINTS /usr/lib/debug/usr/lib/ C:/Windows/System32/ )

IF( SQLITE3_LIBRARY_RELEASE OR SQLITE3_LIBRARY_DEBUG AND SQLITE3_INCLUDE_DIR )
SET( SQLITE3_FOUND TRUE )
ENDIF( SQLITE3_LIBRARY_RELEASE OR SQLITE3_LIBRARY_DEBUG AND SQLITE3_INCLUDE_DIR )

IF( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE )
# if the generator supports configuration types then set
# optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value
IF( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
SET( SQLITE3_LIBRARIES optimized ${SQLITE3_LIBRARY_RELEASE} debug ${SQLITE3_LIBRARY_DEBUG} )
ELSE( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
    # if there are no configuration types and CMAKE_BUILD_TYPE has no value
    # then just use the release libraries
SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_RELEASE} )
ENDIF( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
ELSEIF( SQLITE3_LIBRARY_RELEASE )
SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_RELEASE} )
ELSE( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE )
SET( SQLITE3_LIBRARIES ${SQLITE3_LIBRARY_DEBUG} )
ENDIF( SQLITE3_LIBRARY_DEBUG AND SQLITE3_LIBRARY_RELEASE )

IF( SQLITE3_FOUND )
IF( NOT SQLITE3_FIND_QUIETLY )
MESSAGE( STATUS "Found Sqlite3 header file in ${SQLITE3_INCLUDE_DIR}")
MESSAGE( STATUS "Found Sqlite3 libraries: ${SQLITE3_LIBRARIES}")
ENDIF( NOT SQLITE3_FIND_QUIETLY )
ELSE(SQLITE3_FOUND)
IF( SQLITE3_FIND_REQUIRED)
MESSAGE( FATAL_ERROR "Could not find Sqlite3" )
ELSE( SQLITE3_FIND_REQUIRED)
MESSAGE( STATUS "Optional package Sqlite3 was not found" )
ENDIF( SQLITE3_FIND_REQUIRED)
ENDIF(SQLITE3_FOUND)

这在 Linux 上运行良好,但在 Windows 上不行。我现在花了几个小时尝试对其他 CMAKE 变量进行小的更改,但没有成功。让 CMake 找到这个似乎应该是直截了当的dll。我可以得到一些帮助来找到 Windows 上的 sqlite3 库吗?

4

2 回答 2

10

这里有一些问题,还有一些奇怪的 Windows 东西!

首要问题; 在使用 MSVC 作为生成器的 Windows 上搜索库时,CMake 将始终查找“.lib”文件 - 从不查找“.dll”,即使您指定例如sqlite3.dll作为. 不幸的是,这没有正确记录,实际上文档错误地指出:NAMESfind_libraryCMAKE_FIND_LIBRARY_SUFFIXES

这指定 find_library 命令查找库时要添加到库名称的后缀。在 Windows 系统上,这通常是 .lib 和 .dll,这意味着当尝试查找 foo 库时,它将查找 foo.dll 等。

您可以轻松检查这一点;只需添加

message("CMAKE_FIND_LIBRARY_SUFFIXES:  ${CMAKE_FIND_LIBRARY_SUFFIXES}")

到您的 CMakeLists.txt。您应该看到如下输出:

CMAKE_FIND_LIBRARY_SUFFIXES:  .lib

CMake 邮件列表中的这个线程进一步证实了这种行为。如果您确实需要查找 dll,则需要使用该find_file命令,例如:

find_file(SQLITE3_DLL_DEBUG NAMES sqlite3d.dll PATHS ...)



下一个问题是一个小问题。如果它是硬编码的猜测,您应该更喜欢PATHS作为命令HINTS中的参数。find_xxx从文档中find_library

3. 搜索选项指定的路径HINTS。这些应该是由系统自省计算的路径,例如由已找到的另一个项目的位置提供的提示。应使用该PATHS选项指定硬编码猜测。



一个稍微更严重的问题是:

FIND_LIBRARY(SQLITE3_LIBRARY_DEBUG NAMES sqlite3 sqlite3d ...)

您应该先指定 sqlite3d ,然后如果两者都可用,则 sqlite3 或 sqlite3 将被错误地选择为调试库。



而现在的诡异...

在 Windows x64 系统上,find_xxx部分忽略 C:\Windows\System32 目录,而选择 C:\Windows\SysWOW64 目录。

如果 C:\Windows\SysWOW64 中没有 sqlite3.lib,那么无论参数find_library如何,该命令都会失败。PATHS

但是,如果您确实有 C:\Windows\SysWOW64\sqlite3.lib,那么C:/Windows/SysWOW64和/或C:/Windows/System32作为PATHS参数的任何组合都会找到该库,但C:/Windows/System32/sqlite3.lib 即使 C:/Windows/System32/sqlite3.lib 没有,也会将完整路径设置为不存在!如果图书馆不在那里,这显然是无用的。将导致链接器错误。

从这里的 CMake 邮件列表中有一些进一步的阅读。

话虽如此,如果您正在链接,您将使用 .lib 文件,而不是 .dll,并且 System32 和 SysWOW64 并不是 .lib 文件的真正位置。

于 2013-04-10T00:46:24.950 回答
0

我没有发现cmake寻找.lib。请

请检查cmake 文件并在cmake 文件夹中找到 Sqlite.cmake文件并检查它正在寻找的路径。

当我给出“ dll ”的完整路径时,它对我有用,对应于 cmake 文件中提到的输入变量,它也可能对你有用。

如果您的问题没有解决,请通知我编辑答案。

于 2019-12-06T05:42:36.697 回答