移植LAMP服务器到嵌入式平台

时间:2022-06-30 16:29:22

一、工具准备工作 

    要想在ARM平台上移植一套Apache+Msql+PHP的Web型服务器。

所用物理机系统: Ubuntu 14.04 LTS(64位)

交叉编译环境:   arm-linux-gnueabihf-gcc-4.7.3(32位)

                 gcc-4.8.4(64位)

所需源码:       Httpd-2.4.3.tar.gz          

 Pcre-8.31.tar.gz

 Apr-1.4.6.tar.gz

 Apr-util-1.4.1.tar.gz

 Mysql-5-1-51.tar.gz

 Ncurses-5.6.tar.gz 

 PHP-5.6.16.tar.gz

 Libxml-2.7.2.tar.gz

 Zlib-1-2-7-tar.gz

目标机器环境:   AM335X(ARM)

其中:U-boot和内核是用TI的SDK工具包,然后用arm-linux-gnueabihf-交叉编译链编译出的;文件系统是用Busybox制作的最小的文件系统,当然,交叉编译工具和内核是一样的,必须是同一个编译工具。这里我就栽了一个跟头,没有同一内核和文件系统还有应用软件的编译工具,导致最后编译出来的内核或应用程序无法正常工作。所以在此强调,内核和其他应用软件的编译工具必须统一,从道到尾都用同一个。U-boot可以用任何交叉编译器编译,可以跟内核的不一样,也能跑的起来,因为uboot只是一个引导系统启动的一个程序,启动后就没他的事了,就是操作系统在管理了。但是,应用程序是在操作系统上跑的,文件系统也一样,所以编译应用软件的编译工具必须跟内核的一样,否者这个应用程序无法在该系统上跑。

 

二、编译安装Apache  

2.1、下载安装包:

要安装Apache,需要先下载好这四个源码包:

httpd-2.4.3.tar.gz  、Pcre-8.3.1.tar.gz、Apr-1.4.6.tar.gz、 Apr-util-1.4.1.tar.gz

当然并不是只有这些版本的源码可以安装,还有很多可以的,我尝试了,4个版本的Apache,最后发现2.0以上的版本才能编译通过(对于我的物理机上的交叉编译链来说)。因为apache2.0以下的版本比较久,所以我下载了一个也比较过时的交叉编译编译工具arm-linux-gcc4.6.3来试了一下,是可以编译通过的,但是在我的内核上跑不起来,原因就是上面说的内核和应用程序的编译工具不统一(内核的编译工具是arm-linux-gnueabihf-gcc)。所以最后我选择安装2.0以上的版本。 

2.2、 安装开发包

假设我已经创建好了/home/ccj/works目录下了,把下载好的安装包都copy到该目录下,然后解压。会得到httpd-2.4.3、pcre-8.3.1、apr-1.4.6、apr-util-1.4.1。

2.2.1、本地编译  (X86_64平台)

1. 安装pcre-8.3.1

    #tar –zxvf pcre-8.31.tar.gz

    #cd  pcre-8.31

    #./configure-–prefix=/home/ccj/install/local/pcre

    #make

    #make install

2、安装apr 

    # tar –zxvfapr-1.4.6.tar.gz

    #cd apr-1.4.6

    #./configure --prefix=/home/ccj/install/local/apr

    #make

    #make install

3、安装apr-util

    #tar –zxvfapr-util-1.4.1.tar.gz

    #cd apr-util-1.4.1

    #./configure --prefix=/home/ccj/install/local/apr-util --with-apr=/home/ccj/install/local/apr

    #make

    #make install 

4、 安装httpd

   #tar –zxvfhttpd-2.4.3.tar.gz

    #cd  httpd-2.4.3

    #./configure --prefix=/home/ccj/install/apache   --with-pcre=/home/ccj/install/local/pcre      --with-apr=/home/ccj/install/local/apr  --with-apr-util=/home/ccj/install/local/apr-util

    #make

make 完之后把httpd-2.4.3改名为httpd-pc。目的是为了让在当前的目录下从新解压一个httpd-2.4.2出来,这个是用来进行交叉编译的,但是交叉编译的时候会用到一个执行脚本,而这个脚本必须是在物理机上执行的,所以交叉编译出来的那个不能在物理机上执行,才需要将刚刚在本地物理机上编译完成的httpd-pc中拷贝过来,然后将它覆盖替换掉,但是为了保证相对目录的位置不变,所以才需要将刚刚本地编译完的那个改名为httpd-pc,然后再在当前目录下在解压一个httpd-2.4.3。

    好了,本地编译到此完成!

2.2.2、交叉编译  (ARM平台)

1、 安装pcre

    #cd  pcre-8.31

    #make clean

    #./configure --prefix=/home/ccj/installl/pcre  --host=arm-linux-gnueabihf   

    #make

    #make install

2、安装apr 

     #cd apr-1.4.6

    #make clean

     # ./configure --prefix=/home/ccj/installl/apr --host=arm-linux-gnueabihf  ac_cv_file__dev_zero=yes   ac_cv_func_setpgrp_void=yes  apr_cv_tcp_nodelay_with_cork=yes  ac_cv_sizeof_struct_iovec=8            --cache=arm-linux.cache

    #make 

    #make install

这里简要说明一下如果不添加某些选项会出现的错误提示及一些需要特别注意的地方(这里按照我所记录的错误出现的顺序说明,而不是按上面选项的顺序):

①如果不添加ac_cv_file__dev_zero=yes(注意file和dev之间是两个下划线),则会出现:

   check for /dev/zero... configure:error:cannot check for file existence when cross compile 的错误

②如果不添加ac_cv_func_setpgrp_void=yes,则会出现:

   checking whether setpgrp takes no argument... configure: error: cannot check setpgrp when crosscompiling   的错误

③选项--cache=arm-linux.cache中,arm-linux.cache为自己建立编写的文件(在编译过程中内容会被修改),在建立时需要自己写入如下内容:

④  apr_cv_process_shared_works=yes

    apr_cv_mutex_robust_shared=yes

 如果不写入第一项,则会出现:

       checking for working PROCESS_SHARED locks... configure:error: in `.../apr-1.4.6':

       configure:error: cannot run test program while cross compiling  See `config.log' for more details

 如果不写入第二项,则会出现:

        checking for robust cross-process mutex support... configure: error: in `.../apr-1.4.6' configure: error: cannot run test program while cross compiling See `config.log' for more details的错误

在以后为开发板配置软件包时遇到这种错误:configure:error:cannot run test program while crosscompiling,应该都可以通过这种方法解决。但是我还有一种方法,也是我比较喜欢的方式,可以避免带那么多的参数。因为这些错误产生的原因在于这里在configure运行配置的过程中要运行几个测试程序来检验一些配置,但在此处指定了编译时采用的编译器是交叉编译链,这几个测试程序都是经过交叉编译链编译产生的,而在宿主机系统上无法运行这些程序。因此,我就在configure文件里把这些产生测试程序的地方把他们注释掉,这样执行./condigure的时候就不会生成测试程序了,就可以通过编译了。

⑤如果不添加ac_cv_sizeof_struct_iovec=8选项,则会在使用make指令时出现:

    ./include/apr_want.h:95: error: redefinition of 'struct iovec'

make[1]: *** [passwd/apr_getpass.lo] 错误

在添加了ac_cv_sizeof_struct_iovec=8选项后,还需要对configure文件进行一下修改,搜索apr_ssize_t可以定位到下面一段代码:

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which format to use for apr_ssize_t" >&5

$as_echo_n "checking which format to use for apr_ssize_t... " >&6; }

if test -n "$ssize_t_fmt"; then

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %$ssize_t_fmt" >&5

$as_echo "%$ssize_t_fmt" >&6; }

elif test "$ac_cv_sizeof_ssize_t" = "$ac_cv_sizeof_int"; then

    ssize_t_fmt="d"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %d" >&5

$as_echo "%d" >&6; }

