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
