交叉编译MySQL并在Qt应用

大多数开发板上都内置的有SQList,确实在开发中这个数据库时比较好用的, 但是没办法,各种原因需要使用mysql。
好像是mysql5之后的需要的是cmake,之前的是.configure。
在此之前也编译了mysql5.1.51,后来用windows测试的时候说版本太老了,所以再次编译个比较新的版本。

前期准备

环境

Windows:windows 11
ubuntu:18.04
目标平台 Linux 5.10.87 aarch64
交叉编译链:aarch64-none-linux-gnu
gcc g++版本:8
cmake版本:3.16.5

注意:

1、需要确认好目标平台是32位还是64位,用对应的交叉编译链,同时ubuntu位数也要是一致的。
2、本着尽量简单的原则,需要确认开发板上openssl版本,可以使用openssl version查看

资源包版本及下载

boost_1_77_0.tar.bz2 下载
ncurses_6.5.tar.gz 下载
openssl-1.1.1l.tar.gz 下载
mysql8.0.39.tar.gz 下载
musql下载图解:
1、选中源码
MySQL源码下载
2、拉到最下面选中tar.gz
在这里插入图片描述

注意:

1、其中boots版本是mysql8.0.39指定的,后面会提到。
2、openssl版本是由ARM环境下确定的, 如果想使用其他版本,记得把开发板上也更新一下

ubuntu环境更新检查

1、gcc g++版本要不低于8
2、cmake 没有的需要安装一下

编译开始

思路,将两个版本分开编译,路径分别为:/opt/x86和/opt/arm
将下载的4个包拷贝分别进两个目录里面
我已经切换了root用户,否则的话,需要命令前都加sudo 防止乱七八糟的错误

编译x86_64版本

sudo su
cd /opt/x86

1、解压boots:

tar jxvf boost_1_77_0.tar.bz2

2、编译openssl:

tar -zxvf openssl-1.1.1l.tar.gz //解压
mkdir openssl	//创建安装目录
cd openssl-1.1.1l
./Configure without-asm shared --prefix=/opt/x86/openssl //配置
make -j4
make install

3、编译ncurses:

tar -zxvf ncurses-6.5tar.gz	//解压
mkdir ncurses		//创建安装目录
cd ncurses-6.5
//配置、编译、安装
./configure -with-yielding-select=no --prefix=/opt/x86/ncurses/
make
make install

4、编译mysql

tar -zxvf mysql-8.0.39.tar.gz	//解压
cd mysql-8.0.39
mkdir build		//创建安装目录
cd build
配置cmake:
cmake .. \
-DCMAKE_BUILD_TYPE:STRING=Release \
-DCMAKE_INSTALL_PREFIX=/opt/x86/mysql-8.0.39/build/__install \
-DMYSQL_DATADIR=/opt/x86/mysql-8.0.39/build/__install/data \
-DENABLED_LOCAL_INFILE=1 \
-DENABLE_DTRACE=0 \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EMBEDDED_SERVER=0 \
-DMYSQL_MAINTAINER_MODE=0 \
-DWITH_BOOST=/opt/x86/boost_1_77_0 \
-DWITH_SSL=system \
-DOPENSSL_ROOT_DIR=/opt/x86/openssl \
-DCURSES_INCLUDE_PATH=/opt/x86/ncurses/include \
-DCURSES_LIBRARY=/opt/x86/ncurses/lib/libncursesw.a \
-DWITH_LIBEVENT=bundled \
-DRESOLV_LIBRARY=/snap/gnome-3-38-2004/143/usr/lib/x86_64-linux-gnu/libresolv.so \
-DWITH_TEST_TRACE_PLUGIN=0 \
-DIGNORE_AIO_CHECK=1 \
-DBUILD_CONFIG=mysql_release \
-DWITH_UNIT_TESTS=0

报错1:

CMake Error at CMakeLists.txt:444 (MESSAGE):
Please do 'apt install gcc-8 g++-8'

解决1:

//通过查看本地gcc版本为7,需要升级到8
sudo apt update 
sudo apt install gcc-8 g++-8 
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 50 //设置为默认gcc

报错2:

You can also download boost manually, from
https://archives.boost.io/release/1.77.0/source/boost_1_77_0.tar.bz2

解决2:这就是上面提到的,必须要下载1.77.0,我原先下载的是1.80.0
重新cmake 配置

安装

执行make,这里 可能 会有个错误,跟ubuntu配置有关:

g++-8: fatal error: Killed signal terminated program cc1plus
compilation terminated.
sql/CMakeFiles/sql_gis.dir/build.make:478: recipe for target 'sql/CMakeFiles/sql_gis.dir/gis/symdifference_functor.cc.o' failed
make[2]: *** [sql/CMakeFiles/sql_gis.dir/gis/symdifference_functor.cc.o] Error 1
make[2]: *** Waiting for unfinished jobs....
CMakeFiles/Makefile2:19715: recipe for target 'sql/CMakeFiles/sql_gis.dir/all' failed
make[1]: *** [sql/CMakeFiles/sql_gis.dir/all] Error 2
Makefile:151: recipe for target 'all' failed
make: *** [all] Error 2

解决:内存不足,扩大虚拟内存即可

//根据具体情况,我原本就有2G,配完是6G是够用的
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

然后继续执行就完成了

make
make install

编译aarch64版本

流程是一样的,只是中间碰到的问题不一样。

cd /opt/arm/

1、解压boots:

 tar jxvf boost_1_77_0.tar.bz2

2、编译openssl:

tar -zxvf openssl-1.1.1l.tar.gz //解压
mkdir openssl	//创建安装目录
cd openssl-1.1.1l
./Configure no-asm shared --prefix=/opt/arm/openssl --cross-compile-prefix=/opt/arago-2021.09-aarch64-linux-tisdk/sysroots/x86_64-arago-linux/usr/bin/aarch64-none-linux-gnu- linux-aarch64 //配置
make -j4
make install

3、编译ncurses

tar -zxvf ncurses-6.5tar.gz	//解压
mkdir ncurses		//创建安装目录
cd ncurses-6.5
配置
./configure --prefix=/opt/arm/ncurses -with-yielding-select=no CC=aarch64-none-linux-gnu-gcc CXX=aarch64-none-linux-gnu-g++ STRIP=aarch64-none-linux-gnu-strip --host=aarch64-linux-gnu

报错:

/usr/bin/install -c -s tic     /opt/arm/ncurses/bin/echo tic|       sed 's/$//'|sed 's,x,x,'|sed 's/$//'
strip: Unable to recognise the format of the input file /opt/arm/ncurses/bin/tic'
/usr/bin/install: strip process terminated abnormally
Makefile:234: recipe for target 'install.progs' failed

解决:直接暴力解决,不编译该模块

//在configure时添加参数 
--disable-stripping

添加后重新执行./configure ……

安装
make -j4 && install

4、编译MySQL

tar -zxvf mysql-8.0.39.tar.gz	//解压
cd mysql-8.0.39
mkdir build		//创建安装目录
cd build
配置cmake:
cmake .. \
-DCMAKE_BUILD_TYPE:STRING=Release \
-DCMAKE_INSTALL_PREFIX=/opt/arm/mysql-8.0.39/build/__install \
-DMYSQL_DATADIR=/opt/arm/mysql-8.0.39/build/__install/data \
-DENABLED_LOCAL_INFILE=1 \
-DENABLE_DTRACE=0 \
-DHAVE_CLOCK_GETTIME=1 \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EMBEDDED_SERVER=0 \
-DMYSQL_MAINTAINER_MODE=0 \
-DWITH_BOOST=/opt/arm/boost_1_77_0 \
-DWITH_SSL=system \
-DOPENSSL_ROOT_DIR=/opt/arm/openssl \
-DCURSES_INCLUDE_PATH=/opt/arm/ncurses/include \
-DCURSES_LIBRARY=/opt/arm/ncurses/lib/libncurses.a \
-DWITH_LIBEVENT=bundled \
-DRESOLV_LIBRARY=/opt/arago-2021.09-aarch64-linux-tisdk/sysroots/aarch64-linux/usr/lib/libresolv.so \
-DWITH_TEST_TRACE_PLUGIN=0 \
-DIGNORE_AIO_CHECK=1 \
-DBUILD_CONFIG=mysql_release \
-DWITH_UNIT_TESTS=0 \
-DCMAKE_CXX_COMPILER=/opt/arago-2021.09-aarch64-linux-tisdk/sysroots/x86_64-arago-linux/usr/bin/aarch64-none-linux-gnu-g++ \
-DCMAKE_C_COMPILER=/opt/arago-2021.09-aarch64-linux-tisdk/sysroots/x86_64-arago-linux/usr/bin/aarch64-none-linux-gnu-gcc \
-DCMAKE_SYSTEM_PROCESSOR=arm

