RPI中安裝MariaDB ODBC Connector

Raspberry Pi 除了用來架設網站外,其實它就真的是一台小電腦,所以要用來開發程式也是可以的。

要讓你的Raspberry Pi能開發程式,最基本要安裝的就是以下套件:

apt install -y build-essentials

有了開發套件後,這次想要測試的是由raspberry pi中可以透過c++的方式去連到MariaDB資料庫存取資料。通常這種要連線到資料庫的話,有一種方式就是透過ODBC的方式。要能使用ODBC就要找到相關資料庫的ODBC連線函式庫。

測試環境

在這次測試的環境如下:

  • Raspberry Pi 4
  • ubuntu 20.04
  • docker

強烈建議要使用docker來測試,因為這樣如果安裝上有什麼閃失的話,還可以還原再重來。

由source code安裝MariaDB ODBC Connector

因為MariaDB ODBC Connector基本套件中並沒有提供arm64的套件,所以在Raspberry Pi 中無法直接下載及安裝。還好MariaDB有提供用source code安裝的方式。原本以為照著網站上的說明就可以按表操課,順利編譯及安裝。沒想到在第一關用cmake產生make file時就卡關了。

依網站中的說明,安裝完必要套件,並用git下載程式碼後,接著就是切換到程式碼的目錄,並執行以下指令:

cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONC_WITH_UNIT_TESTS=Off -DCONC_WITH_MSI=OFF -DCMAKE_INSTALL_PREFIX=/usr/local .

沒想到執行完卻看到 Driver Manager was not found

 -- Static PLUGINS mysql_native_password;mysql_old_password;pvio_socket
-- Dynamic PLUGINS dialog;mysql_clear_password
-- CPack generation: TGZ
-- SSL support:  Libs:
-- Zlib support: yes (using bundled zlib)
-- Installation layout: DEFAULT
-- Include files will be installed in include/mariadb
-- Libraries will be installed in lib/mariadb
-- Binaries will be installed in bin
-- Documentation included from
-- Required: dl;m;pthread
-- Looking for floor
-- Looking for floor - not found
-- odbc_config is not found
-- Found ODBC Driver Manager includes: /usr/include
CMake Error at CMakeLists.txt:252 (MESSAGE):
  Driver Manager was not found 

一時之間想不出到底哪邊出了問題。我想這時大家一定會採取的方式就是上google找資料。可惜找了半天,只在StackOverflow看到有人在詢問,但沒有人回覆。想說那不然就直接找看看是否有現成的MariaDB ODBC connector for arm64的,結果找了半天也沒有。看來真的只能靠自已了。

還好先前還有學過一些CMake,想說不然就來研究一下是哪邊出了問題。於是就用 “Dirver Manager was not found”的關鍵字,查找了一下source code目錄中的CMakeList.txt這個檔案,才發現原來它是在執行一個cmake子目錄中的FindDM.cmake時失敗才跳出來的錯誤訊息。

在CMake中通常會再用子功能(同樣也是CMake的語法)來輔助一些建置過程中需要的資料,所以就再繼續去研究FindDM.cmake的內容。看了一下,發現原來FindDM.cmake是在找尋odbc driver的函式庫及引用標頭檔的目錄:

 # FindDM.cmake
#
# Cmake script to look for driver manager includes and libraries on platforms others than Windows
# We expect that the driver manager is UnixODBC


IF(WITH_IODBC)
  SET(ODBC_CONFIG_EXEC iodbc-config)
  SET(ODBC_CONFIG_INCLUDES --cflags)
  SET(ODBC_CONFIG_LIBS --libs)
  SET(ODBC_LIBS iodbc)
  SET(ODBC_INSTLIBS iodbcinst)
ELSE() #UnixODBC
  SET(ODBC_CONFIG_EXEC odbc_config)
  SET(ODBC_CONFIG_INCLUDES --include-prefix)
  SET(ODBC_CONFIG_LIBS --lib-prefix)
  SET(ODBC_LIBS odbc)
  SET(ODBC_INSTLIBS odbcinst)
ENDIF()


IF(ODBC_LIB_DIR AND ODBC_INCLUDE_DIR)
  MESSAGE(STATUS "Using preset values for DM dirs")
ELSE()
  FIND_PROGRAM(ODBC_CONFIG ${ODBC_CONFIG_EXEC}
               PATH
               /usr/bin
               ${DM_DIR}
               "${DM_DIR}/bin"
               ) 

上面程式碼中的第22行,可以看到一個IF條件式,如果有定義ODBC_LIB_DIR及ODBC_INCLUDE_DIR的話,就不用去找系統中odbc driver的目錄,如果沒有才要去找。又細看了一下查找的程式碼,發現其實都沒有支援arm64的OS:

