yocto使用SDKToolchain 2
1.2 Makefile-Based 项目
简单Makefile-based的项目使用运行cross-toolchain环境设置脚本时建立的cross-toolchain环境变量并与之交互。 环境变量受一般make 规则的约束。
本节介绍了一个简单的Makefile开发流程,并提供了一个示例,让您了解如何在开发过程中使用cross-toolchain环境变量和Makefile变量。
本节的重点是解释以下三种有关变量表现的情况:
- 情况1-在Makefile中没有设置与SDK安装脚本中相同的环境变量:由于在Makefile中没有专门设置匹配变量,因此变量会根据环境设置脚本保留其值。
- 情况2-在变量文件中设置了变量,设置了与SDK安装脚本中相同的环境变量:在构建过程中专门在Makefile中设置匹配变量会导致变量的环境设置被覆盖。在这种情况下,将使用您在Makefile中设置的变量。
- 情况3-使用命令行设置变量,设置了与SDK安装脚本中相同的环境变量:从命令行执行Makefile会导致环境变量被覆盖。在这种情况下,将使用命令行内容。
注意
无论如何设置变量,如果对make都使用“ -e”选项,则SDK安装脚本中的变量优先:
$ make -e target
本节的其余部分提供了一个简单的Makefile示例,该示例演示了这些变量效果。
在新的Shell环境中,直到您运行安装脚本,才为SDK建立变量。 例如,以下命令显示了编译器变量(即CC)的空值。
$ echo ${CC}
$
使用Yocto Project运行64位构建主机的SDK设置脚本,以及用于核心图像保存图像的i586调整目标体系结构,然后回显该变量将显示通过脚本建立的值:
$ source /opt/poky/3.2/environment-setup-i586-poky-linux
$ echo ${CC}
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/3.2/sysroots/i586-poky-linux
为了说明变量的用法,请通过以下简单的“ Hello World!”进行操作。 例:
1.创建一个工作目录并填充:为您的项目创建一个干净的目录,然后将该目录作为您的工作位置
$ mkdir $HOME/helloworld
$ cd $HOME/helloworld
设置目录后,用流程所需的文件填充目录。 您需要一个用来调用函数的main.c文件,一个包含头文件的module.h文件以及一个定义函数的module.c文件。
创建三个文件,如下所示:
- main.c:
#include "module.h"
void sample_func();
int main()
{
sample_func();
return 0;
}
- module.h:
#include <stdio.h>
void sample_func();
- module.c:
#include "module.h"
void sample_func()
{
printf("Hello World!");
printf("\n");
}
2.Souce Cross-Toolchain环境设置文件:安装Cross-Toolchain会在SDK的安装目录中创建Cross-Toolchain环境设置脚本。 在使用这些工具来开发项目之前,必须Souce此安装脚本。 该脚本以字符串“ environment-setup”开头,包含机器体系结构,其后是字符串“ poky-linux”。 对于此示例,该命令从使用32位Intel x86体系结构和DISTRO_NAME Yocto Project的默认SDK安装目录中获取脚本:
$ source /opt/poky/DISTRO/environment-setup-i586-poky-linux
3.创建Makefile:对于此示例,Makefile包含两行,可用于设置CC变量。 一行与运行SDK环境设置脚本时设置的值相同,另一行将CC设置为“ gcc”,即构建主机上的默认GNU编译器:
# CC=i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux
# CC="gcc"
all: main.o module.o
${CC} main.o module.o -o target_bin
main.o: main.c module.h
${CC} -I . -c main.c
module.o: module.c
module.h ${CC} -I . -c module.c
clean:
rm -rf *.o
rm target_bin
4.生成项目:使用make命令创建二进制输出文件。 因为变量在Makefile中被注释掉,所以用于CC的值是运行SDK环境设置文件时设置的值:
$ make
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
从上一个命令的结果中,您可以看到所使用的编译器是通过安装脚本中定义的CC变量建立的编译器。
您可以通过取消注释Makefile中的行并再次运行make来使用与Makefile中设置的变量相同的变量覆盖CC环境变量。
$ make clean
rm -rf *.o
rm target_bin
#
# Edit the Makefile by uncommenting the line that sets CC to "gcc"
#
$ make
gcc -I . -c main.c
gcc -I . -c module.c
gcc main.o module.o -o target_bin
如前面的示例所示,未使用cross-toolchain编译器。 而是使用默认的编译器。
接下来的情况显示了如何通过在命令行中提供变量来覆盖变量。 进入Makefile并重新插入注释字符,以便运行make使用已建立的SDK编译器。 但是,在运行make时,请使用命令行参数将CC设置为“ gcc”:
$ make clean
rm -rf *.o
rm target_bin
#
# Edit the Makefile to comment out the line setting CC to "gcc"
#
$ make
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
$ make clean
rm -rf *.o
rm target_bin
$ make CC="gcc"
gcc -I . -c main.c
gcc -I . -c module.c
gcc main.o module.o -o target_bin
在前一种情况下,命令行参数将覆盖SDK环境变量。
在后一种情况下,再次编辑Makefile以使用“ gcc”编译器,然后在make命令行上使用“ -e”选项:`在这里插入代码片:
$ make clean
rm -rf *.o
rm target_bin
#
# Edit the Makefile to use "gcc"
#
$ make
gcc -I . -c main.c
gcc -I . -c module.c
gcc main.o module.o -o target_bin
$ make clean
rm -rf *.o
rm target_bin
$ make -e
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
在前一种情况下,“-e”选项强制使make使用SDK环境变量,而不管Makefile中的值如何。
执行项目:要执行项目(即target_bin),请使用以下命令:
$ ./target_bin
Hello World!
注意
如果使用cross-toolchain编译器来构建target_bin,并且构建主机的体系结构与目标计算机的体系结构不同,则需要在目标设备上运行项目。
正如预期的那样,该项目将显示“ Hello World!”信息。