From 29d1738329ddf4e63844a9ad1158a1d41e2ee343 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Thu, 4 Aug 2016 12:02:11 +0300 Subject: package.bbclass: better handling of middle-path dir symlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For example in a directory structure like this . ├── symlink -> foo/bar └── foo └── bar └── file 'file' could be referenced by specifying e.g. 'foo/bar/file' or 'symlink/file'. In cases like this populate_packages() might crash if the file was referenced (in FILES) via the symlinked directory. The outcome depends on how the user defined FILES_pn. This patch should make the function behave more consistently. It looks for files which are referenced via symlinked directories and handles them separately, failing if their parent directory is a non-existent path. For example, defining FILES_{PN} = "symlink/file" causes a build failure because symlinks target 'foo/bar' is not included at all. [YOCTO #9827] Signed-off-by: Markus Lehtonen Signed-off-by: Ross Burton --- meta/classes/package.bbclass | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass index 81acc10367..5cb1939e54 100644 --- a/meta/classes/package.bbclass +++ b/meta/classes/package.bbclass @@ -259,14 +259,27 @@ def files_from_filevars(filevars): continue files.append(f) - for f in files: + symlink_paths = [] + for ind, f in enumerate(files): + # Handle directory symlinks. Truncate path to the lowest level symlink + parent = '' + for dirname in f.split('/')[:-1]: + parent = os.path.join(parent, dirname) + if dirname == '.': + continue + if cpath.islink(parent): + symlink_paths.append(f) + files[ind] = parent + f = parent + break + if not cpath.islink(f): if cpath.isdir(f): newfiles = [ os.path.join(f,x) for x in os.listdir(f) ] if newfiles: files += newfiles - return files + return files, symlink_paths # Called in package_.bbclass to get the correct list of configuration files def get_conffiles(pkg, d): @@ -281,7 +294,7 @@ def get_conffiles(pkg, d): if conffiles == None: conffiles = "" conffiles = conffiles.split() - conf_orig_list = files_from_filevars(conffiles) + conf_orig_list = files_from_filevars(conffiles)[0] # Remove links and directories from conf_orig_list to get conf_list which only contains normal files conf_list = [] @@ -1111,7 +1124,7 @@ python populate_packages () { filesvar.replace("//", "/") origfiles = filesvar.split() - files = files_from_filevars(origfiles) + files, symlink_paths = files_from_filevars(origfiles) if autodebug and pkg.endswith("-dbg"): files.extend(debug) @@ -1157,6 +1170,15 @@ python populate_packages () { if ret is False or ret == 0: raise bb.build.FuncFailed("File population failed") + # Check if symlink paths exist + for file in symlink_paths: + if not os.path.exists(os.path.join(root,file)): + bb.fatal("File '%s' cannot be packaged into '%s' because its " + "parent directory structure does not exist. One of " + "its parent directories is a symlink whose target " + "directory is not included in the package." % + (file, pkg)) + os.umask(oldumask) os.chdir(workdir) -- cgit 1.2.3-korg