如何交叉编译具有 Yocto Linux 库依赖项的应用程序?

How to cross-compile an application with library dependencies for Yocto Linux?

我在我的笔记本电脑 (Ubuntu 14.04) 上写了一个依赖于 GStreamer 的应用程序,并想为我的 Yocto Linux 目标 (iMX6S-Wandboard) 交叉编译它。如何交叉编译应用程序,使其在目标板上运行并能够使用 GStreamer 库?

谢谢,

东安

更新:

我的生成文件:

PACKAGES            = gstreamer-1.0

override CFLAGS     += `pkg-config --cflags $(PACKAGES)` -Wall -Wextra "-DDATADIR=\"$(DATADIR)/\"" -ffunction-sections -fdata-sections
override LIBS       += `pkg-config --libs $(PACKAGES)`
override LDFLAGS    += -Wl,--gc-sections

OBJS    = basic-tutorial-7.o
DEPS    = $(foreach file,$(OBJS),$(basename $(file)).d)
EXE     = basic-tutorial-7

DESTDIR     ?=
PREFIX      ?=  $(HOME)/.local/
BINDIR      ?=  $(PREFIX)bin
DATADIR     ?=  $(PREFIX)share/$(PKGNAME)

.PHONY : clean install uninstall

all:    $(EXE)

$(EXE)  :   $(OBJS)
    $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)

$(OBJS) : %.o   :   %.c %.d
    @[ -d "$(@D)" ] || mkdir -p "$(@D)"
    $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

$(DEPS) : %.d : $(PROJECT_ROOT)%.c
    @[ -d "$(@D)" ] || mkdir -p "$(@D)"
    $(CC) $(CFLAGS) $(CPPFLAGS) -M -MF $@ -MT "$(basename $@).o" $<

clean:
    rm -fr $(EXE) $(OBJS) $(DEPS)

install : $(EXE)
    install -DT -m 0755 $(EXE) $(DESTDIR)$(BINDIR)/$(EXE)

uninstall :
    rm -v $(DESTDIR)$(BINDIR)/$(EXE)

ifneq ($(MAKECMDGOALS), clean)
-include $(DEPS)
endif

我的 *.bb 文件:

DESCRIPTION = "Basic Tutorial 7"
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""

DEPENDS = "gstreamer1.0 pkgconfig-native gstreamer1.0-plugins-base"

FILES_${PN} += "${bindir}/basic-tutorial-7 ${bindir}/basic-tutorial-7"

EXTRA_OEMAKE += "DESTDIR=${D}/ DATADIR=${datadir}/basic-tutorial-7 BINDIR=${bindir}"

do_compile () {
    oe_runmake install
}

do_install () {
    oe_runmake clean
}

构建日志:

$ devtool build basic-tutorial-7

NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |############################################| Time: 0:00:00
Loaded 1298 entries from dependency cache.
Parsing recipes: 100% |##########################################| Time: 0:00:00
Parsing of 773 .bb files complete (772 cached, 1 parsed). 1299 targets, 63 skipped, 0 masked, 0 errors.
Loading cache: 100% |############################################| Time: 0:00:00
Loaded 1298 entries from dependency cache.
Parsing recipes: 100% |##########################################| Time: 0:00:00
Parsing of 773 .bb files complete (772 cached, 1 parsed). 1299 targets, 63 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
Initialising tasks: 100% |#######################################| Time: 0:00:01
Sstate summary: Wanted 0 Found 0 Missed 0 Current 322 (0% match, 100% complete)
NOTE: Executing Tasks
NOTE: Setscene tasks completed
NOTE: Tasks Summary: Attempted 1480 tasks of which 1480 didn't need to be rerun and all succeeded.

部署日志:

$ devtool deploy-target basic-tutorial-7 root@192.168.0.101

NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |############################################| Time: 0:00:00
Loaded 1298 entries from dependency cache.
Parsing recipes: 100% |##########################################| Time: 0:00:00
Parsing of 773 .bb files complete (772 cached, 1 parsed). 1299 targets, 63 skipped, 0 masked, 0 errors.
ERROR: No files to deploy - have you built the basic-tutorial-7 recipe? If so, the install step has not installed any files.

Yocto eSDK 允许您在 PC 上使用目标本身使用的编译器和库为 Yocto 目标交叉编译应用程序。无需将 GCC 添加到目标。 eSDK 可以从 Yocto 源代码树生成,但由于您已经安装了源代码,所以您不需要安装 eSDK,可以直接从源代码构建。所有这些都不是特定于 ARM 的,而是针对特定 Yocto 目标交叉编译的通用 Yocto 工作流程。

为此,首先像往常一样设置 Yocto 构建环境,方法是切换到 Yocto 目录,运行宁 source setup-environment yourbuilddir