报错:

LIBEVENT version must be at least 2.1, found /.

解决方案:
检查过后这是要求最低2.1,但我们有的已经是2.1.11,不知道为什么没检测到,所以直接修改这个文件:
mysql-8.0.39/cmake/libevent.cmake
添加5行代码

SET(LIBEVENT_VERSION "2.1.11-stable") 
SET(COMPILE_TEST_RESULT TRUE)
SET(RUN_OUTPUT "2.1.11-stable")
MESSAGE(STATUS "LIBEVENT_VERSION_STRING ${LIBEVENT_VERSION_STRING}") 
MESSAGE(STATUS "LIBEVENT_VERSION (${WITH_LIBEVENT}) ${LIBEVENT_VERSION}") 

位置如图:
在这里插入图片描述
改完后再次进行配置,就没问题了

make

这个过程比较繁琐,每个环境可能报错都不一样,但大差不差,需要耐心。
报错1:
在这里插入图片描述
解决:
这是说文件格式不正确,因为我们是交叉编译,本地是x86,需要将刚刚编译的x86文件拷贝到这里。
注意!!!
这里的aarch64格式的文件要备份,后面的错误基本都是说文件类型不正确,都需要备份,后面要用的!

cd /opt/arm
mkdir backup
cd -
//备份aarch64格式文件
cp ./runtime_output_directory/protoc-24.0.0 /opt/arm/backup
//替换为x86格式文件
cp /opt/x86/mysql-8.0.39/build/runtime_output_directory/protoc-24.0.0 ./runtime_output_directory/
make

这里要说一个:我参考了一篇博客(见文末),博主在这里还设置了运行库的位置,
放在我这里应该是

export LD_LIBRARY_PATH=/opt/arm/build/library_out_directory/$LD_LIBRARY_PATH

但是我查看了protoc-24.0.0,应该是由于静态编译,所以RPATH是内置的,我用patchelf 去强制更改后,ldd查看依赖库变空,但依旧没有去找我设置的这个LD_LIBRARY_PATH里面的库
所以我认为这里设置和不设置没什么区别,这也许是最后无法install的原因

报错2:

/bin/sh: 1: ../runtime_output_directory/uca9dump: Exec format error

解决:备份文件、替换文件

报错3:

/bin/sh: 1: ../runtime_output_directory/comp_err: Exec format error

解决:备份文件、替换文件

报错4:

/bin/sh: 1: /opt/arm/mysql-8.0.39/build/runtime_output_directory/comp_sql: Exec format error

解决:备份文件、替换文件

报错5:

opt/arm/mysql-8.0.39/storage/ndb/src/common/portlib/NdbTick.cpp:132:2: error: #error clock_gettime is expected to be supported on non Windows
  132 | #error clock_gettime is expected to be supported on non Windows
      |  ^~~~~
/opt/arm/mysql-8.0.39/storage/ndb/src/common/portlib/NdbTick.cpp: In function ‘int NdbTick_GetMonotonicClockId(clockid_t*):
/opt/arm/mysql-8.0.39/storage/ndb/src/common/portlib/NdbTick.cpp:140:10: error: ‘NdbTick_clk_id’ was not declared in this scope; did you mean ‘NdbTick_Elapsed’?
  140 |   *clk = NdbTick_clk_id;
      |          ^~~~~~~~~~~~~~
      |          NdbTick_Elapsed
storage/ndb/src/common/portlib/CMakeFiles/ndbportlib_objlib.dir/build.make:179: recipe for target 'storage/ndb/src/common/portlib/CMakeFiles/ndbportlib_objlib.dir/NdbTick.cpp.o' failed

解决思路:
1、查看NdbTick132行发现是检查HAVE_CLOCK_GETTIME是否定义
2、查看mysql-8.0.39/include/config.h 发现 HAVE_CLOCK_GETTIME未定义,如下:
/* Code tests*/
/* #undef HAVE_CLOCK_GETTIME /
/
#undef HAVE_CLOCK_REALTIME */
3、检查本地是否支持gettime
执行:grep -r "clock_gettime" /usr/include/time.h
ubuntu虚拟机:
extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;
开发板显示:
extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;
解决方法:

make clean
//在cmake 时候 强制设置这个宏 
-DHAVE_CLOCK_GETTIME=1
//重新cake
cmake ……
//再次make
make