elif test "$ac_cv_sizeof_ssize_t" = "$ac_cv_sizeof_long"; then

    ssize_t_fmt="ld"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %ld" >&5

$as_echo "%ld" >&6; }

else

    as_fn_error $? "could not determine the proper format for apr_ssize_t" "$LINENO" 5

fi

将中间添加一段代码(红色标注),修改为

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which format to use for apr_ssize_t" >&5

$as_echo_n "checking which format to use for apr_ssize_t... " >&6; }

if test -n "$ssize_t_fmt"; then

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %$ssize_t_fmt" >&5

$as_echo "%$ssize_t_fmt" >&6; }

elif test "$ac_cv_sizeof_ssize_t" = "$ac_cv_sizeof_int"; then

    ssize_t_fmt="d"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %d" >&5

$as_echo "%d" >&6; }

elif test "$ac_cv_sizeof_ssize_t" = "$ac_cv_sizeof_long"; then

    ssize_t_fmt="ld"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %ld" >&5

$as_echo "%ld" >&6; }

elif test "$ac_cv_sizeof_ssize_t" = "$ac_cv_sizeof_long_long";then

    ssize_t_fmt="lld"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %lld" >&5

$as_echo "%lld" >&6; }

else

    as_fn_error $? "could not determine the proper format for apr_ssize_t" "$LINENO" 5

fi

搜索apr_size_t可以定位到下面一段代码

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which format to use for apr_size_t" >&5

$as_echo_n "checking which format to use for apr_size_t... " >&6; }

if test -n "$size_t_fmt"; then

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %$size_t_fmt" >&5

$as_echo "%$size_t_fmt" >&6; }

elif test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_int"; then

    size_t_fmt="d"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %d" >&5

$as_echo "%d" >&6; }

elif test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_long"; then

    size_t_fmt="ld"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %ld" >&5

$as_echo "%ld" >&6; }

else

    as_fn_error $? "could not determine the proper format for apr_size_t" "$LINENO" 5

fi

将中间添加一段代码(红色标注),修改为:

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which format to use for apr_size_t" >&5

$as_echo_n "checking which format to use for apr_size_t... " >&6; }

if test -n "$size_t_fmt"; then

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %$size_t_fmt" >&5

$as_echo "%$size_t_fmt" >&6; }

elif test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_int"; then

    size_t_fmt="d"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %d" >&5

$as_echo "%d" >&6; }

elif test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_long"; then

    size_t_fmt="ld"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %ld" >&5

$as_echo "%ld" >&6; }

elif test "$ac_cv_sizeof_size_t" = "$ac_cv_sizeof_long_long"; then

    size_t_fmt="lld"

    { $as_echo "$as_me:${as_lineno-$LINENO}: result: %lld" >&5

$as_echo "%lld" >&6; }

else

    as_fn_error $? "could not determine the proper format for apr_size_t" "$LINENO" 5

fi

        如果什么修改也不做,则会出现:

checking which format to use for apr_ssize_t... configure:error:could not determine the proper format for apr_ssize_t的错误

        如果只做了第一个修改,则会出现:

checking which format to use for apr_size_t... configure:error:could not determine the proper format for apr_size_t的错误

这是apr源代码包本身有的bug,这样修改后,在最后编译httpd时,会出现一些warning,大概意思是说参数类型为pid_t的地方,出现的参数类型为long long,但pid_t的类型本身就是unsigned int,因此应该是没有问题的。



3、安装apr-util   

   # cd   apr-util-1.4.1

   # make clean

   #./configure --prefix=/home/ccj/install/apr-util--with-apr=/home/ccj/install/apr  --host=arm-linux-gnueabihf

   # make

   #  make install

4、 安装httpd

   #tar –zxvfhttpd-2.4.3.tar.gz      

   #cd httpd-2.4.3

   #./configure

--prefix=/home/ccj/install/apache   --with-pcre=/home/ccj/install/pcre    --with-apr=/home/ccj/install/apr         --with-apr-util=/home/ccj/install/apr-util   --host=arm-linux-gnueabihfap_cv_void_ptr_lt_long=no   --enable-so       --enable-cgi    LDFLAGS=-lpthread   --with-mpm=prefork