然后,运行 devtool add,传递您的应用程序名称(将用于 BitBake 配方)和现有源代码树的路径,例如:

devtool add myhelloworld /home/user/Projects/myhelloworld

这将自动生成一个配方,并将名为 workspace 的图层添加到您的 Yocto 源代码树中。食谱将被命名为 /yocto/source/path/yourbuilddir/workspace/recipes/myhelloworld/myhelloworld.bb。您可以通过 运行ning

编辑它
devtool edit-recipe myhelloworld

在命令前加上 EDITOR=gedit 之类的前缀,以使用您喜欢的文本编辑器。修改配方以正确构建您的应用程序; BitBake 会自动判断是 运行 make 还是 CMake。使用 make 的示例是:

DESCRIPTION = "My GStreamer Hello World"
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""

DEPENDS = "gstreamer1.0 pkgconfig-native"
FILES_${PN} += "${bindir}/myhelloworld ${datadir}/myhelloworld"

EXTRA_OEMAKE += "DESTDIR=${D}/ DATADIR=${datadir}/myhelloworld BINDIR=${bindir}"

do_install() {
    oe_runmake install
}

do_clean() {
    oe_runmake clean
}

DEPENDS 列出了依赖项,我添加了 gstreamer1.0pkgconfig-native,这是在 Makefile 中使用 pkg-config 时所必需的。如果需要,可以向 DEPENDS 添加更多依赖项,例如 boost openssl。 一个合适的示例 makefile 是:

PACKAGES            = gstreamer-1.0

override CFLAGS     += `pkg-config --cflags $(PACKAGES)` -Wall -Wextra "-DDATADIR=\"$(DATADIR)/\"" -ffunction-sections -fdata-sections
override LIBS       += `pkg-config --libs $(PACKAGES)`
override LDFLAGS    += -Wl,--gc-sections

OBJS    = main.o
DEPS    = $(foreach file,$(OBJS),$(basename $(file)).d)
EXE     = myhelloworld

DESTDIR     ?=
PREFIX      ?=  $(HOME)/.local/
BINDIR      ?=  $(PREFIX)bin
DATADIR     ?=  $(PREFIX)share/$(PKGNAME)

.PHONY : clean install uninstall

all:    $(EXE)

$(EXE)  :   $(OBJS)
    $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)

$(OBJS) : %.o   :   %.c %.d
    @[ -d "$(@D)" ] || mkdir -p "$(@D)"
    $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

$(DEPS) : %.d : $(PROJECT_ROOT)%.c
    @[ -d "$(@D)" ] || mkdir -p "$(@D)"
    $(CC) $(CFLAGS) $(CPPFLAGS) -M -MF $@ -MT "$(basename $@).o" $<

clean:
    rm -fr $(EXE) $(OBJS) $(DEPS)

install : $(EXE)
    install -DT -m 0755 $(EXE) $(DESTDIR)$(BINDIR)/$(EXE)

uninstall :
    rm -v $(DESTDIR)$(BINDIR)/$(EXE)

ifneq ($(MAKECMDGOALS), clean)
-include $(DEPS)
endif

在您的 Makefile 中,确保 make install 将您的应用程序二进制文件安装到 $(DESTDIR)$(BINDIR)/myhelloworld 中,并将数据文件(例如图像)安装到 $(DESTDIR)$(DATADIR)/somefile 中。在目标上,您的二进制文件将位于 /usr/bin/myhelloworld 中,数据文件位于 /usr/share/myhelloworld 中。在 Makefile 中,将 "-DDATADIR=\"$(DATADIR)/\"" 传递给编译器,以便您可以通过类似 fopen(DATADIR "somepic.png", "rb"); 的方式打开数据文件。对于源文件 main.c,您可以使用 GStreamer example 1.

保存食谱,Makefilemain.c,然后 运行

devtool build myhelloworld

编译您的应用程序。如果一切顺利,您可以通过 SSH 通过 运行ning 将其安装到目标,例如

devtool deploy-target myhelloworld root@targethostname

然后您可以通过键入 myhelloworld 通过 SSH 连接到目标和 运行 您的应用程序。要卸载它:

devtool undeploy-target myhelloworld root@targethostname

如果您以后决定将您的应用程序作为 Yocto 映像的一部分发布,请修改系统映像的配方并添加:

IMAGE_INSTALL_append = " yourhelloworld"

保留第一个引号后的 space。构建映像时,将包含您的应用程序和数据。这种方法(使用 BitBake 配方)的主要优点是将应用程序添加到映像变得容易,并且应用程序将准确链接到目标上可用的库,因此您可以准确使用这些版本中的功能.

使用上面的示例 makefile,您还可以通过简单地 运行ning make.

直接为您的主机编译