报错6:

/opt/arm/mysql-8.0.39/build/runtime_output_directory/xprotocol_plugin: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable

解决:备份文件、替换文件

报错7:

/bin/sh: 1: ../runtime_output_directory/gen_lex_hash: Exec format error

解决:备份文件、替换文件

报错8:

/bin/sh: 1: ../runtime_output_directory/gen_keyword_list: Exec format error

解决:备份文件、替换文件

报错9:

/bin/sh: 1: ../runtime_output_directory/gen_lex_token: Exec format error

解决:备份文件、替换文件

报错10:

Make Error at info_macros.cmake:186 (MESSAGE):
  mysqld --no-defaults --help failed:
  /opt/arm/mysql-8.0.39/build/runtime_output_directory/mysqld: 1:
  /opt/arm/mysql-8.0.39/build/runtime_output_directory/mysqld:
  ELF   @P  @8: not found

  /opt/arm/mysql-8.0.39/build/runtime_output_directory/mysqld: 2:
  /opt/arm/mysql-8.0.39/build/runtime_output_directory/mysqld: Syntax error:
  ")" unexpected

解决:备份文件、替换文件

报错11:

  /bin/sh: 1: ./build_id_test: Exec format error

解决:替换文件,这个文件在报错的时候自动删除了,没办法备份

报错12:

/bin/sh: 1: ../runtime_output_directory/libmysql_api_test: Exec format error

解决:备份文件、替换文件

报错13:

/bin/sh: 1: ../runtime_output_directory/comp_client_err: Exec format error

解决:备份文件、替换文件

报错14:

/bin/sh: 1: /opt/arm/mysql-8.0.39/build/router/src/json_schema_embedder/json_schema_embedder: Exec format error

解决:替换 json_schema_embedder
路径为:mysql-8.0.39/bulid/router/src/json_schema_embedder/

到这里make就完成了,make install的时候会遇到一个bin文件安装路径的问题,如下图:

在这里插入图片描述
正是这个错误,才会有前面修改RPATH的问题,但是最后也没能成功,还是参考了别人打包的思路……

