MySQL Connector/C++ 開發人員指南  /  建置 Connector/C++ 應用程式  /  建置 Connector/C++ 應用程式:一般考量

5.1 建置 Connector/C++ 應用程式:一般考量

本節討論建置 Connector/C++ 應用程式時要記住的一般考量。如需適用於特定平台的資訊,請參閱第 5.2 節「建置 Connector/C++ 應用程式:平台特定考量」中適用於您平台的章節。

此處顯示的命令是從命令列給出的(例如,從 Makefile 呼叫)。這些命令適用於任何支援 make 和命令列建置工具(例如 g++ccclang)的平台,但可能需要針對您的建置環境進行調整。

建置工具和組態設定

您用來建置 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_BININFO_SRC。)

C++17 支援

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。

Connector/C++ 標頭檔

應用程式使用的 API 決定了它應包含哪些 Connector/C++ 標頭檔。以下 include 指示假設 include 路徑包含 $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 新增至 include 路徑。

若要編譯您打算與 Connector/C++ 靜態連結的程式碼,請定義一個巨集,以調整標頭檔中的 API 宣告,以用於靜態程式庫。如需詳細資訊,請參閱使用 Connector/C++ 靜態程式庫

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 版本無關,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 巨集來檢查早於 Connector/C++ 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 標頭檔

在下列情況下需要 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 或更新版本,並且必須將標頭的位置新增至 include 路徑。若要取得 Boost 及其安裝指示,請瀏覽官方 Boost 網站

連結程式庫

當執行使用共用 Connector/C++ 程式庫的應用程式時,動態連結器必須找到程式庫及其執行階段相依性。必須正確設定動態連結器,才能找到 Connector/C++ 程式庫及其相依性。這包括明確將 -lresolv 新增至編譯/連結命令。

使用 OpenSSL 建置 Connector/C++ 會使連接器程式庫相依於 OpenSSL 動態程式庫。在這種情況下

  • 當將應用程式動態連結至 Connector/C++ 時,此相依性僅在執行階段相關。

  • 當將應用程式靜態連結至 Connector/C++ 時,也連結至 OpenSSL 程式庫。在 Linux 上,這表示明確將 -lssl -lcrypto 新增至編譯/連結命令。在 Windows 上,這會自動處理。

在 Windows 上,連結至 C++ 執行階段程式庫的動態版本。

執行階段程式庫

C 應用程式的 X DevAPI 在執行階段需要 libstdc++。根據您的平台或建置工具,可能會套用不同的程式庫。例如,在 macOS 上,該程式庫為 libc++;請參閱第 5.2.2 節「macOS 注意事項」

如果應用程式是使用動態連結程式庫建置的,則這些程式庫不僅必須存在於建置主機上,還必須存在於執行應用程式的目標主機上。必須正確設定動態連結器,以找到這些程式庫及其執行階段相依性,以及找到 Connector/C++ 程式庫及其執行階段相依性。

Oracle 建置的 Connector/C++ 程式庫依賴 OpenSSL 程式庫。後者必須安裝在系統上,才能執行連結到 Connector/C++ 程式庫的程式碼。另一種選擇是將 OpenSSL 程式庫放在與 Connector/C++ 相同的位置,在這種情況下,動態連結器應在連接器程式庫旁邊找到它們。另請參閱第 5.2.1 節「Windows 注意事項」第 5.2.2 節「macOS 注意事項」

注意

自 Connector/C++ 8.0.28 起,不再支援 TLSv1 和 TLSv1.1 連線協定,這使得 TLSv1.2 成為最早支援的連線協定。

使用 Connector/C++ 動態程式庫

Connector/C++ 動態程式庫名稱取決於平台。這些程式庫實作了 X DevAPI 和 C 的 X DevAPI,其中程式庫名稱中的 A 代表 ABI 版本

  • libmysqlcppconn8.so.A (Unix)

  • libmysqlcppconn8.A.dylib (macOS)

  • mysqlcppconn8-A-vsNN.dll,帶有匯入程式庫 vsNN/mysqlcppconn8.lib (Windows)

