环境设备
- 交叉编译器:arm-linux-gnueabihf-gcc
- 编译器:gcc-9(用 gcc-11 可能会出现版本问题)
- 编译平台:unbutu20.04
- ARM 开发板:100ask_imx6ull_pro
在 ubuntu 上交叉编译 MySQL
准备工作
- 下载 mysql-5.1.51.tar.gz
- 下载 ncurses-5.6
- 配置好交叉编译环境
- 安装所需的库:
apt-get install libncurses5-dev
编译 MySQL-PC 版本
- 解压 mysql 压缩包:
tar zxvf mysql-5.1.51.tar.gz
- 进入解压目录:
cd mysql-5.1.51
- 运行 configure:
CXXFLAGS="-std=c++98" ./configure -prefix=/usr/local/mysql
我的环境中如果不加前面的
CXXFLAGS="-std=c++98"
编译器默认是 C++11,会报错
- 执行
make
(注意这里没有 make install) - 将这个文件夹重命名为
mysql-5.1.51-pc
作为备用,之后需要用到里面编译好的文件
交叉编译 ncurses
- 解压 ncurses 压缩包:
tar zxvf ncurses-5.6.tar.gz
这里注意如果 mysql 采用的是 5.1.51 版本,对应的 ncurses 最好是采用 5.6,尝试过 5.9 版本会导致编译失败
- 进入解压目录:
cd ncurses-5.6
- 运行 configure:
CXXFLAGS="-std=c++98" ./configure --host=arm-linux-gnueabihf --prefix=/usr/local/ncurses --enable-static
- 运行
make
- 运行
make install
错误 1:
../c++/cursesf.h:707:42: 错误: cannot convert ‘const NCursesUserForm<T>*’ to ‘NCursesForm*’
707 | return reinterpret_cast<T*>(get_user ());
| ~~~~~~~~~^~
../c++/cursesf.h:384:16: 附注: 初始化‘void* NCursesForm::get_user()’的实参 'this'
384 | inline void *get_user() {
| ^~~~~~~~
- 解决:在对应的*.h 文件中的
inline void *get_user()
函数后添加const
关键字(应该是有三个.h 文件) - 修改完后应该还有个错误,在
inline UserHook *UserPointer()
函数声明后添加const
就行了
In file included from ../c++/cursesf.h:39,
from ../c++/cursesf.cc:35:
../c++/cursesp.h: 在成员函数‘void* NCursesPanel::get_user() const’中:
../c++/cursesp.h:81:33: 错误: passing ‘const NCursesPanel’ as ‘this’ argument discards qualifiers [-fpermissive]
81 | UserHook* uptr = UserPointer();
| ~~~~~~~~~~~^~
../c++/cursesp.h:61:20: 附注: 在调用‘NCursesPanel::UserHook* NCursesPanel::UserPointer()’时
61 | inline UserHook *UserPointer()
| ^~~~~~~~~~~
交叉编译 MySQL
- 重新解压 mysql 压缩包:
tar zxvf mysql-5.1.51.tar.gz
- 进入解压目录:
cd mysql-5.1.51
- 修改
configure
为如下形式(有四处这样的语句):
if test "$cross_compiling" = yes; then
echo “skipcorss_compiling test”;
# { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
# $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
# { { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling
# See \`config.log' for more details." >&5
# $as_echo "$as_me: error: cannot run test program while cross compiling
# See \`config.log' for more details." >&2;}
# { (exit 1); exit 1; }; }; }
- 运行 configure:
CXXFLAGS="-std=c++98" CPPFLAGS="-I/usr/local/ncurses5.6/include/ncurses" ./configure --host=arm-linux-gnueabihf --enable-static --with-named-curses-libs=/usr/local/ncurses5.6/lib/libncurses.a --prefix=/usr/local/mysql --without-debug --without-docs --without-man --without-bench --with-charset=gb2312 --with-extra-charsets=ascii,latin1,utf8
/usr/local/ncurses5.6/
:ncurse 的安装目录/usr/local/mysql
:mysql 准备安装到的目录
- 运行
make
- 运行
make install
交叉编译 Qt 的 MySQL 插件
下面的步骤是在 ubuntu 上安装好 qt 并交叉编译出 qmake 工具后才能进行的
Qt 在 ubuntu 的安装可以参考正点原子的视频:https://www.bilibili.com/video/BV1sF411L7cz?p=5&vd_source=b9ad59ac5105585b5c44c5b8255346d8
Qt 交叉编译可以参考我的上一篇文章:
- 找到 qt 安装目录,进入类似于
/opt/Qt5.12.9/5.12.9/Src/qtbase/src/plugins/sqldrivers/mysql
的目录,修改 mysql.pro 文件如下:
TARGET = qsqlmysql
HEADERS += $$PWD/qsql_mysql_p.h
SOURCES += $$PWD/qsql_mysql.cpp $$PWD/main.cpp
INCLUDEPATH += /usr/local/mysql/include/mysql
LIBS +=-L/usr/local/mysql/lib/mysql -lmysqlclient_r
# QMAKE_USE += mysql
OTHER_FILES += mysql.json
PLUGIN_CLASS_NAME = QMYSQLDriverPlugin
include(../qsqldriverbase.pri)
- 其中 INCLUDEPATH 为之前 mysql 的安装路径
- 找到上一级目录中的
qsqldriverbase.pri
文件,修改为如下形式:
QT = core core-private sql-private
# For QMAKE_USE in the parent projects.
#include($$shadowed($$PWD)/qtsqldrivers-config.pri)
include(./configure.pri)
PLUGIN_TYPE = sqldrivers
load(qt_plugin)
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
- 使用 Qt Creator 的构建方式在
xxxx/sqldrivers/mysql
目录下生成 Makefile 文件(这一步在 Qt 的软件中操作)
注意这里使用的 qmake 为之前 Qt 移植时交叉编译生成的 qmake
- 执行
make
- 执行
make install
- 在
xxxx/sqldrivers/
目录下出现libqsqlmysql.so
即可
移植 MySQL 到 imx6ull 开发板
- 这里参考文档:《编译 ARM 平台的 QtEmbedded 的 MySQL 插件和移植 MySQL 到 ARM 开发板》
小结
- 在 mysql 全部移植好后出现了
mysql: /lib/libc.so.6: version
GLIBC_2.33’ not found (required by mysql)` 的问题,说明我的 ubuntu 中 glibc 版本高于开发板,但降低 glibc 版本的风险太大,所以只能考虑使用 docker 进行数据库的编译 - 交叉编译 mysql 的过程较为复杂且在编译过程中会出现各种问题,可以考虑更换成 sqlite 数据库,这个移植过程比较简单,且操作过程和 mysql 很像,在有 mysql 基础的情况下学起来比较容易
参考资料
- https://blog.csdn.net/zd394071264/article/details/8623669
- 《编译 ARM 平台的 QtEmbedded 的 MySQL 插件和移植 MySQL 到 ARM 开发板》