diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml
index 50924a78f0e79da1c0bc264d0aa692721698dbe9..6dc42e4ea1bb78fa8f64c7da687cc8e82139e612 100644
--- a/doc/src/sgml/extend.sgml
+++ b/doc/src/sgml/extend.sgml
@@ -427,23 +427,38 @@
      </varlistentry>
 
      <varlistentry>
-      <term><varname>requires</varname> (<type>string</type>)</term>
+      <term><varname>encoding</varname> (<type>string</type>)</term>
       <listitem>
        <para>
-        A list of names of extensions that this extension depends on,
-        for example <literal>requires = 'foo, bar'</literal>.  Those
-        extensions must be installed before this one can be installed.
+        The character set encoding used by the script file(s).  This should
+        be specified if the script files contain any non-ASCII characters.
+        Otherwise the files will be assumed to be in the database encoding.
        </para>
       </listitem>
      </varlistentry>
 
      <varlistentry>
-      <term><varname>encoding</varname> (<type>string</type>)</term>
+      <term><varname>module_pathname</varname> (<type>string</type>)</term>
       <listitem>
        <para>
-        The character set encoding used by the script file(s).  This should
-        be specified if the script files contain any non-ASCII characters.
-        Otherwise the files will be assumed to be in the database encoding.
+        The value of this parameter will be substituted for each occurrence
+        of <literal>MODULE_PATHNAME</> in the script file(s).  If it is not
+        set, no substitution is made.  Typically, this is set to
+        <literal>$libdir/<replaceable>shared_library_name</></literal> and
+        then <literal>MODULE_PATHNAME</> is used in <command>CREATE
+        FUNCTION</> commands for C-language functions, so that the script
+        files do not need to hard-wire the name of the shared library.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><varname>requires</varname> (<type>string</type>)</term>
+      <listitem>
+       <para>
+        A list of names of extensions that this extension depends on,
+        for example <literal>requires = 'foo, bar'</literal>.  Those
+        extensions must be installed before this one can be installed.
        </para>
       </listitem>
      </varlistentry>
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 0661303fea3bf330fc30fc5d7c8655dcb8a73b46..92edcbc3cf2e6dd99443f24e101a879c8dbc9194 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -65,6 +65,7 @@ typedef struct ExtensionControlFile
 	char	   *name;			/* name of the extension */
 	char	   *directory;		/* directory for script files */
 	char	   *default_version; /* default install target version, if any */
+	char	   *module_pathname; /* string to substitute for MODULE_PATHNAME */
 	char	   *comment;		/* comment, if any */
 	char	   *schema;			/* target schema (allowed if !relocatable) */
 	bool		relocatable;	/* is ALTER EXTENSION SET SCHEMA supported? */
@@ -493,6 +494,10 @@ parse_extension_control_file(ExtensionControlFile *control,
 
 			control->default_version = pstrdup(item->value);
 		}
+		else if (strcmp(item->name, "module_pathname") == 0)
+		{
+			control->module_pathname = pstrdup(item->value);
+		}
 		else if (strcmp(item->name, "comment") == 0)
 		{
 			control->comment = pstrdup(item->value);
@@ -836,7 +841,20 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
 										CStringGetTextDatum(sql),
 										CStringGetTextDatum("@extschema@"),
 										CStringGetTextDatum(qSchemaName))));
+		}
 
+		/*
+		 * If module_pathname was set in the control file, substitute its
+		 * value for occurrences of MODULE_PATHNAME.
+		 */
+		if (control->module_pathname)
+		{
+			sql = text_to_cstring(
+				DatumGetTextPP(
+					DirectFunctionCall3(replace_text,
+										CStringGetTextDatum(sql),
+										CStringGetTextDatum("MODULE_PATHNAME"),
+										CStringGetTextDatum(control->module_pathname))));
 		}
 
 		execute_sql_string(sql, filename);