diff --git a/meta/classes/devtool-source.bbclass b/meta/classes/devtool-source.bbclass
index 9762003ba75..d4e307e886b 100644
--- a/meta/classes/devtool-source.bbclass
+++ b/meta/classes/devtool-source.bbclass
@@ -92,9 +92,13 @@ python devtool_post_unpack() {
             for fname in local_files:
                 f.write('%s\n' % fname)
 
-    if os.path.dirname(srcsubdir) != workdir:
+    if srcsubdir.startswith(unpackdir) and srcsubdir != unpackdir:
+        srcparentdir = unpackdir
+    else:
+        srcparentdir = workdir
+    if os.path.dirname(srcsubdir) != srcparentdir:
         # Handle if S is set to a subdirectory of the source
-        srcsubdir = os.path.join(workdir, os.path.relpath(srcsubdir, workdir).split(os.sep)[0])
+        srcsubdir = os.path.join(srcparentdir, os.path.relpath(srcsubdir, srcparentdir).split(os.sep)[0])
 
     scriptutils.git_convert_standalone_clone(srcsubdir)
 
diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py
index f8cf65f4a84..e1717bc4ab5 100755
--- a/scripts/lib/devtool/ide_sdk.py
+++ b/scripts/lib/devtool/ide_sdk.py
@@ -334,7 +334,7 @@ class RecipeModified:
         self.srctree = workspace[workspacepn]['srctree']
         # Need to grab this here in case the source is within a subdirectory
         self.real_srctree = get_real_srctree(
-            self.srctree, recipe_d.getVar('S'), recipe_d.getVar('WORKDIR'))
+            self.srctree, recipe_d.getVar('S'), recipe_d.getVar('WORKDIR'), recipe_d.getVar('UNPACKDIR'))
         self.bbappend = workspace[workspacepn]['bbappend']
 
         self.ide_sdk_dir = os.path.join(
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index cdfdba43eef..9a8f990d84a 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -625,7 +625,12 @@ def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works
                 srcsubdir = f.read()
         except FileNotFoundError as e:
             raise DevtoolError('Something went wrong with source extraction - the devtool-source class was not active or did not function correctly:\n%s' % str(e))
-        srcsubdir_rel = os.path.relpath(srcsubdir, os.path.join(tempdir, 'workdir'))
+        unpackdir = d.getVar('UNPACKDIR')
+        if d.getVar('S').startswith(d.getVar('UNPACKDIR')):
+            srcparentdir = os.path.relpath(d.getVar('UNPACKDIR'), d.getVar('WORKDIR'))
+        else:
+            srcparentdir = ''
+        srcsubdir_rel = os.path.relpath(srcsubdir, os.path.join(tempdir, 'workdir', srcparentdir))
 
         # Check if work-shared is empty, if yes
         # find source and copy to work-shared
@@ -742,14 +747,22 @@ def get_staging_kbranch(srcdir):
         staging_kbranch = "".join(branch.split('\n')[0])
     return staging_kbranch
 
-def get_real_srctree(srctree, s, workdir):
+def get_real_srctree(srctree, s, workdir, unpackdir):
     # Check that recipe isn't using a shared workdir
     s = os.path.abspath(s)
     workdir = os.path.abspath(workdir)
-    if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir:
+    unpackdir = os.path.abspath(unpackdir)
+
+    if s.startswith(workdir) and s != workdir:
         # Handle if S is set to a subdirectory of the source
-        srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1]
-        srctree = os.path.join(srctree, srcsubdir)
+        if s.startswith(unpackdir) and s != unpackdir:
+            srcparentdir = unpackdir
+        else:
+            srcparentdir = workdir
+
+        if os.path.dirname(s) != srcparentdir:
+            srcsubdir = os.path.relpath(s, srcparentdir).split(os.sep, 1)[1]
+            srctree = os.path.join(srctree, srcsubdir)
     return srctree
 
 def modify(args, config, basepath, workspace):
@@ -907,7 +920,7 @@ def modify(args, config, basepath, workspace):
 
         # Need to grab this here in case the source is within a subdirectory
         srctreebase = srctree
-        srctree = get_real_srctree(srctree, rd.getVar('S'), rd.getVar('WORKDIR'))
+        srctree = get_real_srctree(srctree, rd.getVar('S'), rd.getVar('WORKDIR'), rd.getVar('UNPACKDIR'))
 
         bb.utils.mkdirhier(os.path.dirname(appendfile))
         with open(appendfile, 'w') as f:
diff --git a/scripts/lib/devtool/upgrade.py b/scripts/lib/devtool/upgrade.py
index 0dace1fb240..e584e03e17c 100644
--- a/scripts/lib/devtool/upgrade.py
+++ b/scripts/lib/devtool/upgrade.py
@@ -571,7 +571,7 @@ def upgrade(args, config, basepath, workspace):
         else:
             srctree = standard.get_default_srctree(config, pn)
 
-        srctree_s = standard.get_real_srctree(srctree, rd.getVar('S'), rd.getVar('WORKDIR'))
+        srctree_s = standard.get_real_srctree(srctree, rd.getVar('S'), rd.getVar('WORKDIR'), rd.getVar('UNPACKDIR'))
 
         # try to automatically discover latest version and revision if not provided on command line
         if not args.version and not args.srcrev:
