Correct usage of FindSQLite3 module in Windows

Hi all,

I’ve been using module FindSQLite3.cmake that comes bundled into CMake’s installation for finding SQLite3’s include dir and library under Linux and macOS. Recently, I’m working on porting one of those projects to Windows and ran into the issue that the module is not able to find SQLite3. So, my question is:

Can this module be used in Windows?

and if so

What additional configuration is required?

I’m wondering if the issue is related to where I installed SQLite’s binaries and sources. This is how my installation looks:

  • C:\sdk\sqlite-3.30.1
    • include\
      • shell.c
      • sqlite3.c
      • sqlite3.h
      • sqlite3ext.h
    • lib\
      • sqlite3.def
      • sqlite3.dll

I noticed that if in my CMakeList.txt file I set variables SQLite3_INCLUDE_DIR and SQLite3_LIBRARY to the corresponding paths matching my SQLite3 installation, the module executes with no errors but if I have to explicitly set those paths then to use the module makes no sense anymore. Nonetheless, I’m still calling the modules in order to keep my build cross-platform. This is the relevant part:

add_executable(sqlite-cache sqlite-cache/main.cpp)

  set(SQLite3_INCLUDE_DIR C:\\sdk\\sqlite-3.30.1\\include)
  set(SQLite3_LIBRARY_DIR C:\\sdk\\sqlite-3.30.1\\lib)
  set(SQLite3_LIBRARY sqlite3.dll)

find_package(SQLite3 REQUIRED)
target_include_directories(sqlite-cache PRIVATE ${SQLite3_INCLUDE_DIRS})
target_link_directories(sqlite-cache PRIVATE ${SQLite3_LIBRARY_DIR})
target_link_libraries(sqlite-cache ${SQLite3_LIBRARIES})

Thanks in advance!

Hmm. You seem to be missing a sqlite3.lib somewhere. On Windows, that is used for linking (the .dll is used at runtime). Unless that .def is supposed to be used instead, though I doubt that.

Hi Ben,

My understanding is that the .dll is required for both: linking and at runtime.

After looking closer at the FindSQLite3.cmake module’s source code and further investigating CMake commands find_path & find_library, which are used by the module to set variables SQLite3_INCLUDE_DIR & * SQLite3_LIBRARY* respectively, I came up with the following solution:

add_executable(sqlite-cache sqlite-cache/main.cpp)

  set(CMAKE_PREFIX_PATH C:\\sdk\\sqlite-3.30.1)

find_package(SQLite3 REQUIRED)
target_include_directories(sqlite-cache PRIVATE ${SQLite3_INCLUDE_DIRS})
target_link_libraries(sqlite-cache ${SQLite3_LIBRARIES})

According to the documentation of find_path and find_library commands, one of the steps of their search algorithm is to look inside paths specified in CMAKE_PREFIX_PATH; per these commands documentation will search for include paths as:

<prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and <prefix>/include for each <prefix> in CMAKE_PREFIX_PATH

and for libraries as:

<prefix>/lib/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and <prefix>/lib for each <prefix> in CMAKE_PREFIX_PATH

As you can see, the commands enforce that headers must be inside an include/ dir and libraries inside a lib/ dir and since my SQLite installation happens to have that format, then the solution above works. The search algorithm also looks in directories declared in system env vars like PATH and INCLUDE, but I prefer this approach since headers & libraries will be found faster.

That’s not how Windows linking works; just the .lib is necessary. Maybe SQLite is doing something weird to make the .dll suitable for the linker, but in general, they aren’t used at all.

That works, but the defaults for where it looks for headers and libraries is not set in stone (mostly taking issue with your use of “enforce” rather than “defaults to”). There are lots of libraries that do things like lib/x64 (TBB, OpenCV), have headers in lib (if they’re architecture-specific), or have their headers completely elsewhere (NumPy puts them beside the module files). CMake supports any of these with the appropriate SUFFIXES or other find_* arguments.