当前位置: 首页 > news >正文

CMake构建学习笔记23-SQLite库的构建

1. 构建思路

在前文中构建了大量的库包程序(参看CMake构建学习笔记-目录)之后,可以总结一下在Windows下使用脚本构建程序的办法:

  1. 使用CMake构建。这是目前最通用最流行的构建方式,大部分C/C++程序都在逐渐向这个方向转。
  2. 使用namke构建。在CMake流行之前,有的程序会提供MSVC项目文件,这种情况下可以使用namke来进行构建。
  3. 使用MSYS2/MinGW构建。适用于只提供了Linux环境构建方式的程序,不过可能会有二进制兼容问题,一般不推荐。
  4. 使用第三方的项目构建。比如自己组织CMake项目,或者使用vcpkg这样的库包管理工具直接安装。

2. 构建SQLite

SQLite是一个轻量级的、无需独立服务器进程的嵌入式关系型数据库。它将整个数据库(包括表、索引和数据)存储在一个单一的磁盘文件中,支持标准的SQL语法,广泛用于嵌入式设备、移动应用和小型Web项目。SQLite是一个老牌的C库,不提供CMake的构建方式,而且它还是个可执行程序而不仅仅是库,这给程序的集成带来一定的麻烦。

那么如何在Windows下将SQLite构建成库文件呢?这里选择第4种方案,根据源代码文件生成CMake项目。SQLite提供了一个很不错的特性,就是支持将所有的实现代码组合成一个sqlite.c文件,因此自己组织CMake项目就比较简单,组织结构如下:

project-root/
├── include/
│ ├── sqlite3.h
│ └── sqlite3ext.h
├── src/
│ └── sqlite3.c
├── CMakeLists.txt
├── CMakePresets.json
└── sqlite3.def

源代码sqlite.csqlite3.hsqlite3ext.h是SQLite的源代码文件,不用进行修改。需要注意的是SQLite提供两种源代码文件,一种是分散组织的,一种是组合成单文件的,一定要选择后者才能看到sqlite.c文件(比如sqlite-amalgamation-3460000.zip)。

另外,sqlite3.def是模块定义文件,为Windows的DLL模块定义各种属性和导出符号。如果是像笔者一样需要构建成动态库,那么这个文件一定要有。这个文件可以在SQLite提供预编译包种找到(比如sqlite-dll-win-x64-3460000)。

最后,CMakeLists.txt中的内容如下:

# 输出cmake版本提示
message(STATUS "The CMAKE_VERSION is ${CMAKE_VERSION}.")# cmake的最低版本要求
cmake_minimum_required (VERSION 3.10)# 工程名称、版本、语言
project(sqlite3 VERSION 3.4.6)# 支持当前目录
set(CMAKE_INCLUDE_CURRENT_DIR ON)# 判断编译器类型
message("CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}")# 判断编译器类型
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")message(">> using Clang")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")message(">> using GCC")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")message(">> using Intel C++")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")message(">> using Visual Studio C++")	  add_compile_options(/utf-8)
else()message(">> unknow compiler.")
endif()# 设置编译定义
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \
-DSQLITE_THREADSAFE=1 \
-DSQLITE_ENABLE_COLUMN_METADATA \
-DSQLITE_ENABLE_PREUPDATE_HOOK \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_GEOPOLY \
-DSQLITE_ENABLE_SESSION \
-DSQLITE_ENABLE_RBU")# 源代码文件
set(INCLUDE_FILES ./include/sqlite3.h./include/sqlite3ext.h
)
set(SOURCE_FILES./src/sqlite3.c${INCLUDE_FILES}
)# 动态库前缀与后缀
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")set(LibraryPrefix lib)set(LibraryPostfix so)
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")set(LibraryPrefix )set(LibraryPostfix lib)
ENDIF()# 将源代码添加到此项目的可执行文件。
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})if(CMAKE_SYSTEM_NAME MATCHES "Windows")   # 指定.def文件set_target_properties(${PROJECT_NAME} PROPERTIESOUTPUT_NAME ${PROJECT_NAME}LINK_FLAGS "/DEF:${CMAKE_CURRENT_SOURCE_DIR}/sqlite3.def")
endif()# TODO: 如有需要,请添加测试# 安装头文件到 include 目录
install(DIRECTORY include/ DESTINATION include)# 安装库文件到 lib 目录
install(TARGETS ${PROJECT_NAME}LIBRARY DESTINATION lib  # 对于共享库ARCHIVE DESTINATION lib  # 对于静态库RUNTIME DESTINATION bin  # 对于可执行文件
)

