嵌入式 lnmp搭建的记录
- N:Nginx
- P:php
- 编译PHP可能遇到的问题
- configure阶段:
- Makefile-make阶段:
- Makefile-make install阶段:
文章比较水,并没有没解决什么实际问题,有点不好意思发布。但好像又记录了不少交叉编译配置的思路,所以还是记录下来,希望有更多大佬能给支支招,共同进步!
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路径,不是开发板的路径。头疼中…
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 \
编译PHP可能遇到的问题
编译PHP可能会遇到很多麻烦,首先先看config.log 日志查找原因。由于我这里库太多,全部记录上不太现实,我慢慢记录遇到的比较有代表性的问题吧。
PPS:想指明第三方库所在路径,有四种方法:,
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=xxx.so
来找到编译器的默认路径
4,在configure阶段,添加-LDFLAG
增加编译选项给编译器直接增加搜索路径
如果你移动了lib库文件,对应的xx.pc也要同步更新,且放到pkgconfig搜索目录下!!否则pkg-config会搜索不到!
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 \
再次运行脚本,就能找到前置依赖库并编译成功啦!
如果还是不行(应该是交叉编译的ld工具查找不到对应库),
这个时候就只能在配置脚本xxx.sh里的./configure里面增加一行 LDFLAGS=-L<dir>
意思是在调用编译的时候直接指定包含的库的路径。
如果这样也是不行,就查看这个依赖库/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 <bits/floatn.h> 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
如果你像我一样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
和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"
这样愉快的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库的加密解密功能的(官网抄的):
<?php
//$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.<br />\n";
} else {
echo "IMAP functions are not available.<br />\n";
}
?>