本节讨论构建 Connector/C++ 应用程序时需要牢记的一般注意事项。有关适用于特定平台的信息,请参阅 第 5.2 节“构建 Connector/C++ 应用程序:平台特定注意事项” 中适用于您平台的章节。
此处显示的命令来自命令行(例如,从 Makefile
调用)。这些命令适用于支持 make 和命令行构建工具(如 g++、cc 或 clang)的任何平台,但可能需要根据您的构建环境进行调整。
用于构建 Connector/C++ 应用程序的工具必须与用于构建 Connector/C++ 本身的工具兼容,这一点非常重要。理想情况下,使用与构建 Connector/C++ 二进制文件相同的工具构建您的应用程序。
为了避免问题,请确保您的应用程序和 Connector/C++ 本身在以下方面保持一致
编译器版本。
运行时库。
运行时链接器配置设置。
为了避免潜在的崩溃,Connector/C++ 的构建配置应与使用它的应用程序的构建配置匹配。例如,不要将 Connector/C++ 的发行版构建与客户端应用程序的调试版构建一起使用。
要使用不同的编译器版本、发行版配置或运行时库,请首先使用您想要的设置从源代码构建 Connector/C++(请参阅 第 4 章,从源代码安装 Connector/C++),然后使用相同的设置构建您的应用程序。
Connector/C++ 二进制发行版包含一个 INFO_BIN
文件,该文件描述了用于构建发行版的环境和配置选项。如果您从二进制发行版安装了 Connector/C++,并在某个平台上遇到构建相关问题,则检查用于在该平台上构建发行版的设置可能会有所帮助。二进制发行版还包含一个 INFO_SRC
文件,该文件提供有关产品版本和生成发行版的源代码存储库的信息。(在 Connector/C++ 8.0.14 之前,请查找 BUILDINFO.txt
而不是 INFO_BIN
和 INFO_SRC
。)
X DevAPI 使用 C++17 语言功能(从 Connector/C++ 8.0.33 开始)。要编译使用 X DevAPI 的 Connector/C++ 应用程序,请使用 -std=c++17
选项在编译器中启用 C++17 支持。此选项对于使用 X DevAPI for C(这是纯 C API)或传统 JDBC API(基于纯 C++)的应用程序来说是不必要的,除非应用程序代码使用 C++17。
应用程序使用的 API 决定了它应该包含哪些 Connector/C++ 头文件。以下包含指令假设包含路径包含 $MYSQL_CPPCONN_DIR/include
,其中 $MYSQL_CPPCONN_DIR
是 Connector/C++ 安装位置。在编译器调用命令上传递 -I $MYSQL_CPPCONN_DIR/include
选项以确保这一点。
-
对于使用 X DevAPI 的应用程序
#include <mysqlx/xdevapi.h>
-
对于使用 X DevAPI for C 的应用程序
#include <mysqlx/xapi.h>
-
对于使用传统 JDBC API 的应用程序,头文件是版本相关的
-
从 Connector/C++ 8.0.16 开始,单个
#include
指令就足够了#include <mysql/jdbc.h>
-
在 Connector/C++ 8.0.16 之前,使用以下
#include
指令集#include <jdbc/mysql_driver.h> #include <jdbc/mysql_connection.h> #include <jdbc/cppconn/*.h>
符号
<jdbc/cppconn/*.h>
表示您应该包含来自jdbc/cppconn
目录的所有应用程序需要的头文件。所需的特定文件取决于应用程序。 -
使用 Connector/C++ 1.1 的传统代码具有以下形式的
#include
指令#include <mysql_driver.h> #include <mysql_connection.h> #include <cppconn/*.h>
要使用 Connector/C++ 8.0 构建此类代码而无需修改它,请将
$MYSQL_CPPCONN_DIR/include/jdbc
添加到包含路径中。
-
要编译打算静态链接到 Connector/C++ 的代码,请定义一个宏,该宏会调整头文件中的 API 声明以供静态库使用。有关详细信息,请参阅 使用 Connector/C++ 静态库。
从 Connector/C++ 8.0.30 开始,版本相关的宏在公共头文件中定义。这些宏的目的是提供一种系统化且可预测的方式来维护 Connector/C++ 产品的版本号。下表描述了版本相关的宏。
宏名称 | 描述 |
---|---|
MYSQL_CONCPP_VERSION_MAJOR |
产品版本的重大版本号;当前为 8。 |
MYSQL_CONCPP_VERSION_MINOR |
产品版本的次要版本号;当前为 00。 |
MYSQL_CONCPP_VERSION_MICRO |
产品版本的微版本号;最初为 30。 |
MYSQL_CONCPP_VERSION_NUMBER |
完整的 Connector/C++ 版本号,它结合了重大版本号、次要版本号和微版本号。例如,组合版本号 8000030 表示 Connector/C++ 8.0.30。 |
这些宏维护的版本号仅适用于 Connector/C++ 产品,与 API 或 ABI 版本无关,这些版本由单独的机制处理。
使用 X DevAPI、X DevAPI for C 或传统 JDBC API 的 Connector/C++ 应用程序可以指定 MYSQL_CONCPP_VERSION_NUMBER
宏来添加条件测试,根据哪个 Connector/C++ 版本引入了依赖项来确定包含或排除功能依赖项。例如,可以在以下情况下使用 MYSQL_CONCPP_VERSION_NUMBER
宏
-
当 Connector/C++ 应用程序需要一个守卫来检查在指定版本之后引入的功能时。以下示例指定版本 8.0.32,该版本在公共头文件中定义了宏。相同的条件编译指令在宏未定义(使用 8.0.30 之前的头文件)时也起作用,因为该值被视为 0。
#if MYSQL_CONCPP_VERSION_NUMBER > 8000032 // use some 8.0.32+ feature #endif
-
当 Connector/C++ 应用程序需要在指定版本之前引入的所有功能时。
#if MYSQL_CONCPP_VERSION_NUMBER < 8000032 // this usage is OK; it compiles with 8.0.31 and all previous versions #endif
-
当使用 X DevAPI 的 Connector/C++ 应用程序还使用
CharacterSet::utf8mb3
枚举常量或任何新的utf8mb4
排序成员时。如果应用程序使用 8.0.30 之前的连接器进行编译,那么可以保护使用这些新 API 元素。#if MYSQL_CONCPP_VERSION_NUMBER >= 8000030 if (CharacterSet::utf8mb3 == cs) #else if (CharacterSet::utf8 == cs) #endif { // cs is the id of the utf8 character set }
-
当使用 X DevAPI 的 Connector/C++ 应用程序需要检查
utf8mb3
字符集或其任何排序的名称时,并且它也必须使用 8.0.30 之前的连接器进行编译。#if MYSQL_CONCPP_VERSION_NUMBER >= 8000030 if ("utf8mb3" == characterSetName(cs)) #else if ("utf8" == characterSetName(cs)) #endif { // cs is the id of the utf8 character set }
注意或者,您可以与数值枚举常量的值进行比较,这应该与连接器版本无关。
-
当使用传统 JDBC API 的 Connector/C++ 应用程序需要检查
utf8mb3
字符集或其任何排序的名称时,并且它也必须使用 8.0.30 之前的连接器进行编译。#if MYSQL_CONCPP_VERSION_NUMBER >= 8000030 if ("utf8mb3" == metadata->getColumnCharset(column)) #else if ("utf8" == metadata->getColumnCharset(column)) #endif { // column is the column index using the utf8 character set }
不要使用 MYSQL_CONCPP_VERSION_NUMBER
宏来检查 8.0.30 之前的版本,这会导致不可靠的结果。例如
#if MYSQL_CONCPP_VERSION_NUMBER > 8000028
// this does not compile the with 8.0.29 connector!
#endif
#if MYSQL_CONCPP_VERSION_NUMBER < 8000028
// this compiles with the 8.0.29 connector!
#endif
在以下情况下需要 Boost 头文件
在 Connector/C++ 8.0.16 之前,在 Unix 和类 Unix 平台上,对于使用 X DevAPI 或 X DevAPI for C 的应用程序,如果您使用 gcc 进行构建,并且系统上的 C++ 标准库版本未实现 UTF8 转换器 (
codecvt_utf8
)。在 Connector/C++ 8.0.23 之前,要编译使用传统 JDBC API 的 Connector/C++ 应用程序。
如果需要 Boost 头文件,则必须安装 Boost 1.59.0 或更高版本,并且必须将头文件的路径添加到包含路径中。要获取 Boost 及其安装说明,请访问 Boost 官方网站。
运行使用共享 Connector/C++ 库的应用程序时,动态链接器必须找到该库及其运行时依赖项。动态链接器必须正确配置才能找到 Connector/C++ 库及其依赖项。这包括在编译/链接命令中显式添加 -lresolv
。
使用 OpenSSL 构建 Connector/C++ 会使连接器库依赖于 OpenSSL 动态库。在这种情况下
将应用程序动态链接到 Connector/C++ 时,此依赖项仅在运行时才相关。
将应用程序静态链接到 Connector/C++ 时,也链接到 OpenSSL 库。在 Linux 上,这意味着在编译/链接命令中显式添加
-lssl -lcrypto
。在 Windows 上,这会自动处理。
在 Windows 上,链接到 C++ 运行时库的动态版本。
X DevAPI for C 应用程序在运行时需要 libstdc++
。根据您的平台或构建工具,可能使用不同的库。例如,该库在 macOS 上是 libc++
;请参阅 第 5.2.2 节“macOS 说明”。
如果应用程序使用动态链接库构建,那么这些库不仅必须存在于构建主机上,还必须存在于应用程序运行的目标主机上。动态链接器必须正确配置才能找到这些库及其运行时依赖项,以及找到 Connector/C++ 库及其运行时依赖项。
Oracle 构建的 Connector/C++ 库依赖于 OpenSSL 库。为了运行链接到 Connector/C++ 库的代码,必须在系统上安装 OpenSSL 库。另一种选择是将 OpenSSL 库放在与 Connector/C++ 相同的位置,在这种情况下,动态链接器应该可以在连接器库旁边找到它们。另请参见 第 5.2.1 节,“Windows 说明”,以及 第 5.2.2 节,“macOS 说明”。
从 Connector/C++ 8.0.28 开始,不再支持 TLSv1 和 TLSv1.1 连接协议,TLSv1.2 是最早支持的连接协议。
Connector/C++ 动态库名称取决于平台。这些库实现了 X DevAPI 和 X DevAPI for C,其中库名称中的 A
代表 ABI 版本
libmysqlcppconn8.so.
(Unix)A
libmysqlcppconn8.
(macOS)A
.dylibmysqlcppconn8-
,包含导入库A
-vsNN
.dllvs
(Windows)NN
/mysqlcppconn8.lib
对于传统 JDBC API,动态库的命名方式如下,其中库名称中的 B
代表 ABI 版本
libmysqlcppconn.so.
(Unix)B
libmysqlcppconn.
(macOS)B
.dylibmysqlcppconn-
,包含导入库B
-vsNN
.dllvs
(Windows)NN
/mysqlcppconn-static.lib
在 Windows 上,库名称中的 vs
值取决于用于构建库的 MSVC 工具链版本。(Oracle 提供的 Connector/C++ 库使用 NN
vs14
,并且与 MSVC 2019 和 2017 兼容。)这种约定允许在同一系统上使用不同版本的 MSVC 构建的库。另请参见 第 5.2.1 节,“Windows 说明”。
要构建使用 X DevAPI 或 X DevAPI for C 的代码,请将 -lmysqlcppconn8
添加到链接器选项。要构建使用传统 JDBC API 的代码,请添加 -lmysqlcppconn
。
您还必须通过指定相应的库目录来指示是否使用 64 位或 32 位库。使用 -L
链接器选项指定 $MYSQL_CONCPP_DIR/lib64
(64 位库)或 $MYSQL_CONCPP_DIR/lib
(32 位库),其中 $MYSQL_CPPCONN_DIR
是 Connector/C++ 的安装位置。在 FreeBSD 上,/lib64
未使用。库名称始终以 /lib
结尾。
要构建一个使用 X DevAPI 的 Connector/C++ 应用程序,其源代码位于 app.cc
中,并动态链接到连接器库,Makefile
可能如下所示
MYSQL_CONCPP_DIR = Connector/C++ installation location
CPPFLAGS = -I $(MYSQL_CONCPP_DIR)/include -L $(MYSQL_CONCPP_DIR)/lib64
LDLIBS = -lmysqlcppconn8
CXXFLAGS = -std=c++17
app : app.cc
使用该 Makefile
,命令 make app 会生成以下编译器调用
g++ -std=c++17 -I .../include -L .../lib64 app.cc -lmysqlcppconn8 -o app
要构建一个使用 X DevAPI for C 的普通 C 应用程序,其源代码位于 app.c
中,并动态链接到连接器库,Makefile
可能如下所示
MYSQL_CONCPP_DIR = Connector/C++ installation location
CPPFLAGS = -I $(MYSQL_CONCPP_DIR)/include -L $(MYSQL_CONCPP_DIR)/lib64
LDLIBS = -lmysqlcppconn8
app : app.c
使用该 Makefile
,命令 make app 会生成以下编译器调用
cc -I .../include -L .../lib64 app.c -lmysqlcppconn8 -o app
生成的代码,即使它被编译为普通的 C 代码,也依赖于 C++ 运行时(通常是 libstdc++
,但这可能因平台或构建工具而异;请参见 运行时库)。
要构建一个使用传统 JDBC API 的普通 C++ 应用程序,其源代码位于 app.c
中,并动态链接到连接器库,Makefile
可能如下所示
MYSQL_CONCPP_DIR = Connector/C++ installation location
CPPFLAGS = -I $(MYSQL_CONCPP_DIR)/include -L $(MYSQL_CONCPP_DIR)/lib64
LDLIBS = -lmysqlcppconn
app : app.c
在这种情况下,库选项是 -lmysqlcppcon
,而不是 X DevAPI 或 X DevAPI for C 应用程序的 -lmysqlcppcon8
。
使用该 Makefile
,命令 make app 会生成以下编译器调用
cc -I .../include -L .../lib64 app.c -lmysqlcppconn -o app
运行使用 Connector/C++ 动态库的应用程序时,动态链接器必须找到该库及其运行时依赖项。请参见 运行时库。
可以将您的应用程序与 Connector/C++ 静态库链接。这样一来,就不会有对连接器的运行时依赖关系,生成的二进制文件可以在未安装 Connector/C++ 的系统上运行。
即使是静态链接,生成的代码仍然依赖于 Connector/C++ 库的所有运行时依赖关系。例如,如果 Connector/C++ 使用 OpenSSL 构建,那么该代码就会有对 OpenSSL 库的运行时依赖关系。请参见 运行时库。
Connector/C++ 静态库名称取决于平台。这些库实现了 X DevAPI 和 X DevAPI for C
libmysqlcppconn8-static.a
(Unix, macOS)vs
(Windows)NN
/mysqlcppconn8-static.lib
对于传统 JDBC API,静态库的命名方式如下
libmysqlcppconn-static.a
(Unix, macOS)vs
(Windows)NN
/mysqlcppconn-static.lib
通用 Linux 包不包含任何 Connector/C++ 静态库。如果您打算将您的应用程序链接到静态库,请考虑安装一个特定于您构建最终应用程序的平台的包。
在 Windows 上,库名称中的 vs
值取决于用于构建库的 MSVC 工具链版本。(Oracle 提供的 Connector/C++ 库使用 NN
vs14
,并且与 MSVC 2019 和 2017 兼容。)这种约定允许在同一系统上使用不同版本的 MSVC 构建的库。另请参见 第 5.2.1 节,“Windows 说明”。
要编译打算静态链接到 Connector/C++ 的代码,请定义一个宏,该宏会调整头文件中的 API 声明以供静态库使用。定义宏的一种方法是在编译器调用命令中传递一个 -D
选项
对于使用 X DevAPI、X DevAPI for C 或(从 Connector/C++ 8.0.16 开始)传统 JDBC API 的应用程序,请定义
STATIC_CONCPP
宏。重要的是您要定义它;该值无关紧要。例如:-DSTATIC_CONCPP
在 Connector/C++ 8.0.16 之前,对于使用传统 JDBC API 的应用程序,请将
CPPCONN_PUBLIC_FUNC
宏定义为一个空字符串。要确保这一点,请将宏定义为CPPCONN_PUBLIC_FUNC=
,而不是CPPCONN_PUBLIC_FUNC
。例如:-DCPPCONN_PUBLIC_FUNC=
要构建一个使用 X DevAPI 的 Connector/C++ 应用程序,其源代码位于 app.cc
中,并静态链接到连接器库,Makefile
可能如下所示
MYSQL_CONCPP_DIR = Connector/C++ installation location
CPPFLAGS = -DSTATIC_CONCPP -I $(MYSQL_CONCPP_DIR)/include
LDLIBS = $(MYSQL_CONCPP_DIR)/lib64/libmysqlcppconn8-static.a -lssl -lcrypto -lpthread
CXXFLAGS = -std=c++17
app : app.cc
使用该 Makefile
,命令 make app 会生成以下编译器调用
g++ -std=c++17 -DSTATIC_CONCPP -I .../include app.cc
.../lib64/libmysqlcppconn8-static.a -lssl -lcrypto -lpthread -o app
为了避免链接器报告未解析的符号,编译行必须包含 Connector/C++ 代码依赖的 OpenSSL 库和 pthread
库。
如果 Connector/C++ 在没有 OpenSSL 的情况下构建,则不需要 OpenSSL 库,但是 Oracle 构建的 Connector/C++ 发行版确实依赖于 OpenSSL。
Connector/C++ 库所需的库的准确列表取决于平台。例如,在 Solaris 上,可能需要 socket
、rt
和 nsl
库。
要构建一个使用 X DevAPI for C 的普通 C 应用程序,其源代码位于 app.c
中,并静态链接到连接器库,Makefile
可能如下所示
MYSQL_CONCPP_DIR = Connector/C++ installation location
CPPFLAGS = -DSTATIC_CONCPP -I $(MYSQL_CONCPP_DIR)/include
LDLIBS = $(MYSQL_CONCPP_DIR)/lib64/libmysqlcppconn8-static.a -lssl -lcrypto -lpthread
app : app.c
使用该 Makefile
,命令 make app 会生成以下编译器调用
cc -DSTATIC_CONCPP -I .../include app.c
.../lib64/libmysqlcppconn8-static.a -lssl -lcrypto -lpthread -o app
要构建一个使用传统 JDBC API 的普通 C 应用程序,其源代码位于 app.c
中,并静态链接到连接器库,Makefile
可能如下所示
MYSQL_CONCPP_DIR = Connector/C++ installation location
CPPFLAGS = -DCPPCONN_PUBLIC_FUNC= -I $(MYSQL_CONCPP_DIR)/include
LDLIBS = $(MYSQL_CONCPP_DIR)/lib64/libmysqlcppconn-static.a -lssl -lcrypto -lpthread
app : app.c
在这种情况下,库选项命名为 libmysqlcppcon-static.a
,而不是 X DevAPI 或 X DevAPI for C 应用程序的 libmysqlcppcon8-static.a
。
使用该 Makefile
,命令 make app 会生成以下编译器调用
cc -std=c++17 --DCPPCONN_PUBLIC_FUNC= -I .../include app.c
.../lib64/libmysqlcppconn-static.a -lssl -lcrypto -lpthread -o app
构建纯 C 代码时,务必注意连接器对 C++ 运行时的依赖关系,即使使用它的代码是纯 C 代码,这种依赖关系也是由连接器库引入的。
-
一种方法是确保使用 C++ 链接器来构建最终代码。这里显示的
Makefile
采用了这种方法MYSQL_CONCPP_DIR = Connector/C++ installation location CPPFLAGS = -DSTATIC_CONCPP -I $(MYSQL_CONCPP_DIR)/include LDLIBS = $(MYSQL_CONCPP_DIR)/lib64/libmysqlcppconn8-static.a -lssl -lcrypto -lpthread LINK.o = $(LINK.cc) # use C++ linker app : app.o
使用该
Makefile
,构建过程分两步:首先使用纯 C 编译器编译app.c
中的应用程序源代码以生成app.o
,然后使用 C++ 链接器链接最终的可执行文件 (app
),它会处理对 C++ 运行时的依赖关系。这些命令看起来像这样cc -DSTATIC_CONCPP -I .../include -c -o app.o app.c g++ -DSTATIC_CONCPP -I .../include app.o .../libmysqlcppconn8-static.a -lssl -lcrypto -lpthread -o app
-
另一种方法是使用纯 C 编译器和链接器,但是将
libstdc++
C++ 运行时库作为显式选项添加到链接器中。这里显示的Makefile
采用了这种方法MYSQL_CONCPP_DIR = Connector/C++ installation location CPPFLAGS = -DSTATIC_CONCPP -I $(MYSQL_CONCPP_DIR)/include LDLIBS = $(MYSQL_CONCPP_DIR)/lib64/libmysqlcppconn8-static.a -lssl -lcrypto -lpthread -lstdc++ app : app.c
使用该
Makefile
,编译器会按如下方式调用cc -DSTATIC_CONCPP -I .../include app.c .../libmysqlcppconn8-static.a -lssl -lcrypto -lpthread -lstdc++ -o app
即使使用 Connector/C++ 的应用程序是用纯 C 编写的,最终的可执行文件仍然依赖于 C++ 运行时,该运行时必须安装在要运行该应用程序的目标计算机上。