问题
I wrote an application on my laptop (Ubuntu 14.04) that depends on GStreamer and would like to cross-compile it for my Yocto Linux target (iMX6S-Wandboard). How do I cross-compile the application so that it runs on the target board and is able to use the GStreamer libraries?
Thank you,
Toan
UDPATE:
My 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 = 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
My *.bb file:
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
}
Build log:
$ 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.
Deploy log:
$ 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.
回答1:
The Yocto eSDK allows you to cross-compile applications for your Yocto target on your PC using exactly the compiler and libraries used for the target itself. There is no need to add GCC to the target. The eSDK can be generated from a Yocto source tree, but since you have the source installed anyways, you don't need to install the eSDK and can build directly from the source. All of the this is not ARM specific but the general Yocto workflow to cross-compile for a specific Yocto target.
To do this, first setup the Yocto build environment as usual by changing into the Yocto directory, running source setup-environment yourbuilddir
.
Then, run devtool add, pass the name of your application (will be used for the BitBake recipe) and the path to the existing source tree, e.g.:
devtool add myhelloworld /home/user/Projects/myhelloworld
This will automatically generate a recipe and add a layer named workspace
to your Yocto source tree. The recipe will be named something like /yocto/source/path/yourbuilddir/workspace/recipes/myhelloworld/myhelloworld.bb
. You can edit it by running
devtool edit-recipe myhelloworld
Prefix the command with something like EDITOR=gedit
to use your favourite text editor. Modify the recipe to build your application correctly; BitBake will automatically determine whether to run make
or CMake
. An example using make
would be:
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
lists the dependencies, I added gstreamer1.0
and also pkgconfig-native
which is neccessary when using pkg-config
inside the Makefile
. You can add more dependencies to DEPENDS
if you need them, for example boost openssl
.
A suitable example makefile would be:
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
Inside your Makefile
, make sure that make install
installs your application binary into $(DESTDIR)$(BINDIR)/myhelloworld
and data files (e.g. images) into $(DESTDIR)$(DATADIR)/somefile
. On the target, your binary will then be located in /usr/bin/myhelloworld
and the data files in /usr/share/myhelloworld
. In the Makefile
, pass "-DDATADIR=\"$(DATADIR)/\""
to the compiler such that you can open your data files by something like fopen(DATADIR "somepic.png", "rb");
. For the source file main.c
, you can use the GStreamer example 1.
Save recipe, Makefile
and main.c
, and then run
devtool build myhelloworld
to compile your application. If all goes well, you can then install it to the target via SSH by running e.g.
devtool deploy-target myhelloworld root@targethostname
You can then SSH to the target and run your application by typing myhelloworld
. To uninstall it:
devtool undeploy-target myhelloworld root@targethostname
If you later decide to ship your application as part of the Yocto image, modify the recipe for your system image and add:
IMAGE_INSTALL_append = " yourhelloworld"
Keep the space after the first quote. When building the image, your application and data will be included. The main advantage of this approach (using a BitBake recipe) is that adding the application to the image becomes easy, and that the application will be linked against exactly the libraries available on the target, so you can use exactly the features present in these versions.
Using the example makefile above, you can also directly compile for your host PC by simply running make
.
来源:https://stackoverflow.com/questions/60815312/how-to-cross-compile-an-application-with-library-dependencies-for-yocto-linux