程序运行的一些基础知识
1. 编译程序时去哪里找头文件?
系统目录:就是交叉编译工具链里的某个 include
目录;也可以自己指定。编译时用 -I dir
选项指定。
2. 链接时去哪里找库文件
系统目录:就是交叉编译工具链里的某个 lib
目录;也可以自己指定。链接时用 -L dir
选项指定。
3. 运行时去哪里找库文件
系统目录:就是板子上的 /lib
、 /usr/lib
目录;也可以自己指定。运行程序用环境变量 LD_LIBRARY_PATH
指定。
注意:
运行时不需要头文件,所以头文件不用放到板子上
常见错误的解决方法
1. 头文件问题
编译时找不到头文件。在程序中如果是这样包含的头文件:#include <xxx.h>
这种尖角号里的头文件,去哪里找?
答案是:系统目录。
也就是交叉编译工具链里面的某个 include
目录。
当然也可以自己指定;编译时用 -I dir
选项指定。
如何确定系统目录呢?
可以执行如下语句
echo ‘main(){}’| arm-buildroot-linux-gnueabihf-gcc -E -v -
然后你会看到头文件目录,库目录(LIBRARY_PATH),你需要做的是在头文件目录确定有没有这个文件,或者是自己指定头文件目录
2. 库文件问题
当你在链接程序时,看到 undefined reference to xxx
,则说明函数未定义。
解决方法有:
-
自己去写出这个函数
-
使用库函数,需要链接时指定库
怎么指定库?
想链接libabc.so
,链接时加上:-labc
库在哪里?
- 系统目录:就是交叉编译工具链里面某个
lib
目录 - 也可以自己指定:链接时用
-L dir
选项指定
- 系统目录:就是交叉编译工具链里面某个
3. 运行问题
运行程序时找不到库:
error while loading shared libraries: libxxx.so:
cannot open shared object file: No such file or directory
无非就是找不到库,库在哪?
- 系统目录:板子上的
/lib
,/usr/lib
目录 - 也可以自己指定:运行程序用环境变量
LD_LIBRARY_PATH
指定,执行以下的命令
export LD_LIBRARY_PATH=/xxx_dir ; ./test
或者
LD_LIBRARY_PATH=/xxx_dir ./test
交叉编译程序的万能命令
如果交叉编译工具链的前缀是 arm-buildroot-linux-gnueabihf-
,比如 arm-buildroot-linux-gnueabihf-gcc
,在交叉编译开源软件时,如果它里面有 configure
, 则可以使用以下的万能命令
./configure --host=arm-buildroot-linux-gnueabihf --prefix=/
make
make install
执行完成之后就可以在当前目录的tmp
目录下看见 bin
, lib
, include
等目录了,里面有可以执行的程序,库,头文件
1. 把头文件、库文件放到工具链目录里
如果你编译的是一个库,需要把得到的头文件,库文件放入工具链的 include
, lib
目录里。别的程序要使用这些头文件、库时、会很方便。
问题是,工具链里可能有很多个 include
, lib
目录,放到哪里去?
执行:
echo ‘main(){}’| arm-buildroot-linux-gnueabihf-gcc -E -v -
就能看到了
头文件:
/home/book/dzz/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include
库文件:
/home/book/dzz/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/
以 IMX6ULL 交叉编译 freetype为例
第1步 确定头文件、库文件在工具链中的目录;同时先设置交叉编译工具链
export ARCH=arm
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
export PATH=$PATH:/home/book/dzz/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
以 IMX6ULL
开 发 板 为 例 , 它 的 工 具 链 是 arm-buildroot-linuxgnueabihf-gcc
,可以执行以下命令:
echo ‘main(){}’| arm-buildroot-linux-gnueabihf-gcc -E -v -
可以确定头文件的系统目录为:
/home/book/dzz/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include
库文件的系统目录为:
/home/book/dzz/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/
第2步 交叉编译、安装 freetype
tar xJf freetype-2.10.2.tar.xz
cd freetype-2.10.2
./configure --host=arm-buildroot-linux-gnueabihf --prefix=$PWD/tmp
make
make install
cd tmp
cp include/freetype2/* -rf /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/include
cp lib/* -rfd /home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib/