I'm attempting to setup the avr toolchain while still utilizing the upstream binutils and gcc recipes. For example, the base recipe for binutils is in yocto/poky/meta/recipes-devtools/binutils/. I have my custom avr-flavored recipe in yocto/meta-avr/recipes-devtools/avr-binutils/.
Inside the custom avr recipe are a few environment variable changes (TARGET_PREFIX, TARGET_SYS, etc), and then a "require recipes-devtools/binutils/binutils-cross_2.23.2.bb". This lets me depend on the upstream binutils recipe without having to replicate everything manually.
Now, the problem I'm having is that the upstream recipe has a bunch of patches that get applied. I can't figure out how to have my custom recipe point to a filepath outside its layer so I can use the patches that already exist. I've tried using FILESEXTRAPATHS_prepend with no luck.
I think you're looking for a .bbappend file, which will inherit the existing recipe and allow you to override some parts of it.
Related
I have a Linux kernel for NXP i.MX6. There are some capture kernel modules in /driver/media/platform/mxc/capture.
One of the files called mxc_v4l2_capture.c. I had to change this file for using it with my own new kernel driver.
I created a repository with my driver and the sources for mxc_v4l2_capture. Then I made a new Yocto recipe in my layer recipies-kernel -> kernel-modules->my-kernel-module.bb
Yocto can build these two kernel modules (my-kernel-module.ko and mxc_v4l2_capture.ko).
Okay, now there is a problem because the kernel recipe already builds the mxc_v4l2_capture module. Therefore I want to manipulate the Makefile for the original kernel modules and exclude the make of mxc_v4l2_capture.
I have created the patch but I don't know how to use the patch with Yocto. Where to place it and how can I call it?
Normally I put a patch into a .bbappend file and finish but I don't know the name of the recipe that build the kernel modules.
It would be great if there is a way without manipulating this Makefile.
Is there a way to solve this with my kernel module recipe?
mxc_v4l2_capture.c is in-tree kernel driver. If you want to change the in-tree driver code and compile, it's highly recommended to patch the kernel and compile the kernel with usual recipe.
Having additional bitbake recipe for the in-tree kernel module is not necessary. To patch the kernel and compile, you can use .bbappend or .bb itself. For example,
if you have recipes-kernel/linux/linux-stable_4.19.75.bb in your Yocto BSP layer, you can add the patch to SRC_URI as below.
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
SRC_URI += "file://mxc_v4l2_capture.patch"
Now, you create recipes-kernel/linux/linux-stable-4.19.75/ and copy the mxc_v4l2_capture.patch file inside.
Or if you don't have permission or not possible to modify the Kernel recipe in BSP layer, you can create .bbappend in your custom layer. For the above example, you can create linux-stable_4.19.75.bbappend (specific version) or linux-stable_%.bbappend (any version). Then place the same content as mentioned above.
Yocto supports various patch formats, refer here for more details.
Look at this answer I wrote some days ago. The steps are basically the same. Using
devtool modify virtual/kernel
will create a working copy in build/workspace where you can do the work you want. Commiting those changes to the local branch and running
devtool finish linux-mainline <path-to-your-layer>
will create a .bbappend file with the patches already created and put to the correct location for you.
If you want to learn how to do it manually follow the advice #Parthiban gave.
Userspace package built for and along with root file system image of some embedded Linux-based system here (using Yocto project) apparently uses autotools - one can see Makefile.am's and configure.ac in package's sources. pkg-config or its successor seems to be used too (.pc.in is present), however out-of scope here.
Package in focus here does it this way (by involving autotools) as in the beginning of its development it was apparently the line of lowest resistance to copy and adopt build scripts from similar but already-existing package.
Actually autotools seem to be dispensable when building with Yocto, as Yocto build system meta data do specify target precisely enough for every target. For good reason standard build flow in Yocto is download, unpack, patch, configure, build,... with scan-and-detect-target-environment not included in this chain.
Now I wonder if it was good to streamline package's build process by removing autotools stage. I'm going to conduct it by proceeding in sequence of few steps starting with replacing .am file with real makefile. Question is if it will be sufficient enough to find env. variables defined and used in .am and .ac then transfer them to makefile? Remaining target-device specification should actually come from Yocto build system meta data. Possibly it will work this straightforward if to build package in scope of root file system image build. But how to ensure build environment provides complete target device specification when building only this package bitbake package-name?
Replacing autotools with a bare makefile isn't a trivial operation, as https://nibblestew.blogspot.co.uk/2017/12/a-simple-makefile-is-unicorn.html demonstrates nicely.
If you don't want to use autotools in your packages then alternatives such as Meson are generally faster.
I've used Buildroot quite a bit over the years, and I've always managed to find solutions to the obstacles I've hit. But this one has me going in circles.
I've added a git-sourced python tool as a host package to my Buildroot build for an ARM target. I have completed the work on the package/Config.in.host and the package/toolname/Config.in.host as well as package/toolname/toolname.mk files. Everything looks to be in order. I have compared the work with what the add_new_package.wizard outputs.
The new option DOES appear in the menuconfig.
It is NOT available as a make target, although I do have target-side packages I have included that ARE valid make targets. i.e. I can run:
make target-side-package-name
and those packages are built just fine.
I cannot run:
make host-side-package-name as I get the error "No rule to make target".
So there must be something I'm doing incorrectly with the host package, although I clearly am doing the right things with the target packages.
Everything points to Buildroot simply ignoring my host package, other than sticking it into the menuconfig. My hours of searching on the webs have led to not one single post about someone having this same problem. I'm missing something obvious I would think.
My question is - what debugging can I do, where can I look to find out what is keeping Buildroot from properly recognizing my new package?
EDIT: I believe I understand now that part of the problem is the build order, and perhaps I can fix one issue with dependency directives. My target package that relies on the host package was being built first. I had assumed as common sense would dictate that host packages would be dealt with first, but that is apparently not true.
EDIT: Posting the .mk file
TOOLNAME_VERSION = 2
TOOLNAME_SITE = $(call github,devname,toolname,$(TOOLNAME_VERSION))
TOOLNAME_SETUP_TYPE = setuptools
TOOLNAME_LICENSE = GPL-3.0
TOOLNAME_LICENSE_FILES = LICENSE
HOST_TOOLNAME_DEPENDENCIES = host-python-library
$(eval $(host-python-package))
TOOLNAME = $(HOST_DIR)/usr/bin/toolname
As I hinted before, it is now running just fine so I know it's mostly set up correctly, the remaining problem is the make target is missing. Per the Buildroot manual, I should have one available.
I have now discovered that the missing make target is in fact making it impossible to build other packages dependent upon this one. The build of the dependent package now fails because "No rule to make" on the toolname package it is made to depend upon through
TARGET_PACKAGE_DEPENDENCIES = toolname
Can you post your toolname.mk? It sounds like you forgot to add the $(eval $(host-python-package)) line.
Hallelujah! The answer is that the make target name is NOT toolname, but is instead host-toolname. The root cause of the problem is the lack of mention of this nuance in section 8.12.5 of the Buildroot documentation. I stumbled across the answer while researching package dependencies in Chapter 17, where it does identify proper use for that specific case.
I'd like to define a Makefile with implicit rules for a bunch of executables, some of which require linking against a custom-built library (let's call it libedich.a).
My problem is that I'd like to be able to build those executables that do not require libedich.a when the latter hasn't been built yet. If I simply add -ledich to the LDLIBS variable, I get errors when libedich.a doesn't exist:
/usr/bin/ld: cannot find -ledich
How do I tell ld that it's okay to continue linking when a given library doesn't exist?
A common solution is to create a dummy archive so that GCC will find it. Since the executable doesn't need any symbols from the library, it won't error out. Like this,
# create an empty archive.
ar cru libedich.a
or even simpler,
echo '!<arch>' >libedich.a
This is the downside of using one LDLIBS variable to hold all of the library dependencies and re-using it for every target, even though you know some targets only need a subset of the libraries. You have several options:
There are probably fancy IDE's and build tools out there that try to infer library dependencies from context, saving you from manually specifying them for each target.
Switch to using shared libraries.
Fix the target in your Makefile so that it depends on libedich.a (even if it doesn't need to). This will work if you are building everything anyway and don't care what order the targets proceed in.
Manually specify the library dependencies for each target in your Makefile.
The last option is my recommendation; it is more work, but eliminating the false dependencies in your Makefile will enable you to build (perhaps most of) your targets even if one of the dependencies is broken. One convenient way to do this is with target-specific variables:
targetname::LDLIBS+=-ledich
You probably also want to be aware of make --keep-going (make -k)
I'd like to build my own GNU/Linux system from scratch using cross-compilation (just like the CLFS project). Most of the packages I would use are distributed with a configure script, and you just have to run it with the right arguments. For various reasons, I'd like to skip this step, and run make instead. Of course I need a custom Makefile for this to work. The question is: is it feasible to create custom Makefiles without having to read and comprehend all the source code? Is it possible to just read the configure.ac files or something like those? Thanks.
Probably not. What happens is that configure tests which of a number of options are most suited for your environment then substitutes them into Makefile.in to build the Makefile, config.h.in to build config.h etc. You could skip running configure and just determine what these values should be from simple cases of configure.ac (or just keep one huge cache if your environment won't change) but I think packages can define extra inline checks in configure.ac that you'd have to parse and implement correctly. It's going to be a lot easier to just run configure, even if you do have to figure out the correct parameter values for your cross-compiled environment without runtime checks.
However hopefully you only need to build a small number of packages cross (kernel, glibc, gcc, make, bash, etc.), then you can switch into your new environment and build the remaining packages there using configure? If you want inspiration as to what switch values you should be using you can always look at the parameters in Fedora SRPMs or Debian source-debs.