然后执行如下脚本指令:

cmake $SourceLocalPath `-B "$BuildDir" `-G "$Generator" `-A x64 `-DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo `-DCMAKE_INSTALL_PREFIX="$InstallDir"# 构建阶段,指定构建类型
cmake --build $BuildDir --config RelWithDebInfo# 安装阶段,指定构建类型和安装目标
cmake --build $BuildDir --config RelWithDebInfo --target install

即可完成编译、链接到安装的完整构建过程。$SourceLocalPath是源代码目录,也就是前面的CMake项目文件夹;$BuildDir是构建目录文件夹;"$Generator"是生成器,比如Visual Studio 16 2019


文章转载自:

http://blueD5oo.bsghk.cn
http://C1ogwXvR.bsghk.cn
http://h1dQ864Q.bsghk.cn
http://OGOWKePE.bsghk.cn
http://BGIt0HTG.bsghk.cn
http://270bIxfC.bsghk.cn
http://ReQoZydG.bsghk.cn
http://7iuptpVO.bsghk.cn
http://u9I4M2QD.bsghk.cn
http://tChHg8Ol.bsghk.cn
http://stBgsuKF.bsghk.cn
http://jTroRSJw.bsghk.cn
http://TqSor9E8.bsghk.cn
http://MLvYUvqZ.bsghk.cn
http://VtqTBLJj.bsghk.cn
http://458nL6Hi.bsghk.cn
http://LddDhRxA.bsghk.cn
http://PQRDCmKZ.bsghk.cn
http://t4o9057m.bsghk.cn
http://6wO6l5zj.bsghk.cn
http://zx1FM7aT.bsghk.cn
http://iKMUcZuy.bsghk.cn
http://ERK9oe78.bsghk.cn
http://bW1ybi2Z.bsghk.cn
http://9aBr9naE.bsghk.cn
http://gfVGq0Cf.bsghk.cn
http://E37jt1Kx.bsghk.cn
http://PqlwStEJ.bsghk.cn
http://hQc20Nko.bsghk.cn
http://IqWwO4ZV.bsghk.cn
http://www.dtcms.com/a/363591.html

相关文章:

  • SQL Server 数据库创建与用户权限绑定
  • 构建下一代智能金融基础设施
  • 网络编程 05:UDP 连接,UDP 与 TCP 的区别,实现 UDP 消息发送和接收,通过 URL 下载资源
  • 网络传输的实际收发情况及tcp、udp的区别
  • python 创建websocket教程
  • 异常处理小妙招——1.别把“数据库黑话”抛给用户:论异常封装的重要性
  • GitHub每日最火火火项目(9.2)
  • 使用谷歌ai models/gemini-2.5-flash-image-preview 生成图片
  • Python/JS/Go/Java同步学习(第一篇)格式化/隐藏参数一锅端 四语言输出流参数宇宙(附源码/截图/参数表/避坑指南/老板沉默术)
  • 下载速度爆表,全平台通用,免费拿走!
  • Linux中断实验
  • VibeVoice 部署全指南:Windows 下的挑战与完整解决方案
  • 为什么需要锁——多线程的数据竞争是怎么引发错误的
  • 梯度消失问题:深度学习中的「记忆衰退」困境与解决方案
  • 从C语言入门到精通:代码解析与实战
  • 零知开源——STM32红外通信YS-IRTM红外编解码器集成灯控与显示系统
  • Obsidian本地笔记工具:构建知识网络关联笔记,支持Markdown与插件生态及知识图谱生成
  • 95%企业AI失败?揭秘LangGraph+OceanBase融合数据层如何破局!​
  • 【前端面试题✨】Vue篇(一)
  • 【XR技术概念科普】什么是注视点渲染(Foveated Rendering)?为什么Vision Pro离不开它?
  • 使用gsoap实现简单的onvif服务器:1、编译
  • SpringBoot 整合 RabbitMQ 的完美实践
  • @ZooKeeper 详细介绍部署与使用详细指南
  • 网站搭建应该选择什么服务器?
  • 人体姿态估计与动作分类研究报告
  • 四.shell脚本编程
  • 在时间序列中增加一个阶跃对长期趋势变化的影响
  • 大批量文件管理操作的linux与windows系统命令行终端命令
  • Linux内核进程管理子系统有什么第四十回 —— 进程主结构详解(36)
  • 【网络安全入门基础教程】网络安全行业,未来两年就业和再就业都会很难