大多数开发板上都内置的有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、选中源码
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 测试步骤:
- 在arm_mysql_8.0.39 下创建data目录,存放数据。
cd /mylib/arm_mysql_8.0.39
mkdir data
cd bin
- 指定运行库(当前是用来测试,临时指定,如果正式使用肯定要写到环境变量的或者拷贝到指定目录里去)
export LD_LIBRARY_PATH=/mylib/arm_mysql8.0.39/lib:$LD_LIBRARY_PATH
- 初始化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
- 启动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
给个示例图:
- 到此就可以了,登录成功后可以改个简单的密码或者进行测试,贴几个简单的命令。
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插件(在虚拟机进行)
- 先确认QT安装目录中有没有源码目录 Qt5.14.2/5.14.2/Src/qtbase
若是没有该目录,去下载对应版本源码的插件目录
我的版本是5.14.2,对应的下载地址为 https://download.qt.io/archive/qt/5.14/5.14.2/submodules/
- (用root用户打开Qt Creator)Qt Creator打开工程:qtbase/src/plugins/sqldrivers/mysql/mysql.pro,构建套件选择包含交叉编译链的套件。
- 修改mysql.pro
注释掉:QMAKE_USE += mysql
指定库和头文件的路径
- 修改qsqldriverbase.pri
注释掉下面的内容:
include($$shadowed($$PWD)/qtsqldrivers-config.pri)
- 构建ctrl+B,然后会在根目录下生成一个plugins文件夹,将里面的 libqsqlmysql.so 拷贝至开发板
scp /plugins/sqldrivers/libqsqlmysql.so root@your_ip:/usr/lib/plugins/sqldrivers/
写Qt程序测试MySQL
- pro 文件添加:
QT+=sql
path = /opt/arm/mysql_8.0.39/arm_mysql8.0.39
INCLUDEPATH += $$path/include
LIBS += -L$$path/lib -lmysqlclient
- .cpp添加头文件
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
- 添加代码
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();
}
- 编译,到开发板执行。可看到结果。测试完成!
注意 :
- 首先保证开发板的数据库是启动状态。
- 数据库中应包含basename: sqltest
- sqltest 中应有一个表为:students
- 表students应有对应的字段和类型,最少有4个,依次为:int ,varchar,varchar,int;