手动打包
mkdir arm_mysql_8.0.39; 							// 创建一个打包目录
cp -r runtime_output_directory arm_mysql8.0.39/bin	// 拷贝bin
cp -r library_output_directory arm_mysql8.0.39/lib	// 拷贝lib
cp -r include arm_mysql8.0.39/						// 拷贝include
cp -r packaging arm_mysql8.0.39/					// 拷贝配置文件
cp -r share arm_mysql8.0.39/						// 拷贝共享库
//此时bin路径下还存在着刚才拷贝过来的N个x86_64结构的可执行文件,需要替换
//将刚才备份的文件拷贝回来
cp /opt/arm/backup/* ./arm_mysql8.0.39/bin/

到这里就结束了,接下来将arm_mysql_8.0.39文件夹拷贝到开发板上,然后开始下一步测试。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ARM 测试步骤:

  1. 在arm_mysql_8.0.39 下创建data目录,存放数据。
cd /mylib/arm_mysql_8.0.39
mkdir data
cd bin
  1. 指定运行库(当前是用来测试,临时指定,如果正式使用肯定要写到环境变量的或者拷贝到指定目录里去)
export LD_LIBRARY_PATH=/mylib/arm_mysql8.0.39/lib:$LD_LIBRARY_PATH
  1. 初始化mysql(这里会生成随机密码,接下来的密码需要登陆,可能会报错找不到库云云,是上一步指定运行库没成功,重新执行一遍)
./mysqld --initialize --user=mysql --basedir=/mylib/arm_mysql8.0.39 --datadir=/mylib/arm_mysql8.0.39/data
//输出的内容应该包含类似与下面一条,其中 H-daQl=!h7id 就是生成的随机密码
2024-08-29T05:16:09.740601Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: H-daQl=!h7id
  1. 启动mysql(这里会有两个报错)
./mysqld --daemonize --pid-file=/mylib/arm_mysql8.0.39/data/mysqld.pid --user=mysql

报错1:

[ERROR] [MY-010124] [Server] Fatal error: Can't change to run as user 'mysql' ;  Please check that the user exists!

解决1: 为系统增加一个mysql用户

useradd mysql   #添加mysql用户
passwd mysql    #设置mysql用户密码

报错2:

[ERROR] [MY-013236] [Server] The designated data directory /mylib/arm_mysql8.0.39/data/ is unusable. You can remove all files that the server added to it.

解决2:给data文件夹设置权限

chown -R mysql:mysql /mylib/arm_mysql8.0.39/data/
chmod 750 /mylib/arm_mysql8.0.39/data/

重新启动mysql
5. 连接mysql

//连接方法一:
./mysql -u root -p -S /tmp/mysql.sock
//方法二:
./mysql -u root -p -h 127.0.0.1 -P 3360

给个示例图:
在这里插入图片描述

  1. 到此就可以了,登录成功后可以改个简单的密码或者进行测试,贴几个简单的命令。
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password'; //修改root用户密码为:new_password
update user set host='%' where user = 'root';  				//给root用户增加远程访问权限
select host,user from user;									//查询用户的权限
CREATE DATABASE my_database;								//创建数据库 my_database;
USE my_database;											//选择数据库
CREATE TABLE table_name(xxx,xxx,xxxx);						//创建表table_name 里面包含了N个字段
insert into table_name(xxx,xxx) values('xxx','xxx');		//给表table_name 插入数据,前面括号是字段,后面是value
select * from table_name;									//查询表table_name 内容,也可以在后面加where等限定词
update table_name set xx= 'xxx' where xxx='x';				//在table_name表内根据限定xxx = 'x' 修改xx 的值为'xxx' 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Qt使用MySQL

ps:这里说的是在开发板上使用,如果是windows使用,步骤也一样,编译一下拿来用就可以。

查看是否已经支持插件

方法一:

直接在开发板查找插件文件,路径一般在:/usr/lib/plugins/sqldrivers/ 查看是否有 libqsqlmysql.so 文件

方法二:

编写Qt程序,在pro文件中添加 QT+=sql,然后在初始化或者其他位置添加以下代码:

qDebug() << "Available SQL drivers: " << QSqlDatabase::drivers();

执行后输出:
在这里插入图片描述
像我现在是支持的,如果只有QSQLITE那就是不支持。

编译MySQL插件(在虚拟机进行)

  1. 先确认QT安装目录中有没有源码目录 Qt5.14.2/5.14.2/Src/qtbase
    若是没有该目录,去下载对应版本源码的插件目录
    我的版本是5.14.2,对应的下载地址为 https://download.qt.io/archive/qt/5.14/5.14.2/submodules/
    在这里插入图片描述
  2. (用root用户打开Qt Creator)Qt Creator打开工程:qtbase/src/plugins/sqldrivers/mysql/mysql.pro,构建套件选择包含交叉编译链的套件。
  3. 修改mysql.pro
    注释掉:QMAKE_USE += mysql
    指定库和头文件的路径
    在这里插入图片描述
  4. 修改qsqldriverbase.pri
    注释掉下面的内容:
include($$shadowed($$PWD)/qtsqldrivers-config.pri)
  1. 构建ctrl+B,然后会在根目录下生成一个plugins文件夹,将里面的 libqsqlmysql.so 拷贝至开发板
scp /plugins/sqldrivers/libqsqlmysql.so root@your_ip:/usr/lib/plugins/sqldrivers/

写Qt程序测试MySQL

  1. pro 文件添加:
QT+=sql

path = /opt/arm/mysql_8.0.39/arm_mysql8.0.39
INCLUDEPATH += $$path/include
LIBS += -L$$path/lib -lmysqlclient
  1. .cpp添加头文件
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
  1. 添加代码
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");  //数据库服务器IP
db.setUserName("root");    //数据库用户名
db.setPassword("test123456");  //密码
db.setDatabaseName("sqltest");  //使用哪个数据库
if(db.open() == false){
        qDebug() << "MySQL open fail: " << db.lastError().text();
        return;
}
//查询数据库
QSqlQuery query;
QString str = "select * from students";
query.exec(str);
while(query.next()){
    qDebug()<<"select result: " << query.value(0).toInt() << query.value(1).toString() << query.value(2).toString() << query.value(3).toInt();
}
  1. 编译,到开发板执行。可看到结果。测试完成!
    在这里插入图片描述
注意 :
  1. 首先保证开发板的数据库是启动状态。
  2. 数据库中应包含basename: sqltest
  3. sqltest 中应有一个表为:students
  4. 表students应有对应的字段和类型,最少有4个,依次为:int ,varchar,varchar,int;

资源下载和参考博客

参考博客
编译好的库下载链接

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值