IF(ODBC_CONFIG)
     MESSAGE(STATUS "Found ${ODBC_CONFIG_EXEC}: ${ODBC_CONFIG}")
     EXECUTE_PROCESS(COMMAND ${ODBC_CONFIG} ${ODBC_CONFIG_INCLUDES}
                     OUTPUT_VARIABLE result)
     STRING(REPLACE "\n" "" ODBC_INCLUDE_DIR ${result})
     EXECUTE_PROCESS(COMMAND ${ODBC_CONFIG} ${ODBC_CONFIG_LIBS}
                     OUTPUT_VARIABLE result)
     STRING(REPLACE "\n" "" ODBC_LIB_DIR ${result})
 IF(WITH_IODBC)   STRING(REPLACE "-I" "" ODBC_INCLUDE_DIR ${ODBC_INCLUDE_DIR})   STRING(REPLACE "-L" "" ODBC_LIB_DIR ${ODBC_LIB_DIR})   STRING(REGEX REPLACE " +-liodbc -liodbcinst" "" ODBC_LIB_DIR ${ODBC_LIB_DIR}) ENDIF()
 ELSE()
     MESSAGE(STATUS "${ODBC_CONFIG_EXEC} is not found ")
     # Try to find the include directory, giving precedence to special variables
     SET(LIB_PATHS /usr/local /usr /usr/local/Cellar/libiodbc/3.52.12)
 IF("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")   SET(LIB_PATHS "${LIB_PATHS}" "/usr/lib/x86_64-linux-gnu")   IF(EXISTS "/usr/lib64/")     SET(LIB_SUFFIX "lib64" "x86_64-linux-gnu")   ELSE()     SET(LIB_SUFFIX "lib" "x86_64-linux-gnu")   ENDIF() ELSE()   SET(LIB_PATHS "${LIB_PATHS}" "/usr/local/lib/i386-linux-gnu" "/usr/lib/i386-linux-gnu" "/usr/local/lib/i686-linux-gnu" "/usr/lib/i686-linux-gnu")   SET(LIB_SUFFIX "lib" "i386-linux-gnu" "i686-linux-gnu") ENDIF()

原本的想法是要修改FindDM.cmake的程式碼,讓它也能支援arm64 OS的odbc driver查找,但這樣有些費時。突然靈光一閃,想說要查找是因為沒有指定好才要查找,那如果我一開始就指定odbc driver的Lib及Include目錄不就可以了嗎!

於是第一步就是先找到那odbc driver的安裝目錄。因為一開始安裝odbc driver時是用以下指令安裝的:

sudo apt install -y unixodbc-dev

要知道它將driver相關資料安裝到哪個目錄的話,可以用以下指令來查詢:

dpkg -L unixodbc-dev

就可以找到原來是安裝在以下的目錄中:

 root@132aa8b2cc80:/usr/share# dpkg -L unixodbc-dev
/.
/usr
/usr/include
/usr/include/aarch64-linux-gnu
/usr/include/aarch64-linux-gnu/unixodbc_conf.h
/usr/include/autotest.h
/usr/include/odbcinst.h
/usr/include/odbcinstext.h
/usr/include/sql.h
/usr/include/sqlext.h
/usr/include/sqlspi.h
/usr/include/sqltypes.h
/usr/include/sqlucode.h
/usr/include/uodbc_extras.h
/usr/include/uodbc_stats.h
/usr/lib
/usr/lib/aarch64-linux-gnu
/usr/lib/aarch64-linux-gnu/libodbc.a
/usr/lib/aarch64-linux-gnu/libodbccr.a
/usr/lib/aarch64-linux-gnu/libodbcinst.a
/usr/lib/aarch64-linux-gnu/pkgconfig
/usr/lib/aarch64-linux-gnu/pkgconfig/odbc.pc
/usr/lib/aarch64-linux-gnu/pkgconfig/odbccr.pc
/usr/lib/aarch64-linux-gnu/pkgconfig/odbcinst.pc
/usr/share
/usr/share/doc
/usr/share/doc/unixodbc-dev
/usr/share/doc/unixodbc-dev/copyright
/usr/lib/aarch64-linux-gnu/libodbc.so
/usr/lib/aarch64-linux-gnu/libodbccr.so
/usr/lib/aarch64-linux-gnu/libodbcinst.so
/usr/share/doc/unixodbc-dev/NEWS.Debian.gz
/usr/share/doc/unixodbc-dev/changelog.Debian.gz 

於是只要將執行cmake的指令改為以下方式,指定好ODBC_LIB_DIR及ODBC_INCLUDE_DIR這兩個參數就可以了:

 cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONC_WITH_UNIT_TESTS=Off -DCONC_WITH_MSI=OFF -DCMAKE_INSTALL_PREFIX=/usr/local -DODBC_LIB_DIR=/usr/lib/aarch64-linux-gnu -DODBC_INCLUDE_DIR=/usr/include/aarch64-linux-gnu . 

到此就可以正常地用cmake建好make file,並執行建置及安裝了。

總結

簡單來說,要在Raspberry pi 中安裝MariaDB ODBC Connector的話,可以用以下指令:

sudo apt-get update 
sudo apt-get install git cmake make gcc libssl-dev unixodbc odbcinst unixodbc-dev
git clone https://github.com/MariaDB/mariadb-connector-odbc.git 
cd mariadb-connector-odbc

cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONC_WITH_UNIT_TESTS=Off -DCONC_WITH_MSI=OFF -DCMAKE_INSTALL_PREFIX=/usr/local -DODBC_LIB_DIR=/usr/lib/aarch64-linux-gnu -DODBC_INCLUDE_DIR=/usr/include/aarch64-linux-gnu . 

cmake --build . --config RelWithDebInfo

sudo make install

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *