Search code examples
linuxyoctomdnsnxp-microcontroller

How does one get everything right to build mDNS in Yocto?


Can someone help me in setting up the recipe to build mDNS in Yocto and/or correct any other mistakes I may have made?
I previously successfully built mDNS and got it running in Linaro embedded Linux.
This is a pretty detailed post, to try to err on the side of giving enough information. As one responder wrote in a forum message that I saw recently: "Welcome to Yocto. Here's your bottle of whiskey and Advil..."

Building in Linaro Linux: I had obtained this .tar of mDNS from Apple: https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-878.200.35.tar.gz
Following this got it going: https://github.com/balaji-reddy/mDNSResponder .
I made a base folder /mDNS/ for my mDNS stuff and extracted the .tar there, creating an mDNSResponder-878.200.35/ folder. I did cd into that.
It build readily for me in Linaro using the command: make os="linux" -C "mDNSPosix"

I got 8 files in /mDNS/mDNSR-878.200.35/mDNSPosix/build/prod/ :
40,592 libdns_sd.so
55,960 libnss_mdns-0.2.so
370,288 mDNSClientPosix
448,608 mdnsd
374,616 mDNSIdentify
387,904 mDNSNetMonitor
373,960 mDNSProxyResponderPosix
379,768 mDNSResponderPosix
Then, still in mDNSResponder-878.200.35/, I did:
make install os="linux" -C "mDNSPosix"

Among other things, this install starts a demon running. It also copies libdns_sd.so, and libnss_mdns-0.2.so to /lib/, which should be in the path.
These lines are included in the install output:
--------------------------------------------------------------**
Starting Apple Darwin Multicast DNS / DNS Service Discovery daemon: mdnsd.
/usr/sbin/mdnsd installed
--------------------------------------------------------------**

For Yocto, I figured I would add the copy of libdns_sd.so to the /lib/ folder in the destination to my recipe so I could link another module to it before I ran the make install, which has to be done running on the target. But if I build that other module in Yocto, I think I should add copying it to /lib/ under my tmp/work/ dir, not D, the destination. My do_install line:
install -m 0755 ${S}/mDNSResponder-878.200.35/mDNSPosix/build/prod/libdns_sd.so ${D}${base_libdir}
is for copying it to /lib/ in D. How would I correctly write that line to copy it to /lib/ under ~/Yocto/imx-yocto-bsp/build-wayland/tmp/work/aarch64-poky-linux/?

The Yocto low-level folder isn't very important; I just felt that I wanted a
Yocto folder under my home dir to hold my Yocto stuff. I created imx-yocto-bsp
following the i.MX_Yocto_Project_User's_Guide.pdf.

First, I had followed the i.MX_Yocto_Project_User's_Guide.pdf, "IMXLXYOCTOUG" from the imx-yocto-L5.4.47_2.2.0 download, to get my basic system, which worked. I got that from: www.nxp.com/imx8mnanoevk -> https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-8m-nano-applications-processor:8MNANOD4-EVK
And downloaded and unpacked this .zip described in the next three lines:
L5.4.47_2.2.0_LINUX_DOCS (REV L5.4.47_2.2.0 ) UPDATED
i.MX L5.4.47_2.2.0 for Linux BSP Documentation. Includes Release Notes, User Guide.
ZIP 11.6 MB 03 Nov 2020 L5.4.47_2.2.0_LINUX_DOCS [ English ]
I'm doing this for the i.MX 8M nano eval board.
The build-wayland folder in my path above is my build folder.
I had done the following line to get that.
~/Yocto/imx-yocto-bsp$ DISTRO=fsl-imx-wayland MACHINE=imx8mnddr4evk source imx-setup-release.sh -b build-wayland
One result of that was to end up with the directory changed to the build-wayland folder. It turned out it was the right thing to do to stay in that folder for subsequent steps in the i.MX_Yocto_Project_User's_Guide.pdf, such as my "bitbake imx-image-multimedia" command that I did; I don't believe the .pdf made that clear.

So I previously got this working on a Linux host PC running Ubuntu 18.04.4 "Bionic Beaver" and flashed the resulting images onto my i.MX 8M nano board.
One line of many I see in my UART output is:
Welcome to NXP i.MX Release Distro 5.4-zeus (zeus)!
I followed the following very good tutorial and also added a helloworld layer as it shows and had helloworld working on my target board after flashing the built .wic image from the host:
https://medium.com/the-innovation/how-to-prepare-a-helloworld-c-recipe-with-yocto-project-1f74c296a777
It is a good tutorial, for one thing, because it clearly describes the directory structure and can be followed. Be careful about a typo that the author put in, however. He starts out spelling helloworld.c as hello-world.c in his Steps 5 and 6 then switches to helloworld.c in his Step 7. You have to catch that and fix the spelling in your work when you notice the switch.

I used the structure that he, George Calin, showed, to make my mdns layer.

In my build folder, build-wayland, I created meta-mdns-so alongside the meta-helloworld-app folder that I had created following the tutorial. I used similar steps as given in the tutorial, including
bitbake-layers create-layer meta-mdns-so
bitbake-layers add-layer meta-mdns-so

This got me through Step 4 in the tutorial in a similar manner.
This created the following tree in meta-mdns-so (one dash indented per level):

conf
-layer.conf
COPYING.MIT
README
recipes-example
-mdns
--files
---mDNSResponder-878.200.35.tar.gz
--mDNSResponder_878.200.35.bb

Note that items followed by items that are more indented are directories.

Putting mDNSResponder-878.200.35.tar.gz under files I found out from https://wiki.yoctoproject.org/wiki/Building_your_own_recipes_from_first_principles However the information here is about seven years old and background info links have rotted.
There's more information in the Yocto Mega Manual at https://www.yoctoproject.org/docs/3.0/mega-manual/mega-manual.html .
See "7.3.21.3. Makefile-Based Package"

Here's the recipe in mDNSResponder_878.200.35.bb that I came up with for my first try:
----------------------------------------------------------------------
DESCRIPTION = "The mDNS component"
PRIORITY = "optional"
SECTION = "protocols"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://mDNSResponder-878.200.35.tar.gz"
# S = "${WORKDIR}"
# -Shouldn't set S because BitBake expects the source to be in a dir called
# mDNSResponder-878.200.35 in the work dir.
# Don't need a do_compile step since by default BitBake starts the make command
# to compile the application.
# But need additional make options
EXTRA_OEMAKE = "'os="linux"' '-C "mDNSPosix"'"
do_install() {
install -d ${D}${base_libdir}
install -m 0755 ${WORKDIR}/mDNSResponder-878.200.35/mDNSPosix/build/prod/libdns_sd.so ${D}${base_libdir}
}
----------------------------------------------------------------------**
I did bitbake mdns in ~/Yocto/imx-yocto-bsp/build-wayland$ .

When coming back to this work in a fresh terminal window I always do
~/Yocto/imx-yocto-bsp$ source setup-environment build-wayland
It puts me in my build-wayland folder: ~/Yocto/imx-yocto-bsp/build-wayland$

The bitbake seemed to do the compile fine, and I got content under:
~/Yocto/imx-yocto-bsp/build-wayland/tmp/work# find -iname mdns
Found lots, including this folder:
./aarch64-poky-linux/mdns/878.200.35-r0/

As in the helloworld tutorial:
Step 10. Add package to conf/local.conf in variable IMAGE_INSTALL and set the details for next image
I added:
IMAGE_INSTALL_append=" mdns" after the line, 'CONF_VERSION' = "1"'.

I did the bitbake from my build dir: bitbake imx-image-multimedia

Under my deploy folder, in ~/Yocto/imx-yocto-bsp/build-wayland/tmp/deploy/images/imx8mnddr4evk/, I got imx-image-multimedia-imx8mnddr4evk-20210211215119.rootfs.wic.bz2 With the up-to-date timestamp of 2021/02/11 (Thurs) 21:51:19 (0000 UTC).

Flashing it onto my i.MX 8M nano board, it
-didn't have libdns_sd.so in the /lib/ folder
-didn't have a /mDNSR-878.200.35 folder in root.
-find -iname mdns doesn't find mDNSR-878.200.35; finds a screenful of files.
-the /mDNSR-878.200.35/mDNSPosix/build/prod/ folder with its 8 build artifacts wasn't there.

However, on the bitbake host, the 8 build artifacts were found:
~/Yocto/imx-yocto-bsp/build-wayland/tmp/work/aarch64-poky-linux/mdns/878.200.35-r0/mDNSResponder-878.200.35/mDNSPosix/build/prod# ls -l
total 9452
-rwxr-xr-x 1 159200 Feb 11 16:07 libdns_sd.so
-rwxr-xr-x 1 239856 Feb 11 16:07 libnss_mdns-0.2.so
-rwxr-xr-x 1 1504904 Feb 11 16:07 mDNSClientPosix
-rwxr-xr-x 1 1750944 Feb 11 16:07 mdnsd
-rwxr-xr-x 1 1481136 Feb 11 16:07 mDNSIdentify
-rwxr-xr-x 1 1525392 Feb 11 16:07 mDNSNetMonitor
-rwxr-xr-x 1 1493112 Feb 11 16:07 mDNSProxyResponderPosix
-rwxr-xr-x 1 1511048 Feb 11 16:07 mDNSResponderPosix

