diff --git a/SConstruct b/SConstruct
index 422efe6476878779a0d8a1bbb759403906c60f28..c46c0904c9cfce5db2cce0ad4814c4ec843dc834 100644
--- a/SConstruct
+++ b/SConstruct
@@ -28,6 +28,8 @@ if 'DESTDIR' in env:
 
 env['libpath'] = calcInstallPath("$prefix", "lib")
 env['incpath'] = calcInstallPath("$prefix", "include", "hammer")
+env['parsersincpath'] = calcInstallPath("$prefix", "include", "hammer", "parsers")
+env['backendsincpath'] = calcInstallPath("$prefix", "include", "hammer", "backends")
 env['pkgconfigpath'] = calcInstallPath("$prefix", "lib", "pkgconfig")
 env.ScanReplace('libhammer.pc.in')
 
@@ -35,6 +37,7 @@ env.MergeFlags("-std=gnu99 -Wall -Wextra -Werror -Wno-unused-parameter -Wno-attr
 
 if not env['PLATFORM'] == 'darwin':
     env.MergeFlags("-lrt")
+    env.Append(SHLINKFLAGS = ['-install_name ' + '$TARGET'])
 
 AddOption("--variant",
           dest="variant",
@@ -90,4 +93,6 @@ env.Command('test', 'build/$VARIANT/src/test_suite', 'env LD_LIBRARY_PATH=build/
 
 env.Alias("install", "$libpath")
 env.Alias("install", "$incpath")
+env.Alias("install", "$parsersincpath")
+env.Alias("install", "$backendsincpath")
 env.Alias("install", "$pkgconfigpath")
diff --git a/src/SConscript b/src/SConscript
index a06244b9d6638e2d715e77535a0ba555a12a8cf3..1d9ca7621c1983d32cae4d86490d5d95c6582834 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -6,7 +6,17 @@ bindings = []
 dist_headers = [
     "hammer.h",
     "allocator.h",
-    "glue.h"
+    "glue.h",
+    "internal.h"
+]
+
+parsers_headers = [
+    "parsers/parser_internal.h"
+]
+
+backends_headers = [
+    "backends/regex.h",
+    "backends/contextfree.h"
 ]
 
 parsers = ['parsers/%s.c'%s for s in
@@ -64,6 +74,8 @@ libhammer_static = env.StaticLibrary('hammer', parsers + backends + misc_hammer_
 
 env.Install("$libpath", [libhammer_static, libhammer_shared])
 env.Install("$incpath", dist_headers)
+env.Install("$parsersincpath", parsers_headers)
+env.Install("$backendsincpath", backends_headers)
 env.Install("$pkgconfigpath", "../../../libhammer.pc")
 
 testenv = env.Clone()
diff --git a/src/backends/contextfree.h b/src/backends/contextfree.h
index b387e55df21387d4be137d7ff159889de50985ba..ab04ab523064fba731d2cf292bcc1a7bd28a9faf 100644
--- a/src/backends/contextfree.h
+++ b/src/backends/contextfree.h
@@ -1,3 +1,8 @@
+/*
+ * NOTE: This is an internal header and installed for use by extensions. The
+ * API is not guaranteed stable.
+*/
+
 // This is an internal header; it provides macros to make desugaring cleaner.
 #include <assert.h>
 #include "../internal.h"
diff --git a/src/backends/regex.h b/src/backends/regex.h
index a84904d0b6bcd4ea18b8b0281b625c4c303e9a8d..4ea85a884b3fdec764f9ad94fc4c48880a0a6ea2 100644
--- a/src/backends/regex.h
+++ b/src/backends/regex.h
@@ -1,3 +1,8 @@
+/*
+ * NOTE: This is an internal header and installed for use by extensions. The
+ * API is not guaranteed stable.
+*/
+
 // Internal defs
 #ifndef HAMMER_BACKEND_REGEX__H
 #define HAMMER_BACKEND_REGEX__H
diff --git a/src/internal.h b/src/internal.h
index c402da511fe75da9a4365266207634fbdc9e8798..89cb38054333fef477e08fbce804ba207b492a23 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -15,6 +15,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
+/*
+ * NOTE: This is an internal header and installed for use by extensions. The
+ * API is not guaranteed stable.
+*/
+
 #ifndef HAMMER_INTERNAL__H
 #define HAMMER_INTERNAL__H
 #include <stdint.h>
diff --git a/src/parsers/parser_internal.h b/src/parsers/parser_internal.h
index aeb202bf410a53b262e87cc3eadde603b9e11e8a..ec97dd1b0696fcb69f4a17bfc7d4078138f4d355 100644
--- a/src/parsers/parser_internal.h
+++ b/src/parsers/parser_internal.h
@@ -1,3 +1,8 @@
+/*
+ * NOTE: This is an internal header and installed for use by extensions. The
+ * API is not guaranteed stable.
+*/
+
 #ifndef HAMMER_PARSE_INTERNAL__H
 #define HAMMER_PARSE_INTERNAL__H
 #include "../hammer.h"