Reimplement addbuilddir() in C inside getpath.c, so as to execute it
at interpreter startup before importing any non-builtin modules.
Should fix #9589.
diff --git a/setup.py b/setup.py
index 4e08eea..c81358c 100644
--- a/setup.py
+++ b/setup.py
@@ -22,6 +22,10 @@
 # This global variable is used to hold the list of modules to be disabled.
 disabled_module_list = []
 
+# File which contains the directory for shared mods (for sys.path fixup
+# when running from the build dir, see Modules/getpath.c)
+_BUILDDIR_COOKIE = "pybuilddir.txt"
+
 def add_dir_to_list(dirlist, dir):
     """Add the directory 'dir' to the list 'dirlist' (at the front) if
     1) 'dir' is not already in 'dirlist'
@@ -224,6 +228,16 @@
             args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags
         self.compiler.set_executables(**args)
 
+        # Not only do we write the builddir cookie, but we manually install
+        # the shared modules directory if it isn't already in sys.path.
+        # Otherwise trying to import the extensions after building them
+        # will fail.
+        with open(_BUILDDIR_COOKIE, "wb") as f:
+            f.write(self.build_lib.encode('utf-8', 'surrogateescape'))
+        abs_build_lib = os.path.join(os.path.dirname(__file__), self.build_lib)
+        if abs_build_lib not in sys.path:
+            sys.path.append(abs_build_lib)
+
         build_ext.build_extensions(self)
 
         longest = max([len(e.name) for e in self.extensions])