如何交叉编译程序:以 freetype 为例

怎么确定“系统目录”?

echo 'main(){}'| arm-linux-gnueabihf-gcc -E -v -

系统头文件目录 以stdio.h为例:

/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include

系统库目录LIBRARY_PATH:

/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib

Linux编译程序时找不到头文件的解决办法

Linux编译程序时如果找不到头文件会提示如下错误:

error: xxx.h: No such file or directory
 #include 
                   ^

解决方法:

下面叙述以Ubuntu系统为例。

  1. 先查找 xxx.h 所在路径:
$ sudo find / -name xxx.h
/usr/local/include/xxx/xxx.h
  1. 库的来源问题:

    假设这个库文件是我们自己写的,那么只要在编译时用-I选项指定自定义头文件的dir即可,或者规范一些,可以把这个头文件放入系统目录的中,方便后续使用#include ,直接系统目录下查找。

    假设这个库文件不是我们自己写的,即对于系统目录,#include 我们执行find命令有可能查出不止一个xxx.h,他们的名字相同,但是目录不同,这样还是不知道是哪个目录。

  2. 查寻main()函数所需的系统库文件目录

    鉴于只执行find命令后出现了多个xxx.h所在路径,我们若想快速定位到我们所需的系统库文件的目录,就需要查一下运行main()函数时所依赖的系统库文件

    执行

    echo 'main(){}'| arm-linux-gnueabihf-gcc -E -v -
    

    系统会列出头文件目录、库目录(LIBRARY_PATH)

  3. 结合第1和3两者的打印信息,即可快速确定系统目录的路径

  4. 然后用-I选项把目录加上编译:

    $ gcc test.c -o test -I /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include
    

双引号是首先在使用include的源文件所在目录找,如果未找到,则到在编译器工作路径下继续寻找。“<>”在编译器工作路径下查找

https://blog.csdn.net/vegetable_bird_001/article/details/50905244

https://my.oschina.net/2bit/blog/389556

安装过程

注意:

  1. 这里make和install如果无权限受限问题尽量不要使用管理员权限进行安装,即不要加sudo,否则编译时,输入make指令后,系统有可能出现make:arm-linux-gnueabihf-gcc: Command not found这样的错误。

    可能的原因:在root权限下,环境变量中没有添加arm-linux-gnueabihf-gcc所在的路径。

    如果您就是需要在root路径下运行的话可以参考这篇文章https://blog.csdn.net/whocarea/article/details/103365339

  2. 编译其他库的时候要看其他库的configure的参数是否支持–host,不支持的话需要export CC设置为你的arm工具链

  3. 切记:不要安装共享文件夹中共享的文件

    在虚拟机中编译freetype时不要使用共享文件夹去共享库,否则会报错如下:

    ln: failed to create symbolic link ‘libavutil.so’: Operation not supported

    这个问题主要原因是在使用ln创建软连接时候失败了,因为这个文件系统是NTFS,windows上的,通过虚拟机挂载到linux上,所以并不支持ln操作。

    解决方法:

    1.安装VMTools,把freetype和其相关的依赖包拷贝到linux中再编译。

    2.通过FileZilla把freetype和其相关的依赖包通过sftp传输到linux系统中,就可以直接编译了。

首先安装zlib库

zlib的官网地址:http://www.zlib.net/

编译zlib库时,./configure不允许传入–host参数;不支持的话需要export CC设置为你的arm工具链
这里通过 $ export CC=arm-linux-gnueabihf-gcc(根据自己的交叉编译工具链修改arm-linux-gnueabihf-gcc) 进行配置交叉编译工具。

 cd zlib-1.2.11
 export CC=arm-linux-gnueabihf-gcc
 ./configure --prefix=$PWD/tmp
 make
 make install

copy编译好的库到“系统目录”

book@100ask:~/mytest/zlib-1.2.11$ cd tmp/include/
book@100ask:~/mytest/zlib-1.2.11/tmp/include$ cp -rf * /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include
book@100ask:~/mytest/zlib-1.2.11/tmp/include$ cd ../lib/
book@100ask:~/mytest/zlib-1.2.11/tmp/lib$ cp -drf * /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib

其次安装libpng库

安装好zlib库后,再进行libpng库的安装。

cd libpng-1.6.37
export LDFLAGS="-L/home/book/mytest/zlib-1.2.11"
export CPPFLAGS="-L/home/book/mytest/zlib-1.2.11"
./configure --host=arm-linux-gnueabihf --prefix=$PWD/tmp
make
sudo make install

注意:这里的LDFLAGS和CPPFLAGS要使用刚刚的zlib-1.2.11的绝对路径,否则libpng报错:zlib not installed

copy编译好的库到“系统目录”

book@100ask:~/mytest/libpng-1.6.37$ cd tmp/
book@100ask:~/mytest/libpng-1.6.37/tmp$ ls
bin  include  lib  share
book@100ask:~/mytest/libpng-1.6.37/tmp$ cd include/
book@100ask:~/mytest/libpng-1.6.37/tmp/include$ ls
libpng16  pngconf.h  png.h  pnglibconf.h
book@100ask:~/mytest/libpng-1.6.37/tmp/include$ cp -rf * /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include 
book@100ask:~/mytest/libpng-1.6.37/tmp/include$ cd ../lib/
book@100ask:~/mytest/libpng-1.6.37/tmp/lib$ ls
libpng16.a  libpng16.la  libpng16.so  libpng16.so.16  libpng16.so.16.37.0  libpng.a  libpng.la  libpng.so  pkgconfig
book@100ask:~/mytest/libpng-1.6.37/tmp/lib$ cp -drf * /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib

最后安装freetype库

cd freetype-2.10.2
./configure --host=arm-linux-gnueabihf --prefix=$PWD/tmp
make
make install

copy编译好的库到“系统目录”

book@100ask:~/mytest/freetype-2.10.2$ cd tmp
book@100ask:~/mytest/freetype-2.10.2/tmp$ ls
include  lib  share

book@100ask:~/mytest/freetype-2.10.2/tmp$ cd include/
book@100ask:~/mytest/freetype-2.10.2/tmp/include$ cp -rf * /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include 

book@100ask:~/mytest/freetype-2.10.2/tmp/include$ cd ../lib/
book@100ask:~/mytest/freetype-2.10.2/tmp/lib$ cp -drf * /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib

Makefile配置:

CFLAGS := -Wall -O2 -g
CFLAGS += -I $(shell pwd)/include
LDFLAGS := -lfreetype

export CFLAGS LDFLAGS 

此处Makefile中要指定链接库-lfreetype

详见:https://www.cnblogs.com/taskiller/archive/2012/12/14/2817650.html

CFLAGS 表示用于 C 编译器的选项,
CXXFLAGS 表示用于 C++ 编译器的选项。
这两个变量实际上涵盖了编译和汇编两个步骤。

CFLAGS: 指定头文件(.h文件)的路径,如:CFLAGS=-I/usr/include -I/path/include。同样地,安装一个包时会在安装路径下建立一个include目录,当安装过程中出现问题时,试着把以前安装的包的include目录加入到该变量中来。

LDFLAGS:gcc 等编译器会用到的一些优化参数,也可以在里面指定库文件的位置。用法:LDFLAGS=-L/usr/lib -L/path/to/your/lib。每安装一个包都几乎一定的会在安装目录里建立一个lib目录。如果明明安装了某个包,而安装另一个包时,它愣是说找不到,可以抒那个包的lib路径加入的LDFALGS中试一下。

LIBS:告诉链接器要链接哪些库文件,如LIBS = -lpthread -liconv

简单地说,LDFLAGS是告诉链接器从哪里寻找库文件,而LIBS是告诉链接器要链接哪些库文件。不过使用时链接阶段这两个参数都会加上,所以你即使将这两个的值互换,也没有问题。

最后,简单测试一下:执行make

如何交叉编译程序:以 freetype 为例_第1张图片

参考来源:

特此感谢!

韦东山老师的视频教程

交叉编译libpng报错:configure: error: zlib not installed

Makefile选项CFLAGS,LDFLAGS,LIBS

#include<> 和 #include""的区别

关于C语言include尖括号和双引号的对话

你可能感兴趣的:(嵌入式linux学习笔记)