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} PROPERTIES
OUTPUT_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

CMake构建学习笔记23-SQLite库的构建的更多相关文章

  1. C++学习笔记23:库

    静态库(Archives) 后缀一般为"*.a" 使用两个目标文件创建单一静态库的编译与链接命令:ar cr libtest.a  test1.o test2.o 链接器搜索静态库 ...

  2. Ext.Net学习笔记23:Ext.Net TabPanel用法详解

    Ext.Net学习笔记23:Ext.Net TabPanel用法详解 上面的图片中给出了TabPanel的一个效果图,我们来看一下代码: <ext:TabPanel runat="se ...

  3. 【学习笔记】开源库之 - sigslot (在解决浅拷贝问题的基础上增加信号拦截功能)

    前言说明 在文中<[学习笔记]开源库之 - sigslot (提供该库存在对象拷贝崩溃问题的解决方案)>已经介绍过 sigslot ,此文主要应用在实际的工作项目中时,发现会有拦截信号的需 ...

  4. iOS学习笔记16-数据库SQLite

    一.数据库 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等.离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式: 归档:NSKeyedArchiver 偏好设置:NSU ...

  5. SpringCloud学习笔记(6):使用Zuul构建服务网关

    简介 Zuul是Netflix提供的一个开源的API网关服务器,SpringCloud对Zuul进行了整合和增强.服务网关Zuul聚合了所有微服务接口,并统一对外暴露,外部客户端只需与服务网关交互即可 ...

  6. Java学习笔记之使用反射+泛型构建通用DAO

    PS:最近简单的学了学后台Servlet+JSP.也就只能学到这里了.没那么多精力去学SSH了,毕竟Android还有很多东西都没学完.. 学习内容: 1.如何使用反射+泛型构建通用DAO. 1.使用 ...

  7. [原创]java WEB学习笔记23:MVC案例完整实践(part 4)---模糊查询的设计与实现

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. Python学习笔记23:Django构建一个简单的博客网站(一个)

    在说如何下载和安装Django,本节将重点讨论如何使用Django站点. 一 新建project 命令:django-admin startproject mysite # 有的须要输入:django ...

  9. CMake学习笔记五-依赖库添加

    # # 项目名称 # SET(WIS_PROJECT_NAME EXAMPLE) # dependencies SET(DEPENDENCIES #依赖第三方库 ) #Qt模块 SET(QT_MODU ...

  10. 学习笔记_Java_day13_JSTL标签库(1、2、3、4、5、6、7、8)

    1.一种标签语言 day13 l  JSTL标签库(重点) l  自定义标签(理解) l  MVC设计模式(重点中的重点) l  Java三层框架(重点中的重点) JSTL标签库 1 什么是JSTL ...

随机推荐

  1. 证明:C++ std::shared_ptr的引用不会增加它的计数值

    #include <thread> #include <memory> #include <Windows.h> int main() { std::thread ...

  2. [Ynoi2014] 置身天上之森

    题传 其实做过由乃打扑克的话思路并不难.但写代码的时候把写由乃打扑克的 bug 全部复现了属实难蚌 注意到线段树不同区间长度是 \(O(\log n)\) 的,因此我们对于每种长度建一个序列,对于 1 ...

  3. Axios 简单使用

    axios({ method: "post", headers: { "Content-Type": "application/json" ...

  4. Redis、Spring Cache 、HttpClient基础

    Redis 基于内存的key-value的结构数据库,读写性能高,常用于存储热点数据(短时间大量访问) MySQL则是基于磁盘的二维表结构的数据库. Redis的使用 Redis中没有用户的概念,只有 ...

  5. 前端开发系列073-JQuery篇之源码核心

    本文介绍jQuery 源码的主体结构和关键细节. jQuery是前端开发中绕不开的一个框架,在React和Vue等框架出现前,jQuery无疑是前端开发主流技术栈中不可或缺的框架.它为我们提供了强大的 ...

  6. Wordpress自动设置第一段为摘要

    我们要修改formatting.php文件,文件的路径为.当然了,每个人的www文件夹位置都不一样,找到自己网站文件夹下面的wp-include文件夹就好. [root@localhost ~]# c ...

  7. Educational Codeforces Round 97 ABCD 题解

    A. Marketing Scheme 题意:对于一个x,如果\({\lfloor{x\over 2}\rfloor}\)<= \(x\) \(mod\) \(a\),则满足题意.现在问你能否选 ...

  8. 让 AI 帮我部署网站,太方便了!

    大家好,我是程序员鱼皮,今天分享一个用 AI 提升效率的神技巧~ 以前,我们开发一个网站,需要先提出需求.再设计方案.再写代码开发.最后部署上线.我们都知道 AI 现在写代码越来越溜了,慢慢地替代了我 ...

  9. 神奇的LLVM与llvmlite之JIT编译。

    https://releases.llvm.org/11.0.0/docs/LangRef.html llvmlite Documentation, Release 0.41.0dev0-64-gbb ...

  10. SoapUI使用教程-九五小庞

    一.简介SoapUI:常用的接口测试工具,掌握了能更好进行接口的开发. 二.Http接口调用1.创建项目 2.输入http请求地址 3.选择对应项目的request,输入信息发送请求 三.Webser ...