• 记录交叉编译环境配置--海思开发板的 嵌入式nginx和 php的移植



    文章比较水,并没有没解决什么实际问题,有点不好意思发布。但好像又记录了不少交叉编译配置的思路,所以还是记录下来,希望有更多大佬能给支支招,共同进步!

    一些交叉编译的配置环境思路分享:

    想指明第三方库所在路径,有四种方法:,

    • 1,添加xx.pc文件路径export PKG_CONFIG_PATH=/xxx:$PKG_CONFIG_PATH
      指定搜索路径export LD_LIBRARY_PATH=/yourdir/:$LD_LIBRARY_PATH
    • 2,在 /etc/ld.so.conf 文件中添加库的搜索路径。将库文件的绝对路径/lib直接写进去就OK。
    • 3,丢到编译器的默认搜索路径。使用 arm-前缀-gcc -print-file-name=libpthread.so 来找到编译器的默认路径
    • 4,在configure阶段,添加-LDFLAG 增加编译选项给编译器直接增加搜索路径

    一篇文章看懂上述部分名词和工具的释义

    P:php

    这里我用的是php7-2.15 点击官网下载其他版本
    由于我这里需要用到许多库libxml、iconv、curl、gd、gmp…,然后网上暂时没找到嵌入式linux版本的一键环境安装…所以只能硬着头皮一个个去交叉编译再包含进configure里。
    我的流程是这样的:
    根据需要的库,去点我点我官方文档里面搜索对应的库,
    在这里插入图片描述

    在这里插入图片描述
    然后点开安装 或者需求 ,一般都会给对应库的下载路径(爱了爱了!省去多少找源码的麻烦!)
    在这里插入图片描述

    下载了源码之后,就好办了,我用的是笨方法,一个个写脚本configure交叉编译
    比如libxml 的交叉编译:

    #!/bin/bash  
    ./configure  \
    --prefix=$PWD/1_libxml2-dom_install \
    --host=arm-himix200-linux \
    --with-tree \
    --with-python=$PWD/python \
    CC=arm-himix200-linux-gcc \
    CPP=arm-himix200-linux-cpp \
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    编译PHP可能遇到的问题

    编译PHP可能会遇到很多麻烦,首先先看config.log 日志查找原因。由于我这里库太多,全部记录上不太现实,我慢慢记录遇到的比较有代表性的问题吧。

    configure阶段:

    1:找不到编译好了的依赖库。
    在移植libgd库的时候,因为它需要libjpeg、libpng、libzlib等依赖前置库,所以先编译它们仨。然后在配置的脚本里–with-jpeg 的时候,总是提醒说找不到库。
    后面configure的配置日志,看到了解决方法
    在这里插入图片描述
    很明显,configure脚本没能找到我提供的交叉编译好的库,只能手动给环境变量PKG_CONFIG_PATH 添加我libjpeg、libpng、libzlib这些库的lib/pkgconfig/xxx.pc ,这个.pc 文件指明了对应库的头文件和lib库文件存在的路径。
    既然只用这一次,那就用作临时环境变量就行:

    #!/bin/bash  
    export PKG_CONFIG_PATH=/home/ouser/himix200-disk/php_nginx/src_tmp/zlib-1.2.11/1_zlib_install/lib/pkgconfig/:$PKG_CONFIG_PATH 
    export PKG_CONFIG_PATH=/home/ouser/himix200-disk/php_nginx/src_tmp/jpeg-9d/1-jpeg/lib/pkgconfig/:$PKG_CONFIG_PATH
    export PKG_CONFIG_PATH=$PWD/freetype-2.10.1/1-TARGET/lib/pkgconfig/:$PKG_CONFIG_PATH 
    export PKG_CONFIG_PATH=/home/ouser/himix200-disk/php_nginx/src_tmp/libpng-1.6.37/1-TARGET/lib/pkgconfig/:$PKG_CONFIG_PATH
    echo $PKG_CONFIG_PATH
    
    ./configure  \
    --prefix=$PWD/1-libgd \
    --host=arm-himix200-linux  \
    --with-config-file-path=/disk/php-7.2.15-arm/lib/ \  设置php.ini文件路径,最好是你开发板上的目录,因为这个选项编译后无法更改
    --with-config-file-scan-dir=/disk/php-7.2.15-arm/lib/ \
    --without-fontconfig \
    --with-zlib \
    --with-jpeg \
    --with-freetype \
    --with-png \
    CC=arm-himix200-linux-gcc \
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    再次运行脚本,就能找到前置依赖库并编译成功啦!

    如果还是不行(应该是交叉编译的ld工具查找不到对应库),
    这个时候就只能在配置脚本xxx.sh里的./configure里面增加一行 LDFLAGS=-L

    意思是在调用编译的时候直接指定包含的库的路径。

    如果这样也是不行,就查看这个依赖库/lib/下面有没有.so ,有种情况是Makefile没有成指向有效库文件的.so 软连接,用;ln -s 源文件 目标文件 即可。
    2,configure可能存在的测试语句
    在这里插入图片描述
    坑爹,改它,修改之前要记得备份喔!
    在这里插入图片描述
    3,移植进开发板后,发现找不到php.ini 文件
    如果没有指定,初始php.ini在源码目录里,且有两个,一个是生产环境,一个是产品环境如php-development.ini 。在源码目录下用find ./ -name "php*.ini"一般就可以找到。

    在桌面linux可以直接放到默认目录/usr/local/php下。但是咱这是交叉编译。 移植完后,想给php指定php.ini文件路径的方法我暂时还没找到,只能返回到configure阶段,用--with-config-file-path=DIR \ --with-config-file-scan-dir=DIR \两个选项来提前指定搜索路径。这个路径是你要把php.ini放在开发板的哪个位置。等make install完成后,就把php.ini放到开发板对应目录即可。
    在这里插入图片描述
    在这里插入图片描述
    这样就可以找到了。如果全部显示(none),就代表你应该向我上面那样重新编译一遍了。


    Makefile-make阶段:

    1:指明了头文件包含目录为交叉编译器包含的目录,但是在make过程中总是去到/usr/include/stdlib.h
    如果你能在你的交叉编译工具里找到stdlib.h,然后make过程中又提示说/usr/include/stdlib.h err: #include no such file ,意思是在/usr/include/stdlib.h找不到那个头文件。可是明明在configure步骤里指明了是交叉编译,却又跑去找/usr/inlcude? 既然是make阶段出问题,得勒,去找编译脚本Makefile修改:

    要修改Makefile --/usr/include  全部换成交叉编译下的 .../xxx/usr/include
    如:CFLAGS_CLEAN : -I/usr/include -g -O2 -fvisibility=hidden -DZEND_SIGNALS   
    路径包含改为-I/opt/hisi-linux/x86-arm/arm-himix200-linux/target/usr/include 
    
    • 1
    • 2
    • 3
    如果你像我一样configure里包含了curl库,则另外需要
    107修改 -INCLUDES =里修改curl包含的路径(别复制,这是我的路径,仅供参考):
    INCLUDES = -I/home/ouser/himix200-disk/php_nginx/php-7.2.15/ext/date/lib -I/home/ouser/himix200-disk/php_nginx/src_tmp/libxml2-2.9.10/1_libxml2-dom_install/include/libxml2 -I/home/ouser/himix200-disk/php_nginx/src_tmp/openssl-1.1.1j/1_ssl_install/include -I/home/ouser/himix200-disk/php_nginx/src_tmp/zlib-1.2.11/1_zlib_install/include -I/home/ouser/himix200-disk/php_nginx/src_tmp/curl-7.75.0/1_curl_install/include -I/home/ouser/himix200-disk/php_nginx/php-7.2.15/ext/sqlite3/libsqlite -I$(top_builddir)/TSRM -I$(top_builddir)/Zend
    
    • 1
    • 2
    • 3

    libtool脚本修改:

    # LTCC compiler flags. 88行 路径更改(别复制,这是我的路径,仅供参考)
    改前:LTCFLAGS="-I/usr/include -g -O2 -fvisibility=hidden -DZEND_SIGNALS"
    改后:LTCFLAGS="-I/opt/hisi-linux/x86-arm/arm-himix200-linux/target/usr/include -g -O2 -fvisibility=hidden -DZEND_SIGNALS"
    
    • 1
    • 2
    • 3

    这样愉快的make了几分钟,之后又报错,说需要生成的某某.lo文件找不到某某.h 头文件
    在这里插入图片描述

    这个简单,直接根据目标 某某.lo 在Makeflie里找到对应段,增加头文件搜索路径 -I/opt/xxx/ttt 文件路径。感觉好像是因为我修改了的configure,导致生成的Makefile总是有各种各样的小问题,还是说官方没有做过arm-linux移植适配?

    2:./main/php_config.h 提示说 #define uint unsigned int 重复定义
    具体的图片我没有截到,总之就是提醒在这个文件里,#define uint unsigned int等等的定义错误,搜翻译和百度才知道是说重复定义了,所以把这个文件里的这类定义注销掉。


    Makefile-make install阶段:

    提示无法执行的文件格式
    在这里插入图片描述
    可能是我在configure原文件里,把函数测试的那几句话给去掉了,所以导致现在install阶段,它居然想去执行开发板端的文件,那肯定不行啊,我的文件都用交叉编译的,肯定不能在桌面Ubuntu执行,怎么处理呢?没办法。只能手动去开发板执行这条Makeflie语句
    在这里插入图片描述
    完事了就在Makefile里注释掉对应语句—‘’我都帮你执行了,你就不用帮我执行了‘’
    拜拜了您勒


    最后,搞定php
    在这里插入图片描述
    附上一点小测试php代码,这是测试php::openssl库的加密解密功能的(官网抄的):

    
    //$key previously generated safely, ie: openssl_random_pseudo_bytes
    $plaintext = "message to be encrypted";
    $ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
    $hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
    $ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );
    echo "decrypt:";
    echo $ciphertext."\n";
    
    
    
    //decrypt later....
    $c = base64_decode($ciphertext);
    $ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
    $iv = substr($c, 0, $ivlen);
    $hmac = substr($c, $ivlen, $sha2len=32);
    $ciphertext_raw = substr($c, $ivlen+$sha2len);
    $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
    $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
    if (hash_equals($hmac, $calcmac))//PHP 5.6+ timing attack safe comparison
    {
        echo $original_plaintext."\n";
    }
    echo $original_plaintext."2\n";
    
     
    var_dump(php_ini_loaded_file());  //获取当前加载php.ini配置文件路径
     
    var_dump(php_ini_scanned_files()); //如果有另外在加载别的php.ini文件会输出相应的信息,否则输出false
    
    if(!extension_loaded('curl'))
    {
          echo '请在php.ini中设置支持php_mysql.dll'."\n";
    }
    else
    {
        echo '您的环境已经支持mysql!'."\n";
    }
    // 这句话可以打印对应拓展库所能提供的函数,可以用来测试库是否移植成功
    print_r(get_extension_funcs("gd")); 
    
    
    if (function_exists('imagejpeg')) {
    echo "IMAP functions are available.
    \n"
    ; } else { echo "IMAP functions are not available.
    \n"
    ; } ?>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    N:Nginx

    Nginx全版本
    要交叉编译这个服务器,需要前置pcre, 点击去官网
    根据官网讲述,常用且稳定的是pcre,虽然版本比较旧,但是用的非常广。pcre2是最新的。
    这里我下载的是pcre-8.44
    这个Nginx的移植比较有意思,它不像其他库,其他库如果要拓展,只需提供编译好的拓展库路径(包含/bin /lib /include 那个),而Nginx,则需要提供源码,它来给我们编译。
    在这里插入图片描述

    这就导致它对交叉编译不友好,这里附上他人例程供参考。下面记录是我遇到的问题以及解决方法
    作者:爱是恒久忍耐_又有恩慈

    找不到pcre2.h
    在这里插入图片描述
    这个简单,根据对应行号和语句,找到Makefile文件里对应的行,添加指定的头文件路径即可。如果可以事先指定CFLAG增加头文件搜索路径,也可以。

    ipv6支持问题
    跟上面引用的博客一样,但是原作者似乎没遇到我这个问题,我这里的ngx_event_udp.c里面有其他语句需要注释掉。既然选择不用ipv6,那就贯彻到底了。108和220行
    在这里插入图片描述

    相信编译完成后,肯定会遇到和我一样的问题:
    在这里插入图片描述
    路径又指向了桌面虚拟机的Ubuntu路径,不是开发板的路径。头疼中…

  • 相关阅读:
    mapbox 地图 生成矢量数据圆
    Redis源码解读之用RedisAe实现一个简单的HTTP服务器
    Java面试题以及答案(三)多线程(必会)
    科技的崛起:国内机器视觉蓬勃发展
    【快速上手系列】使用idea调百度AI接口实现内容审核(鉴黄)功能
    POI及EasyExcel【Java提高】
    2022牛客多校3 A-Ancestor(求LCA前后缀)
    搭建 HRNet-Image-Classification,训练数据集
    AP5101C 高压线性恒流 LED电源驱动IC 3D打印机显示灯驱动器
    【MySQL】学习多表查询和笛卡尔积
  • 原文地址:https://blog.csdn.net/corefunction/article/details/113990427