I concluded that the compile part was fine but my do_install command was wrong.
Can someone correct my recipe for me?

For my second try I changed only the do_install() in the recipe to this:
--------------------------------------------------------------------------------
do_install() {
install -t ${S} ${D}
install -d ${D}${base_libdir}
install -m 0755 ${S}/mDNSResponder-878.200.35/mDNSPosix/build/prod/libdns_sd.so ${D}${base_libdir}
}
--------------------------------------------------------------------------------
That's two changes, first copying from S to D to try to get the mDNSResponder-878.200.35/ dir copied over to the destination, and then trying the "install - m" command from S rather than WORKDIR.

Retrying the bitbake: bitbake imx-image-multimedia, it indicated at the end that all 6968 tasks didn't need to be rerun.

I tried: ~/Yocto/imx-yocto-bsp/build-wayland$ bitbake -c clean mdns -- and got:
NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded.

~/Yocto/imx-yocto-bsp/build-wayland$ bitbake imx-image-multimedia -- got:
NOTE: Tasks Summary: Attempted 6968 tasks of which 6967 didn't need to be rerun and all succeeded.
It typically flashes and erases a bunch of activity, which it did this time. It might be nice to have that remaining displayed to be able to study it.

It didn't update anything in:
~/Yocto/imx-yocto-bsp/build-wayland/tmp/deploy/images/imx8mnddr4evk#
No longer had mDNSResponder-878.200.35/ in ~/Yocto/imx-yocto-bsp/build-wayland/tmp/work/aarch64-poky-linux/mdns/878.200.35-r0/ .

I tried: bitbake -c cleansstate mdns -- got:
NOTE: Tasks Summary: Attempted 2 tasks of which 0 didn't need to be rerun and all succeeded.

Did: ~/Yocto/imx-yocto-bsp/build-wayland$ bitbake imx-image-multimedia
-Got the typical bitbake output, then:
Sstate summary: Wanted 6 Found 0 Missed 6 Current 2580 (0% match, 99% complete)
NOTE: Tasks Summary: Attempted 6968 tasks of which 6954 didn't need to be rerun and all succeeded.
This time I saw do_compile of mdns and 878.200.25 etc.

Again had mDNSResponder-878.200.35 in
~/Yocto/imx-yocto-bsp/build-wayland/tmp/work/aarch64-poky-linux/mdns/878.200.35-r0/.
Have the build artifacts in mDNSPosix in the host at:
~/Yocto/imx-yocto-bsp/build-wayland/tmp/work/aarch64-poky-linux/mdns/878.200.35-r0/mDNSResponder-878.200.35/mDNSPosix/build/prod/
Still don't have an updated image since Thurs Feb 11 in ~/Yocto/imx-yocto-bsp/build-wayland/tmp/deploy/images/imx8mnddr4evk/ .

Can someone correct my recipe and any other mistakes I may have made? Is it my do_install()?

In my do_install(), I have:
install -m 0755 ${S}/mDNSResponder-878.200.35/mDNSPosix/build/prod/libdns_sd.so ${D}${base_libdir}
which is for copying it to /lib/ in D. How would I correctly write that line to copy it to /lib/ under
~/Yocto/imx-yocto-bsp/build-wayland/tmp/work/aarch64-poky-linux/ for use to link to the next module I have to build on the host?

In the meantime, I'll try deleting my imx-image-multimedia-imx8mnddr4evk-20210211215119.rootfs.wic.bz2 and redoing the bitbake.
...Deleting imx-image-multimedia-imx8mnddr4evk-20210211215119.rootfs .tar.bz2 and .wic.bz2 didn't help; they didn't get recreated even after I redid the above cleans and bitbake.

Best regards,

Later: Followup question: Where can I obtain the mdns.service file needed for building mDNS in Yocto?


Solution

  • There is already a recipe for mDNS version 878.200.35: https://git.openembedded.org/meta-openembedded/tree/meta-networking/recipes-protocols/mdns/mdns_878.200.35.bb?h=zeus