一、背景

  1. 本文是《nginx交叉编译》的下半部分。由于本人的CSDN博客已经不再维护,所以以后的内容更新都会发表在这里。给大家带来的不便,敬请见谅。
  2. 由于距离我写这篇博客已经过去很久了,编译器版本、gcc版本、linux版本、nginx版本都已经发生了不少变化。但是基本上遇到的问题都是类似的,目前交叉编译遇到的大部分问题都可以在这里找到。如果还有其它问题,请自行google。
  3. 第一次使用markdown写博客,加上博客主题的原因,导致排版有点乱,希望大家能够见谅。
  4. 本文的上半部分在本人csdn博客。
    《nginx交叉编译(上)》

二、nginx 交叉编译 (下)

8、遇到的问题

  1. 问题内容:没有规则可以创建 “/home/ubuntu/packets/nginx-1.4.7/build/src/core/nginx.o” 需要的目标 “src/core/nginx.h” 。
  2. 原因分析:不知道是不是软件的 bug,指定build路径后,build路径里面的源代码是空的
  3. 解决办法:把主目录的src文件夹里面的东西,拷贝到build目录(build目录请根据自己实际情况进行确定,参考上面那个问题)

9、遇到的问题

问题内容:

- checking whether the C compiler works... configure: error: cannot run Ccompiled programs.
- If you meant to cross compile, use `--host'.
- See 'config.log' for more details.
- make:\*\*\* [/home/ubuntu/packets/pcre-6.7/Makefile]错误

原因分析:
出错的是pcre而不是openssl。原因是编译 pcre 没有指定 `–host’ 参数

解决办法:



打开build目录的Makefile,找到 pcre 参数设定的那几行。
/home/ubuntu/packets/pcre-6.7/Makefile : /home/ubuntu/packets/nginx-1.6.2/build/Makefile
cd /home/ubuntu/packets/pcre-6.7 \
&& if [ -f Makefile ] ; then $(MAKE) distclean; fi \
&& CC="$(CC)" CFLAGS="-O2 -fomit-frame-pointer -pipe "\
./configure --disable-shared

- 在configure那里再添加一个参数 --host=mips-openwrt-linux(具体添加需要根据实际情况,参考我的编译器是mips-openwrt-linux-gcc,所以host是mips-openwrt-linux)

10、遇到的问题

问题内容:

src/os/unix/ngx_errno.c : In function'ngx_strerror':
src/os/unix/ngx_errno.c : 37 : 31 :error:'NGX_SYS_NERR' undeclared (first use in this function)
src/os/unix/ngx_errno.c : 37 : 31 :note: each undeclared identifier is reported only once for eachfunction it appears in
src/os/unix/ngx_errno.c : In function'ngx_strerror_init':
src/os/unix/ngx_errno.c : 58 :11 : error : 'NGX_SYS_NERR' undeclared (first use in this function)
make:*** [/home/ubuntu/packets/nginx-1.6.2/build/src/os/unix/ngx_error.o] 错误1

原因分析:
– NGX_SYS_NERR未定义,NGX_SYS_NERR正常情况下应定义在objs/ngx_auto_config.h文件中,特别注意,这是一个auto性质的文件,只有在执行了./configure后,才能生成这个文件。宏NGX_SYS_NERR的意义为,在Linux系统中有132个错误编码。



解决办法:
– 找到ngx_auto_config.h这个文件(我的ngx_auto_config.h在build目录,不同的configure参数,这个文件的位置可能不一样)

在文件中添加如下三行:

#ifndef NGX_SYS_NERR
#define NGX_SYS_NERR 132
#endif

然后,继续执行make。



11、遇到的问题

问题内容:

./dftables pcre_chartables.c
/bin/bash:./dftables:无法执行二进制文件

原因分析:



dftables需要在编译的时候运行,而交叉编译的程序是不能运行的,要用系统的gcc来编译才能运行

解决办法:

用x86的gcc来单独编译dftables(我的是ubuntu自带的gcc)。
进入pcre代码所在的目录,并且执行
gcc -Wall -O2 -DCROSS_COMPILE dftables.c -o dftables
执行完之后,返回刚才的目录,执行 make 继续编译

12、遇到的问题

问题内容:

openssl-1.0.1i/.openssl/lib/libssl.a(s23_meth.o):Relocations in generic ELF(EM: 3)
libssl.a:could not read symbols: File in wrong format

原因分析:

  • 原因是编译在nginx执行configure的时候,交叉编译参数没有很好的传到openssl。

解决办法:

  • 打开主目录的Makefile,搜索到包含openssl-1.0.1i/.openssl/include/openssl/ssl.h的那一行(可能不同的版本会有一点点区别,搜索openssl,找到最接近那行)
  • 然后,在config的参数那里增加一个,指明交叉编译器所在的路径(请根据实际情况设定)
  • –cross-compile-prefix=/home/ubuntu/…………/mips-openwrt-linux-
  • (需要注意的是,最后那里的横杠不能少,如果编译器是mips-openwrt-linux-gcc那就是mips-openwrt-linux-,如果是arm-linux-gcc就是arm-linux-)
  • 修改完makefile之后,会导致make把所有东西都构建一遍,所以之前已经解决了的那几个问题可能会重新出现,需要再解决一回。

13、遇到的问题

问题内容:

  • x86cpuid.s:Assembler messages:
  • x86cpuid.s:168:Error: Unrecognized opcode `hlt`

原因分析:

  • 原因是编译在nginx执行configure的时候,交叉编译参数没有很好的传到openssl。

解决办法:

  • 找到上面那个问题添加–cross-compile-prefix的那一行,继续添加一个参数no-asm,禁用汇编代码。

14、遇到的问题

问题内容:

./home/ubuntu/packets/nginx-1.6.2/build/src/core/ngx_cycle.o:In function `ngx_init_cycle':
/home/ubuntu/packets/nginx-1.6.2/build/src/core/ngx_cycle.c:457:undefined reference to `ngx_shm_free'
/home/ubuntu/packets/nginx-1.6.2/build/src/core/ngx_cycle.c:462:undefined reference to `ngx_shm_alloc'
/home/ubuntu/packets/nginx-1.6.2/build/src/core/ngx_cycle.c:648:undefined reference to `ngx_shm_free'
/home/ubuntu/packets/nginx-1.6.2/build/src/event/ngx_event.o:In function `ngx_event_module_init':
/home/ubuntu/packets/nginx-1.6.2/build/src/event/ngx_event.c:525:undefined reference to `ngx_shm_alloc'
collect2:ld returned 1 exit status
make:*** [/home/ubuntu/packets/nginx-1.6.2/build/nginx]错误1

原因分析:

  • `ngx_shm_free`函数未定义
  • 通过查看源码可以发现,`ngx_shm_free’定义在
  • src/os/unix/ngx_shmem.c文件中,这个函数要正常使用的话必须要求
  • “NGX_HAVE_MAP_ANON、NGX_HAVE_MAP_DEVZERO、NGX_HAVE_SYSVSHM”这三个宏中有一个被定义。

解决办法:
修改ngx_auto_config.h ,加入这几行:

#ifndef NGX_HAVE_SYSVSHM
#define NGX_HAVE_SYSVSHM 1
#endif



http://xzh.i3geek.com

爱唠叨的老鱼

爱唠叨的老鱼

技术经理,个人站长,创业者

1 条评论

头像

fish · 2017年11月29日 12:01

这篇文章是很久之前写的,目前是百度和google关于nginx交叉编译的第一名。访问量大概在两万左右。已经两三年没有写技术博客了,这两年都在潜心修炼,重新起步。
我把本文的下半部分放在这里,作为我个人博客的开端吧。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据