①如果不添加ap_cv_void_ptr_lt_long=no选项,则会出现:configure: error: Size of "void *" is less than size of "long"的错误

②如果不添加--with-mpm=prefork选项,则在启动httpd服务器时会出现闪退,无法正常启动。

   #make

make的时候会出现

util.c: In function 'ap_find_token':

util.c:1434: error: 'test_char_table' undeclared (first use in this function)

util.c:1434: error: (Each undeclared identifier is reported only once

util.c:1434: error: for each function it appears in.)

这样的错误提示,意思就是说编译中间生成的程序需要马上在Ubuntu上执行,当时Ubuntu没法运行ARM下的二进制文件,所以报错了。解决的办法就是到这个文件的所在文件夹下面,(如果不知道这个文件在源码包的那个文件夹下面的话,那么对整个源码包进行文件搜索,你想要的文件马上就会出现在你的眼前),所以用这个方法找文件在源码包的那个位置是很方便的,我就不累赘这些文件到底在哪个哪个文件目录了,下面的亦然。

那么这个问题的解决方法呢!就是先把交叉编译生成的ARM平台上运行的二进制执行文件给删除了,然后再从我们上面通过本地编译生成的在Ubuntu平台能运行的x86_64的同名文件给拷贝到此。但是,还没结束,接下来才是最关键的,这个时候要执行这条语句

touch -m  /home/ccj/works/httpd-2.4.3/server/gen_test_char

上面的命令是改变gen_test_char的最后修改时间,这样做的目的是告诉编译器gen_test_char已经是最新的了,不要重新生成它,否则编译器检查gen_test_char和它的依赖文件的最后修改时间会发现gen_test_char比它的依赖文件更旧,就会重新交叉编译生成它,这样不管我们做几次覆盖的工作错误都还会再现。

  #make

  #make install

到此,apache成功编译出来了。

2.2.3、移植到开发板及复制共享库

1、将httpd-4.2.3编译好的/home/ccj/install/apache文件夹拷贝到开发板对应的/home/ccj/install目录下,为减少占用资源,可以将manual目录删掉。拷贝到开发板上相同的安装目录下这点很重要,否者会出现很多奇葩的错误,比如个别文件采用的是绝对文件目录的话,如果你改变了他的文件路径,它就找不着北了。

2、复制一些共享库到开发板文件系统的/lib目录下,否则会启动不了httpd服务器,像以下错误:

①error while loading shared libraries: libpcre.so.1:cannot open shared object file:No such file for directory                       

解决方法:cp  /home/ccj/install/pcre/lib/libpcre.so*  /lib

②error while loading shared libraries: libaprutil-1.so.0:cannot openshared object file:No such file for directory                       解决方法:cp   /home/ccj/install/apr-util/lib/libaprutil-1.so* /lib③error while loading shared libraries: libexpat.so.0:cannot open shared object file:No such file for directory                       

解决方法:cp    /home/ccj/install/apr-util/lib/libexpat.so* /lib

④error while loading shared libraries: libapr-1.so.0:cannot open shared object file:No such file for directory                        

解决方法:cp   /home/ccj/install/apr/lib/libapr-1.so*  /lib

如果还有其他缺少的库,那请就根据linux提示的错误信息,从物理机上用交叉编译出来的源码包里找到这个缺失的库,然后copy到开发板的/lib目录下面。

2.2.4、配置httpd.conf

1、apache拒绝使用root用户运行。所以你需要增加一个用户和用户组,我们可以使用用户名和用户组名分别为nobody和nogroup。没有的话,就在/etc/passwd和/etc/group两个文件中添加。这样我们就在httpd.conf中的用户和组修改为nobody和nogroup,具体来说就是在ARM Linux根文件系统上立/etc/passwd和/etc/group两个文件,它们的内容可以如下:

/etc/passwd

root::0:0:root:/:/bin/ash

nobody::65534:65533:nobody:/:/bin/ash



/etc/group

nobody::65533:

nogroup::65534:nobody

root::0:

users::100

2、修改http.conf                       

Listen 0.0.0.0:80

Listen 80

User nobody

Group nobody

ServerAdmin yuaf059@nenu.edu.cn

ServerName localhost:80

主要配置这几个地方

2.2.5、疑难杂症   

    由于我的文件系统使用busybox制作出来的最简单的文件系统,最简单有个好处,就是开机速度超快,但因为文件系统太简单了,很多功能都得自己重新加上去,比如设定固定IP地址,比如NFS文件系统,这些都需要自己手动创建,有时候因为缺少个别重要的系统文件,会导致一些应用程序跑不起来,比如这里的apache。就遇到这个问题。 
    当我启动的Apache的时候,系统提示出现这样的错误

 [:crit] [pid 0] (2)No such file or directory: AH00141: Could not initialize random number generator

    最后找了很久,发现问题出在我制作的跟文件系统下面缺少了/dev/random 和 /dev/urandom 这两个文件,这两个是系统级别的文件,没有的话很多程序会跑不起来

    解决办法:

在/dev下面创建这两个文件:用下面这三条语句轻松搞定

 

 #mknod -m 644 /dev/random     c   1   8  

 #mknod -m 644 /dev/urandom    c   1   9 

 #chown root:root /dev/random/dev/urandom

OK!现在可以开启你梦寐以求的Apache了,在/home/cch/install/apache/bin/ 下,执行./apachectl这个文件,然后Apache就在你的开发板上跑起来了,在开发板上输入top命令,

PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND

  1       0       root        S     2088  0.4   0  0.0 init

  957     1       root        S     5012  0.9   0  0.0 /home/ccj/install/apache/bin/httpd

  958   957    nobody     S     5012  0.9   0  0.0 /home/ccj/install/apache/bin/httpd

  959   957    nobody     S     5012  0.9   0  0.0 /home/ccj/install/apache/bin/httpd

  960   957    nobody     S     5012  0.9   0  0.0 /home/ccj/install/apache/bin/httpd

  961   957    nobody     S     5012  0.9   0  0.0 /home/ccj/install/apache/bin/httpd

  962   957    nobody     S     5012  0.9   0  0.0 /home/ccj/install/apache/bin/httpd

出现上面这样的结果,表示已经成功了。从这里可以清楚的看出,Apache不是用root用户启动的,而是用nobody启动的,而且Apache的子进程都是由“957”这个父进程创建出来的,而“957”的父进程是“1”;“1”进程又是init进程,系统的元老级的进程:init。

 

三、编译安装Mysql

3.1、下载安装包:

要安装mysql,需要先下载好这两个源码包

ncurses-5.6.tar.gz        myqsl-5.1.51.tar.gz

3.2、 安装开发包

假设我已经创建好了/home/ccj/works目录下了,把下载好的安装包都copy到该目录下,然后解压。会得到    ncurses-5.6  、myqsl-5.1.51。

3.2.1、编译本地版本mysql

#cd mysql-5.1.51

#./configure -prefix=/usr/local/mysql 

#make

①、运行configure

如果出现以下提示信息(没有出错就不用管):

checking for termcap functions library… configure: error: No curses/termcap library found

那么就安装libncurses5-dev进行解决: root@ubuntu:/opt/lib/mysql-5.1.51# apt-get install libncurses5-dev

②、make完成后,将这个文件夹改名为mysql-5.1.51-pc留作备用。

3.2.2、交叉编译ARM平台下的mysql  

要交叉编译MySQL -ARM版本,首先我们得先得到一个交叉编译过的libncurses.a的库,所以为了方便,我们先做这一步。

(1)、交叉编译ncurses-5.6.tar.gz

# cd ncurses-5.6

#./configure -host=arm-linux-guneabihf  -prefix=/home/ccj/install/ncurse  –enable-static

# make

# make install

(2)、重新解压mysql-5.1.51.tar.gz得到mysql-5.1.51

