0

I have a directory which again contains subdirectories, which are built has part of other recipe and moved to DEPLOY_DIR_IMAGE using deploy bb class. So now I want to copy it to main image boot partition.

If it was a single file then appending required filename to IMAGE_EFI_BOOT_FILES variable, then yocto copies it to /boot. But same doesn't work for directories containing subdirectories please provide style to include even the subdirectories. Thank you

PS: I have tried appending IMAGE_EFI_BOOT_FILES += "parent_dir/*" didnt work.

2 Answers2

0

It is obvious that IMAGE_EFI_BOOT_FILES is acting like the well known IMAGE_BOOT_FILES and other variables that are responsible for having the files necessary to be shipped in the boot partition. And that needs files and not directories.

So, if you do not need to specify all the files by hand, but instead you want to pass the directory, I suggest you use a python method to collect the files for you and append them to the variable.

See the following example I developed and tested:

def get_files(d, dir):
    import os
    dir_path = dir
    if not os.path.exists(os.path.dirname(dir)):
        dir_path = d.getVar(dir)
    return ' '.join(f for f in os.listdir(d.getVar(dir)) if os.path.isfile(f))

IMAGE_EFI_BOOT_FILES += "${@get_files(d, 'DEPLOY_DIR_IMAGE')}"

The method will test if the argument is a real path then it will directly check for files, if not it will assume that it is a bitbake variable and it will get its content, so if DEPLOY_DIR_IMAGE is, for example, /home/user/dir, passing DEPLOY_DIR_IMAGE or /home/usr/dir will give the same result.

IMPORTANT

It is obvious also that IMAGE_EFI_BOOT_FILES is used in a .conf file such as local.conf or a custom machine configuration file. So adding that python function in .conf file will not work. I suggest creating a class for it and inherit it globally in your .conf file:

  • meta-custom/classes/utils.bbclass

  • local.conf:

INHERIT += "utils"
IMAGE_EFI_BOOT_FILES += "${@get_files(d, 'DEPLOY_DIR_IMAGE')}"

Try this and let me know in the comments.

EDIT

I have just realized that bitbake already imports os within python expressions expansions, so you can do it in one line without any need for a separate python function:

PATH = "/path/to/directory/"  or
PATH = "A variable containing the path"
IMAGE_EFI_BOOT_FILES += "${@' '.join('%s' % f for f in os.listdir('${PATH}') if os.path.isfile(f))}"
Talel BELHADJSALEM
  • 3,199
  • 1
  • 10
  • 30
  • Thank you Talel, I am aware that the functionality can be implemented using python funcs, I was looking for a Yocto intrinsics which can achieve the same. And in the solution provided you there are some mistakes, which will not recursively enter each subdirectory and u forgot append directory path in os.path.isfile(f)) , better if we can exploit os.walk for this. – geralt rivia May 06 '22 at 13:35
  • continued ... And another limitation is above solution will flatten the directory i.e all files in one level hence destroying directory tree structure , which isn't indented. but true all this can be resolved with little tweaks to solution u proposed – geralt rivia May 06 '22 at 13:35
  • Thanks for the review, do you suggest adding recursive directories handling ? If yes I will adapt it to my solution. – Talel BELHADJSALEM May 06 '22 at 14:53
  • Thanks for asking, it is your wish to add that. I have a dev code to to recursive directory handling and retaining dir structure during copy to boot/ partition , will be updating here later to help someone out there. – geralt rivia May 06 '22 at 15:14
0

Note: I am looking for Yocto built-in which can achieve solution for above mentioned , would like to share other way to resolve the functionality for community's benefit.

Add following in bb file if you are using one or refer to talel-belhadjsalem answer to use utils.bbclass.

def add_directory_bootfs(d, dirname, bootfs_dir):
    file_list = list()
    boot_files_list = list()
    deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE')
    for (dirpath, dirnames, filenames) in os.walk(os.path.join(deploy_dir_image, dirname)):
        file_list += [os.path.join(dirpath, file) for file in filenames]
    for file in file_list:
        file_rel_path = os.path.relpath(file, os.path.join(deploy_dir_image, dirname))
        boot_file_entry = os.path.join(dirname, file_rel_path) + ';' + os.path.join(bootfs_dir, dirname, file_rel_path)
        boot_files_list.append(boot_file_entry)
    return ' '.join(boot_files_list)

IMAGE_EFI_BOOT_FILES += "${@add_directory_bootfs(d, 'relative_path_to_dir_in_deploy_dir_image', 'EFI/BOOT')}"