對於舊版的 JDBC API,動態程式庫的命名如下,其中程式庫名稱中的 B 代表 ABI 版本

  • libmysqlcppconn.so.B (Unix)

  • libmysqlcppconn.B.dylib (macOS)

  • mysqlcppconn-B-vsNN.dll,帶有匯入程式庫 vsNN/mysqlcppconn-static.lib (Windows)

在 Windows 上,程式庫名稱中的 vsNN 值取決於用於建置程式庫的 MSVC 工具鏈版本。(Oracle 提供的 Connector/C++ 程式庫使用 vs14,並且與 MSVC 2019 和 2017 相容。) 這種慣例能夠在同一個系統上使用使用不同 MSVC 版本建置的程式庫。另請參閱第 5.2.1 節「Windows 注意事項」

若要建置使用 X DevAPI 或 C 的 X DevAPI 的程式碼,請將 -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

若要建置使用 C 的 X DevAPI 的純 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 或 C 的 X DevAPI 應用程式的 -lmysqlcppcon8

使用該 Makefile,命令 make app 會產生下列編譯器調用

cc -I .../include -L .../lib64 app.c -lmysqlcppconn -o app
注意

當執行使用 Connector/C++ 動態程式庫的應用程式時,動態連結器必須找到該程式庫及其執行階段相依性。請參閱執行階段程式庫

使用 Connector/C++ 靜態程式庫

可以將您的應用程式與 Connector/C++ 靜態程式庫連結。這樣一來,就沒有執行階段對連接器的依賴性,而且產生的二進位檔可以在未安裝 Connector/C++ 的系統上執行。

注意

即使靜態連結,產生的程式碼仍然依賴 Connector/C++ 程式庫的所有執行階段相依性。例如,如果 Connector/C++ 是使用 OpenSSL 建置的,則程式碼會執行階段依賴 OpenSSL 程式庫。請參閱執行階段程式庫

Connector/C++ 靜態程式庫名稱取決於平台。這些程式庫實作了 X DevAPI 和 C 的 X DevAPI

  • libmysqlcppconn8-static.a (Unix, macOS)

  • vsNN/mysqlcppconn8-static.lib (Windows)

對於舊版 JDBC API,靜態程式庫的命名如下

  • libmysqlcppconn-static.a (Unix, macOS)

  • vsNN/mysqlcppconn-static.lib (Windows)

注意

通用 Linux 套件不包含任何 Connector/C++ 靜態程式庫。如果您打算將應用程式連結到靜態程式庫,請考慮安裝特定於您建置最終應用程式的平台的套件。

在 Windows 上,程式庫名稱中的 vsNN 值取決於用於建置程式庫的 MSVC 工具鏈版本。(Oracle 提供的 Connector/C++ 程式庫使用 vs14,並且與 MSVC 2019 和 2017 相容。) 這種慣例能夠在同一個系統上使用使用不同 MSVC 版本建置的程式庫。另請參閱第 5.2.1 節「Windows 注意事項」

若要編譯您打算靜態連結到 Connector/C++ 的程式碼,請定義一個巨集,以調整標頭檔中的 API 宣告,以便與靜態程式庫搭配使用。定義巨集的一種方法是在編譯器調用命令上傳遞 -D 選項

  • 對於使用 X DevAPI、C 的 X DevAPI 或 (從 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
注意

為了避免連結器報告未解析的符號,編譯行必須包含 OpenSSL 程式庫和 Connector/C++ 程式碼所依賴的 pthread 程式庫。

如果沒有使用 OpenSSL 建置 Connector/C++,則不需要 OpenSSL 程式庫,但 Oracle 建置的 Connector/C++ 發行版本確實依賴 OpenSSL。

Connector/C++ 程式庫所需的確切程式庫清單取決於平台。例如,在 Solaris 上,可能需要 socketrtnsl 程式庫。

若要建置使用 C 的 X DevAPI 的純 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 或 C 的 X DevAPI 應用程式的 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++ 執行階段,而該執行階段必須安裝在要執行應用程式的目標電腦上。