1.首先下载好MYSQL5.7.18的源码包,分别解压到MYSQL5.7.18-pc目录和MYSQL5.7.18-arm目录,这个要分别编译的;
2.进行普通PC的源码编译,进入MYSQL5.7.18-pc目录,运行下面的cmake命令:
cmake . -LH -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DEXTRA_CHARSETS=all -DENABLED_LOCAL_INFILE=1 -DWITH_BOOST=/home/fanocean/下载/NitroShare/mysql-5.7.18/boost/boost_1_59_0
以下是编译选项的解释:
-DCMAKE_INSTALL_PREFIX -------mysql安装目录
-DMYSQL_DATADIR -------mysql数据库的安装目录
-DDEFAULT_CHARSET -------使用utf8字符
-DDEFAULT_COLLATION -------校验字符
-DEXTRA_CHARSETS --------安装所有扩展字符集
-DENABLED_LOCAL_INFILE ---------允许从本地导入数据
-DWITH_BOOST ---------Boost库的头文件路径(mysql5.7.18安装需要boost库支持)
执行完以上的命令之后,会显示详细的编译信息,-LH选项是显示详细信息。然后执行make命令,就会进行具体的编译,读者大概知道源码编译的过程。如果读者的电脑配置是双核或者四核以上,执行make -j4命令会编译快一些。(注意:从
MYSQL5.6版本之后,源码安装编译要用到CMAKE工具,请读者在自己的电脑自行安装。建议读者下载包含boost库的MYSQL5.7.18的源码包)
3.现在要进行交叉编译
MYSQL5.7.18的源码,进入MYSQL5.7.18-arm目录,运行下面的cmake命令:
cmake . -LH -DCMAKE_INSTALL_PREFIX=/opt/mysql -DMYSQL_DATADIR=/opt/mysql/data -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DEXTRA_CHARSETS=all -DENABLED_LOCAL_INFILE=1 -DCMAKE_CXX_COMPILER=/usr/local/armv7-marvell-linux-gnueabi-softfp-4.6.4/bin/arm-marvell-linux-gnueabi-g++ -DCMAKE_C_COMPILER=/usr/local/armv7-marvell-linux-gnueabi-softfp-4.6.4/bin/arm-marvell-linux-gnueabi-gcc -DWITH_BOOST=/home/fanocean/下载/NitroShare/mysql-5.7.18-arm/mysql-5.7.18/boost/boost_1_59_0
以下是编译选项的解释:
-DCMAKE_CXX_COMPILER ------指定交叉编译C++编译器的路径
-DCMAKE_C_COMPILER ------指定交叉编译C编译器的路径
运行完以上的cmake命令之后,会打印一连串的信息,其中会有下面的错误提示:
显示检测不到Curses库。显然我们需要下载一个ncurses源码包,对ncurses源码包进行交叉编译。
下面是交叉编译ncurses源码包的命令:
./configure --prefix=/opt/ncurses --host=arm-marvell-linux-gnueabi CC=/usr/local/armv7-marvell-linux-gnueabi-softfp-4.6.4/bin/arm-marvell-linux-gnueabi-gcc CXX=/usr/local/armv7-marvell-linux-gnueabi-softfp-4.6.4/bin/arm-marvell-linux-gnueabi-g++
以下是编译选项的解释:
--prefix 安装目录
--host 主机名(交叉编译工具链名称)
CC 指定交叉编译C编译器的路径
CXX 指定交叉编译C++编译器的路径
编译完之后,执行make命令,然后执行make install(或者sudo make install)。
安装完curses库之后,再看回之前交叉编译
MYSQL5.7.18-arm的步骤。在终端中进入到MYSQL5.7.18-arm目录,
执行:make clean ,
rm -f CMakeCache.txt, 把之前生成的CMakeCache.txt删除,
重新执行以下的cmake命令:
cmake . -LH -DCMAKE_INSTALL_PREFIX=/opt/mysql -DMYSQL_DATADIR=/opt/mysql/data -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DEXTRA_CHARSETS=all -DENABLED_LOCAL_INFILE=1 -DCMAKE_CXX_COMPILER=/usr/local/armv7-marvell-linux-gnueabi-softfp-4.6.4/bin/arm-marvell-linux-gnueabi-g++ -DCMAKE_C_COMPILER=/usr/local/armv7-marvell-linux-gnueabi-softfp-4.6.4/bin/arm-marvell-linux-gnueabi-gcc -DWITH_BOOST=/home/fanocean/下载/NitroShare/mysql-5.7.18-arm/mysql-5.7.18/boost/boost_1_59_0 -DCURSES_INCLUDE_PATH=/opt/ncurses/include/ncurses -DCURSES_LIBRARY=/opt/ncurses/lib/libncurses.a
-DCURSES_INCLUDE_PATH=/opt/ncurses/include/ncurses -DCURSES_LIBRARY=/opt/ncurses/lib/libncurses.a
指定了ncurses库的头文件路径和库路径。
此时,cmake命令没有错误,生成了Makefile文件。
然后在终端中执行make命令,在编译过程中产生错误,如下图所示:
定位到图中所示的错误:
/opt/ncurses/include/ncurses/curses.h:60:104: fatal error: ncurses/ncursed_dll.h: No such file or directory
由于ncurses库是交叉编译的,可能头文件关系有些问题,导致头文件目录寻找不到,只要把头文件的路径改为绝对路径,问题就可以解决了。
把/opt/ncurses/include/ncurses/curses.h头文件的第60行 #include 改为
#inlcude "opt/ncurses/include/ncurses/ncurses_dll.h"
重新执行make命令,再次产生错误,如下图所示:
定位到图中所示的错误:
/opt/ncurses/include/ncurses/curses.h:1694:89: fatal error: ncurses/unctrl.h: No such file or directory
把/opt/ncurses/include/ncurses/curses.h头文件的第1694行 #include
改为#inlcude "opt/ncurses/include/ncurses/unctrl.h"
重新执行make命令,再次产生错误,如下图所示:
定位到图中所示的错误:
/opt/ncurses/include/ncurses/unctrl.h:54:89: fatal error: ncurses/curses.h: No such file or directory
把/opt/ncurses/include/ncurses/unctrl.h头文件的第54行 #include
改为#inlcude "opt/ncurses/include/ncurses/curses.h"
重新执行make命令,curse库的头文件关联问题解决。
但是产生了新的错误,如下图所示:
这个问题的解决方法很简单,就是把原先编译好的普通PC的MYSQL5.7.18-pc目录下的comp_err文件拷贝到MYSQL5.7.18-arm相同目录下,替换掉MYSQL5.7.18-arm目录下的comp_err,并且要在终端下执行touch comp_err,更新comp_err的时间(这个是必要的)。
重新执行make命令,上面的问题解决,但是又产生新的问题,如下图所示:
这个错误是最困难的,我也是想了很久,参考了网上的一片文章才想出来怎样解决,的确花了不少时间。
定位到途中所示的错误:
/home/fanocean/下载/NitroShare/mysql-5.7.18-arm/mysql-5.7.18/storage/innobase/include/os0atomic.ic:222:2: error: #error "Unsupported platform"
/home/fanocean/下载/NitroShare/mysql-5.7.18-arm/mysql-5.7.18/storage/innobase/include/os0atomic.h:68:1: warning: inline function 'lock_word_t os_atomic_test_and_set(volatile lock_word_t*, lock_word_t)' used but never defined [enabled by default]
我从网上一篇文章看到类似的错误,这篇文章启发了我,里面提及到是宏定义的问题导致的,还包括GCC版本的宏定义问题。大家可以参考一下,但是文章说的比较高深,只是说了一下原因,具体步骤简单提了一下,大牛就是大牛。具体文章链接:
https://m.aliyun.com/yunqi/articles/51094
可以看到上面两句错误提示
#error "Unsupported platform"
,
warning: inline function 'lock_word_t os_atomic_test_and_set(volatile lock_word_t*, lock_word_t)' used but never defined [enabled by default]
,
字面意思是不支持的平台,这个内联函数没有定义。
经过我查看
os0atomic.h
头文件和
os0atomic.ic
,在
os0atomic.ic
中查看到有几个宏定义,
os0atomic.ic
如下所示:
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/os0atomics.ic
The interface to the operating system synchronization primitives.
Created 2012-09-23 Sunny Bains (Split from include/os0sync.ic)
*******************************************************/
#ifdef _WIN32
#include
/* Use inline functions to make 64 and 32 bit versions of windows atomic
functions so that typecasts are evaluated at compile time. Take advantage
that lint is either __int64 or long int and windows atomic functions work
on __int64 and LONG */
/**********************************************************//**
Atomic compare and exchange of unsigned integers.
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
lint
win_cmp_and_xchg_lint(
/*==================*/
volatile lint* ptr, /*!< in/out: source/destination */
lint new_val, /*!< in: exchange value */
lint old_val) /*!< in: value to compare to */
{
# ifdef _WIN64
return(InterlockedCompareExchange64(ptr, new_val, old_val));
# else
return(InterlockedCompareExchange(ptr, new_val, old_val));
# endif /* _WIN64 */
}
/**********************************************************//**
Atomic addition of signed integers.
@return Initial value of the variable pointed to by ptr */
UNIV_INLINE
lint
win_xchg_and_add(
/*=============*/
volatile lint* ptr, /*!< in/out: address of destination */
lint val) /*!< in: number to be added */
{
#ifdef _WIN64
return(InterlockedExchangeAdd64(ptr, val));
#else
return(InterlockedExchangeAdd(ptr, val));
#endif /* _WIN64 */
}
/**********************************************************//**
Atomic compare and exchange of unsigned integers.
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
ulint
win_cmp_and_xchg_ulint(
/*===================*/
volatile ulint* ptr, /*!< in/out: source/destination */
ulint new_val, /*!< in: exchange value */
ulint old_val) /*!< in: value to compare to */
{
return((ulint) win_cmp_and_xchg_lint(
(volatile lint*) ptr,
(lint) new_val,
(lint) old_val));
}
/**********************************************************//**
Atomic compare and exchange of 32-bit unsigned integers.
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
DWORD
win_cmp_and_xchg_dword(
/*===================*/
volatile DWORD* ptr, /*!< in/out: source/destination */
DWORD new_val, /*!< in: exchange value */
DWORD old_val) /*!< in: value to compare to */
{
ut_ad(sizeof(DWORD) == sizeof(LONG)); /* We assume this. */
return(InterlockedCompareExchange(
(volatile LONG*) ptr,
(LONG) new_val,
(LONG) old_val));
}
/** Do an atomic test and set.
@param[in,out] ptr Memory location to set
@param[in] new_val new value
@return old value of memory location. */
UNIV_INLINE
lock_word_t
os_atomic_test_and_set(
volatile lock_word_t* ptr,
lock_word_t new_val)
{
return(InterlockedExchange(ptr, new_val));
}
/** Do an atomic compare and set
@param[in,out] ptr Memory location to set
@param[in] old_val old value to compare
@param[in] new_val new value to set
@return the value of ptr before the operation. */
UNIV_INLINE
lock_word_t
os_atomic_val_compare_and_swap(
volatile lock_word_t* ptr,
lock_word_t old_val,
lock_word_t new_val)
{
return(static_cast(win_cmp_and_xchg_lint(
reinterpret_cast(ptr),
static_cast(new_val),
static_cast(old_val))));
}
#elif defined(HAVE_IB_GCC_ATOMIC_COMPARE_EXCHANGE)
/** Do an atomic test and set.
@param[in,out] ptr Memory location to set
@param[in] new_val new value
@return old value of memory location. */
UNIV_INLINE
lock_word_t
os_atomic_test_and_set(
volatile lock_word_t* ptr,
lock_word_t new_val)
{
lock_word_t ret;
/* Silence a compiler warning about unused ptr. */
(void) ptr;
#if defined(__powerpc__) || defined(__aarch64__)
__atomic_exchange(ptr, &new_val, &ret, __ATOMIC_SEQ_CST);
#else
__atomic_exchange(ptr, &new_val, &ret, __ATOMIC_RELEASE);
#endif
return(ret);
}
/** Do an atomic compare and set
@param[in,out] ptr Memory location to set
@param[in] old_val old value to compare
@param[in] new_val new value to set
@return the value of ptr before the operation. */
UNIV_INLINE
lock_word_t
os_atomic_val_compare_and_swap(
volatile lock_word_t* ptr,
lock_word_t old_val,
lock_word_t new_val)
{
/* Silence a compiler warning about unused ptr. */
(void) ptr;
#if defined(__powerpc__) || defined(__aarch64__)
__atomic_compare_exchange(ptr, &old_val, &new_val, false,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
#else
__atomic_compare_exchange(ptr, &old_val, &new_val, false,
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
#endif
return(old_val);
}
#elif defined(IB_STRONG_MEMORY_MODEL)
/** Do an atomic test and set.
@param[in,out] ptr Memory location to set
@param[in] new_val new value
@return old value of memory location. */
UNIV_INLINE
lock_word_t
os_atomic_test_and_set(
volatile lock_word_t* ptr,
lock_word_t new_val)
{
return(__sync_lock_test_and_set(ptr, new_val));
}
/** Do an atomic compare and set
@param[in,out] ptr Memory location to set
@param[in] old_val old value to compare
@param[in] new_val new value to set
@return the value of ptr before the operation. */
UNIV_INLINE
lock_word_t
os_atomic_val_compare_and_swap(
volatile lock_word_t* ptr,
lock_word_t old_val,
lock_word_t new_val)
{
return(__sync_val_compare_and_swap(ptr, old_val, new_val));
}
#else
#error "Unsupported platform"
#endif /* _WIN32 */
错误提示中的
"Unsupported platform",显然错误产生的原因是没有宏定义才导致的。
os0atomic.ic
的宏定义中有
:
HAVE_IB_GCC_ATOMIC_COMPARE_EXCHANGE
,
IB_STRONG_MEMORY_MODEL
这两个宏定义。
我们在看看
os0atomic.h
的内容,
os0atomic.h
内容如下:
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
briefly in the InnoDB documentation. The contributions by Google are
incorporated with their permission, and subject to the conditions contained in
the file COPYING.Google.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/os0atomic.h
Macros for using atomics
Created 2012-09-23 Sunny Bains (Split from os0sync.h)
*******************************************************/
#ifndef os0atomic_h
#define os0atomic_h
#include "univ.i"
#ifdef _WIN32
/** On Windows, InterlockedExchange operates on LONG variable */
typedef LONG lock_word_t;
#elif defined(MUTEX_FUTEX)
typedef int lock_word_t;
# else
typedef ulint lock_word_t;
#endif /* _WIN32 */
#if defined __i386__ || defined __x86_64__ || defined _M_IX86 \
|| defined _M_X64 || defined __WIN__
#define IB_STRONG_MEMORY_MODEL
#endif /* __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__ */
/**********************************************************//**
Atomic compare-and-swap and increment for InnoDB. */
/** Do an atomic test and set.
@param[in/out] ptr Memory location to set
@param[in] new_val new value
@return old value of memory location. */
UNIV_INLINE
lock_word_t
os_atomic_test_and_set(
volatile lock_word_t* ptr,
lock_word_t new_val);
/** Do an atomic compare and set
@param[in/out] ptr Memory location to set
@param[in] old_val old value to compare
@param[in] new_val new value to set
@return the value of ptr before the operation. */
UNIV_INLINE
lock_word_t
os_atomic_val_compare_and_swap(
volatile lock_word_t* ptr,
lock_word_t old_val,
lock_word_t new_val);
#ifdef _WIN32
/**********************************************************//**
Atomic compare and exchange of signed integers (both 32 and 64 bit).
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
lint
win_cmp_and_xchg_lint(
/*==================*/
volatile lint* ptr, /*!< in/out: source/destination */
lint new_val, /*!< in: exchange value */
lint old_val); /*!< in: value to compare to */
/**********************************************************//**
Atomic addition of signed integers.
@return Initial value of the variable pointed to by ptr */
UNIV_INLINE
lint
win_xchg_and_add(
/*=============*/
volatile lint* ptr, /*!< in/out: address of destination */
lint val); /*!< in: number to be added */
/**********************************************************//**
Atomic compare and exchange of unsigned integers.
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
ulint
win_cmp_and_xchg_ulint(
/*===================*/
volatile ulint* ptr, /*!< in/out: source/destination */
ulint new_val, /*!< in: exchange value */
ulint old_val); /*!< in: value to compare to */
/**********************************************************//**
Atomic compare and exchange of 32 bit unsigned integers.
@return value found before the exchange.
If it is not equal to old_value the exchange did not happen. */
UNIV_INLINE
DWORD
win_cmp_and_xchg_dword(
/*===================*/
volatile DWORD* ptr, /*!< in/out: source/destination */
DWORD new_val, /*!< in: exchange value */
DWORD old_val); /*!< in: value to compare to */
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
(win_cmp_and_xchg_lint(ptr, new_val, old_val) == old_val)
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
(win_cmp_and_xchg_ulint(ptr, new_val, old_val) == old_val)
# define os_compare_and_swap_uint32(ptr, old_val, new_val) \
(InterlockedCompareExchange(ptr, new_val, old_val) == old_val)
/* windows thread objects can always be passed to windows atomic functions */
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
(win_cmp_and_xchg_dword(ptr, new_val, old_val) == old_val)
# define INNODB_RW_LOCKS_USE_ATOMICS
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use Windows interlocked functions"
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
# define os_atomic_increment_lint(ptr, amount) \
(win_xchg_and_add(ptr, amount) + amount)
# define os_atomic_increment_ulint(ptr, amount) \
(static_cast(win_xchg_and_add( \
reinterpret_cast(ptr), \
static_cast(amount))) \
+ static_cast(amount))
# define os_atomic_increment_uint32(ptr, amount) \
(static_cast(InterlockedExchangeAdd( \
reinterpret_cast(ptr), \
static_cast(amount))) \
+ static_cast(amount))
# define os_atomic_increment_uint64(ptr, amount) \
(static_cast(InterlockedExchangeAdd64( \
reinterpret_cast(ptr), \
static_cast(amount))) \
+ static_cast(amount))
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount to decrement. There is no atomic substract function on Windows */
# define os_atomic_decrement_lint(ptr, amount) \
(win_xchg_and_add(ptr, -(static_cast(amount))) - amount)
# define os_atomic_decrement_ulint(ptr, amount) \
(static_cast(win_xchg_and_add( \
reinterpret_cast(ptr), \
-(static_cast(amount)))) \
- static_cast(amount))
# define os_atomic_decrement_uint32(ptr, amount) \
(static_cast(InterlockedExchangeAdd( \
reinterpret_cast(ptr), \
-(static_cast(amount)))) \
- static_cast(amount))
# define os_atomic_decrement_uint64(ptr, amount) \
(static_cast(InterlockedExchangeAdd64( \
reinterpret_cast(ptr), \
-(static_cast(amount)))) \
- static_cast(amount))
#else
/* Fall back to GCC-style atomic builtins. */
/**********************************************************//**
Returns true if swapped, ptr is pointer to target, old_val is value to
compare to, new_val is the value to swap in. */
#if defined(HAVE_GCC_SYNC_BUILTINS)
# define os_compare_and_swap(ptr, old_val, new_val) \
__sync_bool_compare_and_swap(ptr, old_val, new_val)
# define os_compare_and_swap_ulint(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
# define os_compare_and_swap_lint(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
# define os_compare_and_swap_uint32(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
#else
UNIV_INLINE
bool
os_compare_and_swap_ulint(volatile ulint* ptr, ulint old_val, ulint new_val)
{
return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}
UNIV_INLINE
bool
os_compare_and_swap_lint(volatile lint* ptr, lint old_val, lint new_val)
{
return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}
UNIV_INLINE
bool
os_compare_and_swap_uint32(volatile ib_uint32_t* ptr, ib_uint32_t old_val, ib_uint32_t new_val)
{
return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}
#endif /* HAVE_GCC_SYNC_BUILTINS */
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
#if defined(HAVE_GCC_SYNC_BUILTINS)
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
#else
UNIV_INLINE
bool
os_compare_and_swap_thread_id(volatile os_thread_id_t* ptr, os_thread_id_t old_val, os_thread_id_t new_val)
{
return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}
#endif /* HAVE_GCC_SYNC_BUILTINS */
# define INNODB_RW_LOCKS_USE_ATOMICS
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes and rw_locks use GCC atomic builtins"
# else /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
# define IB_ATOMICS_STARTUP_MSG \
"Mutexes use GCC atomic builtins, rw_locks do not"
# endif /* HAVE_IB_ATOMIC_PTHREAD_T_GCC */
/**********************************************************//**
Returns the resulting value, ptr is pointer to target, amount is the
amount of increment. */
#if defined(HAVE_GCC_SYNC_BUILTINS)
# define os_atomic_increment(ptr, amount) \
__sync_add_and_fetch(ptr, amount)
#else
# define os_atomic_increment(ptr, amount) \
__atomic_add_fetch(ptr, amount, __ATOMIC_SEQ_CST)
#endif /* HAVE_GCC_SYNC_BUILTINS */
# define os_atomic_increment_lint(ptr, amount) \
os_atomic_increment(ptr, amount)
# define os_atomic_increment_ulint(ptr, amount) \
os_atomic_increment(ptr, amount)
# define os_atomic_increment_uint32(ptr, amount ) \
os_atomic_increment(ptr, amount)
# define os_atomic_increment_uint64(ptr, amount) \
os_atomic_increment(ptr, amount)
/* Returns the resulting value, ptr is pointer to target, amount is the
amount to decrement. */
#if defined(HAVE_GCC_SYNC_BUILTINS)
# define os_atomic_decrement(ptr, amount) \
__sync_sub_and_fetch(ptr, amount)
#else
# define os_atomic_decrement(ptr, amount) \
__atomic_sub_fetch(ptr, amount, __ATOMIC_SEQ_CST)
#endif /* HAVE_GCC_SYNC_BUILTINS */
# define os_atomic_decrement_lint(ptr, amount) \
os_atomic_decrement(ptr, amount)
# define os_atomic_decrement_ulint(ptr, amount) \
os_atomic_decrement(ptr, amount)
# define os_atomic_decrement_uint32(ptr, amount) \
os_atomic_decrement(ptr, amount)
# define os_atomic_decrement_uint64(ptr, amount) \
os_atomic_decrement(ptr, amount)
#endif
#define os_atomic_inc_ulint(m,v,d) os_atomic_increment_ulint(v, d)
#define os_atomic_dec_ulint(m,v,d) os_atomic_decrement_ulint(v, d)
#define TAS(l, n) os_atomic_test_and_set((l), (n))
#define CAS(l, o, n) os_atomic_val_compare_and_swap((l), (o), (n))
/** barrier definitions for memory ordering */
#ifdef HAVE_IB_GCC_ATOMIC_THREAD_FENCE
# define HAVE_MEMORY_BARRIER
# define os_rmb __atomic_thread_fence(__ATOMIC_ACQUIRE)
# define os_wmb __atomic_thread_fence(__ATOMIC_RELEASE)
# define IB_MEMORY_BARRIER_STARTUP_MSG \
"GCC builtin __atomic_thread_fence() is used for memory barrier"
#elif defined(HAVE_IB_GCC_SYNC_SYNCHRONISE)
# define HAVE_MEMORY_BARRIER
# define os_rmb __sync_synchronize()
# define os_wmb __sync_synchronize()
# define IB_MEMORY_BARRIER_STARTUP_MSG \
"GCC builtin __sync_synchronize() is used for memory barrier"
#elif defined(HAVE_IB_MACHINE_BARRIER_SOLARIS)
# define HAVE_MEMORY_BARRIER
# include
# define os_rmb __machine_r_barrier()
# define os_wmb __machine_w_barrier()
# define IB_MEMORY_BARRIER_STARTUP_MSG \
"Solaris memory ordering functions are used for memory barrier"
#elif defined(HAVE_WINDOWS_MM_FENCE) && defined(_WIN64)
# define HAVE_MEMORY_BARRIER
# include
# define os_rmb _mm_lfence()
# define os_wmb _mm_sfence()
# define IB_MEMORY_BARRIER_STARTUP_MSG \
"_mm_lfence() and _mm_sfence() are used for memory barrier"
#else
# define os_rmb
# define os_wmb
# define IB_MEMORY_BARRIER_STARTUP_MSG \
"Memory barrier is not used"
#endif
#ifndef UNIV_NONINL
#include "os0atomic.ic"
#endif /* UNIV_NOINL */
#endif /* !os0atomic_h */
可以看到第头文件开头中第52行左右的内容:
#if defined __i386__ || defined __x86_64__ || defined _M_IX86 \
|| defined _M_X64 || defined __WIN__
#define IB_STRONG_MEMORY_MODEL
#endif /* __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__ */
从以上的内容可以看出,只有定义了 __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__
才能定义
IB_STRONG_MEMORY_MODEL
但是我们是交叉编译MYSQL,平台是arm,明显上面的内容没有定义arm的宏定义,所以在交叉编译的时候就没有定义
IB_STRONG_MEMORY_MODEL
这个宏,所以后面
os0atomic.ic
中的测试内容就没有进行,执行make命令的时候才不成功。
我不知道arm平台的宏如何定义,不过我用了另外一种方法。如下所示:
#if defined __i386__ || defined __x86_64__ || defined _M_IX86 \
|| defined _M_X64 || defined __WIN__
#define IB_STRONG_MEMORY_MODEL
#else
#define HAVE_ATOMIC_BUILTINS
#endif /* __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__ */
如果不是上面 __i386__ || __x86_64__ || _M_IX86 || _M_X64 || __WIN__没有定义,则定义了
HAVE_ATOMIC_BUILTINS
这个宏,这个宏不是随便定义的,在文章前面我介绍到的大牛文章中对此有介绍,读者可以了解一下。
在
os0atomic.ic
中,把
#elif defined(IB_STRONG_MEMORY_MODEL)
改为
#elif defined(HAVE_ATOMIC_BUILTINS)
,把
IB_STRONG_MEMORY_MODEL
这个宏改为
HAVE_ATOMIC_BUILTINS
,这样应该可以了。
在终端中再次执行make命令,前面的问题解决,但是又产生新问题,如下图所示:
定位到错误/home/fanocean/下载/NitroShare/mysql-5.7.18-arm/mysql-5.7.18/storage/innobase/lock/lock0lock.cc:1650:67: error: 'os_compare_and_swap_thread_id' was not declared in this scope
os_compare_and_swap_thread_id()
这个函数没有声明.
经过我查找,发现在
os0atomic.h
头文件中的第262行左右找到
os_compare_and_swap_thread_id()
这个函数的实现,在这个函数的前面有编译条件如下:
-------------------------------------------------------------------------------------------------------------------------
# ifdef HAVE_IB_ATOMIC_PTHREAD_T_GCC
#if defined(HAVE_GCC_SYNC_BUILTINS)
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
#else
UNIV_INLINE
bool
os_compare_and_swap_thread_id(volatile os_thread_id_t* ptr, os_thread_id_t old_val, os_thread_id_t new_val)
{
return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}
------------------------------------------------------------------------------------------------------
但是交叉编译工具GCC中没有这两个宏,所以运行不了,解决方法是改为如下:
-------------------------------------------------------------------------------------------------------------
# ifdef HAVE_ATOMIC_BUILTINS //HAVE_IB_ATOMIC_PTHREAD_T_GCC
#if defined(HAVE_ATOMIC_BUILTINS) //defined(HAVE_GCC_SYNC_BUILTINS)
# define os_compare_and_swap_thread_id(ptr, old_val, new_val) \
os_compare_and_swap(ptr, old_val, new_val)
#else
UNIV_INLINE
bool
os_compare_and_swap_thread_id(volatile os_thread_id_t* ptr, os_thread_id_t old_val, os_thread_id_t new_val)
{
return __atomic_compare_exchange_n(ptr, &old_val, new_val, 0,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------
这样修改之后,在终端中继续执行make命令,就可以继续运行下去。
(但是这样修改有没有产生什么其他作用,暂时还不清楚)
还没有结束,解决了前面的问题,还有新问题产生,不过下面编译的问题都是比较容易解决的。
产生错误如下图所示:
这个问题容易解决,把原来编译好的普通PC的
MYSQL5.7.18-pc目录
中相同的gen_lex_hash文件拷贝到
MYSQL5.7.18-arm的相同目录中,替换掉MYSQL5.7.18-arm目录中的
gen_lex_hash
,并且执行 touch gen_lex_hash更新文件的时间,就可以继续执行make命令了。
又产生错误如下图所示:
跟上面的解决方法一样,
把原来编译好的普通PC的
MYSQL5.7.18-pc目录
中相同的comp_sql文件拷贝到
MYSQL5.7.18-arm的相同目录中,替换掉MYSQL5.7.18-arm目录中的
comp_sql
,并且执行 touch comp_sql更新文件的时间,就可以继续执行make命令了。
又产生错误如下图所示:
跟上面的解决方法一样,
把原来编译好的普通PC的
MYSQL5.7.18-pc目录
中相同的gen_lex_token文件拷贝到
MYSQL5.7.18-arm的相同目录中,替换掉MYSQL5.7.18-arm目录中的
gen_lex_token
,并且执行 touch
gen_lex_token
更新文件的时间,就可以继续执行make命令了。
又产生错误如下图所示:
跟上面的解决方法一样,
把原来编译好的普通PC的
MYSQL5.7.18-pc目录
中相同的protoc文件拷贝到
MYSQL5.7.18-arm的相同目录中,替换掉MYSQL5.7.18-arm目录中的
protoc
,并且执行 touch
protoc
更新文件的时间,就可以继续执行make命令了。
编译完成执行sudo make install命令。如下图所示:
至此,交叉编译MYSQL5.7.18就完成了,但是要移植到arm开发板还有很多工作要做。