(3)、修改configure,注释掉不支持交叉编译的部分

找到所有如下语句: 

①. if test"$cross_compiling" = yes; then

②. { { $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 moredetails." >&2;}

⑥. { (exit 1); exit 1; }; }; }

⑦. else

修改成 

①. if test "$cross_compiling"= yes; then

②. echo “skip corss_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 moredetails." >&2;}

⑧. #{ (exit 1); exit 1; }; }; }

⑨. else

注意:原文有4处这样的地方,都要找出来注释掉。或者可以用上面提到的方法,把   ①. if test "$cross_compiling" =yes; 中的yes改为no

(4)、交叉编译MySQL

    有了这些准备工作,这个时候就可以交叉编译MySQL了。

①、配置configure ./configure   --host=arm-linux-gnuaebihf  --enable-static       --with-named-curses-libs=/home/ccj/install/ncurses/lib/libncurses.a    --prefix=/home/ccj/install/mysql  --without-debug    --without-docs --without-man  --without-bench  --with-charset=gb2312  --with-extra-charsets=ascii,latin1,utf8

②、make

make的时候会出现这样的错误

make[2]: Leaving directory `/opt/mysql-5.5.3-m3/sql'

./gen_lex_hash > lex_hash.h-t

/bin/sh: ./gen_lex_hash: cannot execute binary file

这个时候就需要将刚才我们编译好的PC版本的$mysql\sql\目录下面的gen_lex_hash,然后cp到现在交叉编译时对应的$mysql\sql\目录覆盖即可。覆盖完成后不要急于make,这时输入如下命令:touch –mysql/gen_lex_hash

然后再执行make

   若出现错误:

sql_parse.cc:5432:21: operator '<' has no left operand

解决办法:

这是由于宏变量STACK_DIRECTION没有定义初值,网上查找资料发现arm中定义STACK_DIRECTION为1,所以找到sql_parse.cc文件,将第5432行的前面一行加入#define STACK_DIRECTION 1

③、make install

至此,mysql已经编译完成,接下来就是移植和配置了。

 

3.3、移植mysql到ARM平台

  

a) 拷贝编译生成的mysql到/home/ccj/installmysql开发板的相同目录下

b) 到源码中拷贝配置文件模版

   将PC上的/home/ccj/works/mysql-5.1.51/support-files/my-medium.cnf这个文件copy一份到开发板的/etc下,并改名字为my.cnf

这里的my.cnf存放的路径是按照手册上的建议,前面编译pc版本的MySQL中所述的路径并非全局配置。该文档的注释中说:“# You can copy this file to /etc/my.cnf to set global options, mysql-data-dir/my.cnf to set server-specific options (in this installation this directory is /usr/local/mysql/var) or ~/.my.cnf to set user-specific options.”该配置文件的修改详见mysql5.1的英文手册的4.2.3.3. Using Option Files节中的叙述。 

数据目录是在:/var/lib/mysql (默认)

安装目录是在:/usr/local/mysql (默认)

但是我这里的安装目录是/home/ccj/install/mysql,跟默认的不一样,所以要到配置文件里面去更改一下,数据目录我改到/home/ccj/install/var下。

c)手动建立mysqld/mysqld.pid,手工建立: (这一步不需要,制定到/tmp/mysqld.pid就行)

     #mkdir /home/ccj/install/mysql/var/run/mysqld 
     #touch /home/ccj/install/mysql/var/run/mysqld/mysqld.pid 
这一步不知道是不是必须的。但我这样做了。

d) 到源码中拷贝启动文件 
   /home/ccj/works/mysql-5.1.51/support-files/mysql.server 这个文件copy一份到开发板的/etc/init.d/目录下,并改名为mysqld

  修改该mysqld 

  详见手册中4.3.1. mysqld — The MySQL Server的叙述 
  加上了basedir和datadir,

  还有pid-file=/tmp/mysqld.pid 

  还有service-pid-file=/tmp/mysqld.pid 

  修改完后,要给新的mysqld附以足够的权限: Chmod +x mysqld 

e) 设置软连接使mysql,  mysqldump,  mysqladmin这三个命令能在开发板的shell中直接运行 
     # ln -s /home/ccj/install/mysql/bin/mysql /usr/bin 
     #ln -s /home/ccj/install/mysql/bin/mysqldump /usr/bin 

     #ln -s /home/ccj/install/mysql/bin/mysqladmin /usr/bin

     其他的还有:链接库文件

     ln -s /home/ccj/install/mysql/lib/mysql/libmysqlclient.so.16/lib

 

f) 在开发板开启MySQL服务 

开发板不支持service指令,所以service mysql start无效。

采用的方法是运行./etc/init.d/mysqld start 
但最初运行该指令后出现下面的错误: 
    Starting MySQL... ERROR! Manager of pid-file quit without updating file. 
    困扰我好久,到开发板目录/var/lib/mysql下查阅错误日志文件[hostname].err,在我的系统中该错误日志文件为EmbedSky.err,从中看到下面的记录: 
        150713 21:04:49 [ERROR] Fatal error: Can't change to run as user 'mysql' ;  Please check that the user exists! 
     可能的原因是:在arm的linux上无法执行groupadd mysql,因此需要采用如下方法解决该问题: cd /home/ccj/install/mysql/var/lib/mysql 
     ls –la可以看到里面的属性中没有mysql,于是使用下面的命令: adduser mysql 
     chown mysql:mysql -R /var/lib/mysql 
然后开启mysql服务,还是出现了ERROR! Manager of pid-file quit without updating file.又查看EmbedSky.err日志,其中多了一条: 
        150714  2:48:04 [ERROR] Can't start server: Bind on TCP/IP port: Address already in use 
        150714  2:48:04 [ERROR] Do you already have another mysqld server running on port: 3306 ? 
     很显然是因为已经有mysql的进程尝试打开3306端口,因此就被占用了,需要杀进程,索性重启开发板,然后运行/etc/init.d/mysqld start,可以完美打开。 

3.4、测试ARM平台下的MySQL 

a) mysqladmin -uroot   -p123456   最后一项为我的密码   (设置密码) 

b) mysql -h  127.0.0.1  -uroot  -p123456或mysql -h  localhost  -uroot  -p123456这样便可以进入mysql环境。 

c) mysql>show databases;

   mysql>create databasestable1;

   mysql>use table1;

   mysql>create tablestudent(id int(4) not null primary key auto_increment,stuname char(20));

   mysql> insert intostudent(stuname) values('Tom');

如果这个成功了,那么后面就可以用这个来测试PHP与mysql能否协调工作了!到此,mysql也算成功移植上去了。

 

 

 

四、编译安装PHP

4.1、下载安装包:

要安装mysql,需要先下载好这三个源码包

PHP-5.6.16.tar.gz     Libxml-2.7.2.tar.gz     Zlib-1.2.7-tar.gz

4.2、 安装开发包

假设我已经创建好了/home/ccj/works目录下了,把下载好的安装包都copy到该目录下,然后解压。会得到php.5-6-16、libxml-2.7.2、zlib-1.2.7。

4.2.1、编译本地版本PHP

 #cd php.5-6-16

 #./configure -prefix=/usr/local/php

 # make

 make完成后,将这个文件夹改名为php.5-6-16-pc留作备用。

4.2.2、交叉编译ARM平台的PHP

(1)、交叉编译安装zlib

#cd  zlib-1.2.7

#CC=arm-linux-gnueabihf-gcc  ./configure  --prefix=/home/ccj/install/zlib --host=arm-linux-gnueabihf  --enable-shared

#make 

#make  install

(2)、交叉编译安装libxml

#cd  libxml-2.7.2

#CC=arm-linux-gnueabihf-gcc  ./configure  --prefix=/home/ccj/install/libxml --host=arm-linux-gnueabihf  --enable-#shared

#make 

#make  install

(3)、交叉编译PHP

从新解压php-5.6.16.tar.gz,得到php.5-6-16源码

①、#cd php.5-6-16

②、#CC=arm-linux-gnueabihf-gcc \

./configure  --host=arm-linux-gnueabihf \

--with-apxs2=/home/ccj/install/apache/bin/apxs  \

--prefix=/home/ccj/install/php_arm \

--enable-pdo  \

--with-mysql=/home/ccj/install-p/usr/local/mysql  \

--with-mysqli=/home/ccj/install-p/usr/local/mysql/bin/mysql_config \

--with-pdo-mysql   \

--with-zlib=/home/ccj/install/zlib  \

--with-libxml-dir=/home/ccj/install/lib  \

--enable-opcache=no \

--without-iconv 

上面的apahce和mysql都是基于ARM的版本

执行configure时,可能会出现cannot run test program while cross compiling的错误,然后我查看了一下configure,发现只要把这四个地方的yes改为no即可。然后有些地方用了gcc -V的参数,是不能通过的,所以改为-v  "可能需要注意一下大小写"

③、接着#make

make的时候出现的经典的错误是上面提到的

generating phar.php/home/jason........./sapi/cli/php:1:Syntaxerror:word unexpected (expecting “)”)
或者
Generating phai.phai/home/jason/........./sapi/cli/php:1;syntax  error:word unexpected (expecting “)”)

    这个时候就需要本地编译出来的PHP来帮忙了。我将基于PC平台下编译的/sapi/cli/php拷贝到基于ARM的这个地方,当然先得将这里原来的备份改名成php-back,后面这个php-back还会用到的。这样make就不会报错了。

    当然,这个时候还不能急着make,因为我们刚刚替换的php如果make就会把我们刚刚替换的那个php给冲掉,怎么解决的呢!当然是先touch -m php 一下这个文件,目的是告诉编译器不要去跟新这个php文件。

④、然后#make test

⑤、最后#make install

在make install的时候我还遇到很多莫名奇妙的问题,说我在apache的安装目录下缺失了很多apr和apr-util的头文件,当然,我把这些文件copy到我指定的apache安装目录下面。OK。这样就能make install 了。

4.3、移植PHP到ARM平台

a)将交叉编译生成的php拷贝到开发板的相同目录下面,将源码包的php-back文件拷贝到/home/ccj/install/php/bin下,并改名为php;拷贝php.ini-development文件拷贝到/home/ccj/install/php/lib下并改名为php.ini。

b)修改apache下的配置文件/home/ccj/install/apache/conf/httpd.conf

       DirectoryIndex  index.html

       DirectoryIndex  index.php

       DirectoryIndex  index.php3

       DirectoryIndex  index.phtml

       ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"

       ScriptAlias /php5/ "/home/ccj/install/php/bin/"

       AddType application/x-tar .tgz

       AddType application/x-httpd-php .php3
        AddType application/x-httpd-php .php
        AddType application/x-httpd-php .phtml

红色的部分是需要添加的,这样apache就能支持php了。

 

五、测试Apache、PHP、MySQL的总体功能

1、在apache的htdocs下建立一个php文件php_test.php,里面的内容如下:

<?php 

phpinfo();  

?>

然后在浏览器里输入http://127.0.0.1/php_test.php

如果出现php的相关配置,则证明Apache能成功启动调用PHP,如果什么都没有输出,说明失败!

2、在apache的htdocs下建立一个php文件mysql_test.php,里面的内容如下:

<?php 

$mysqli=new mysqli();

$mysqli->connect('localhost','root','123456','table1');

$sqlstr='select * from student';// 创建查询

$result=$mysqli->query($sqlstr);//发送查询给MySql

while($row=$result->fetch_object())

{

   $name=$row->stuname;

    echo $name;

}

?>

然后在浏览器里输入http://127.0.0.1/mysql_test.php

如果能在浏览器上出现

Tom

这个我们在mysql里面存放的一条记录,那么证明PHP是可以成功调用MySQL数据库的。到此,整个移植过程就顺利完成了。可能你还会遇到其他我没有提及到的错误,这时候你就要自己去百度咯,但要坚信,方法总是比问题多的。