diff --git a/buildlib/check-build b/buildlib/check-build
index 766db7ae46259f..86cb76fcb823aa 100755
--- a/buildlib/check-build
+++ b/buildlib/check-build
@@ -213,17 +213,23 @@ def get_headers(incdir):
                 includes.add(os.path.join(root,I));
     return includes;
 
-def compile_test_headers(tmpd,incdir,includes):
+def compile_test_headers(tmpd,incdir,includes,with_cxx=False):
     with open(os.path.join(tmpd,"build.ninja"),"wt") as F:
         print >> F,"rule comp";
         print >> F," command = %s -Werror -c -I %s $in -o $out"%(args.CC,incdir);
         print >> F," description=Header check for $in";
+        print >> F,"rule comp_cxx";
+        print >> F," command = %s -Werror -c -I %s $in -o $out"%(args.CXX,incdir);
+        print >> F," description=Header C++ check for $in";
         count = 0;
         for I in sorted(includes):
             if is_obsolete(I) or is_fixup(I):
                 continue;
             print >> F,"build %s : comp %s"%("out%d.o"%(count),I);
             print >> F,"default %s"%("out%d.o"%(count));
+            print >> F,"build %s : comp_cxx %s"%("outxx%d.o"%(count),I);
+            if with_cxx:
+                print >> F,"default %s"%("outxx%d.o"%(count));
             count = count + 1;
     subprocess.check_call(["ninja"],cwd=tmpd);
 
@@ -246,6 +252,15 @@ allowed_uapi_headers = {
     "rdma/ib_user_verbs.h",
 }
 
+non_cxx_headers = {
+    "infiniband/arch.h",
+    "infiniband/ib.h",
+    "infiniband/opcode.h",
+    "infiniband/sa-kern-abi.h",
+    "infiniband/sa.h",
+    "rdma/rdma_cma_abi.h",
+}
+
 def test_installed_headers(args):
     """This test also checks that the public headers can be compiled on their own,
     but goes further and confirms that the public headers do not depend on any
@@ -280,7 +295,14 @@ def test_installed_headers(args):
             with open(I,"w") as F:
                 print >> F,'#error "Private internal header"';
 
-        compile_test_headers(tmpd,incdir,includes);
+        # Roughly check that the headers have the extern "C" for C++
+        # compilation.
+        for I in sorted(rincludes - non_cxx_headers):
+            with open(os.path.join(incdir,I)) as F:
+                if 'extern "C" {' not in F.read():
+                    raise ValueError("No extern C in %r"%(I));
+
+        compile_test_headers(tmpd,incdir,includes,with_cxx=True);
 
 # -------------------------------------------------------------------------
 
@@ -291,6 +313,8 @@ parser.add_argument("--src",default=None,dest="SRC",
                     help="Top of the source tree");
 parser.add_argument("--cc",default="cc",dest="CC",
                     help="C compiler to use");
+parser.add_argument("--cxx",default="c++",dest="CXX",
+                    help="C++ compiler to use");
 args = parser.parse_args();
 
 if args.SRC is None:
diff --git a/ibacm/include/infiniband/acm.h b/ibacm/include/infiniband/acm.h
index b4d677cb75ca64..0f8469997ffc23 100644
--- a/ibacm/include/infiniband/acm.h
+++ b/ibacm/include/infiniband/acm.h
@@ -33,6 +33,10 @@
 #include <infiniband/verbs.h>
 #include <infiniband/sa.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define ACM_VERSION             1
 
 #define ACM_OP_MASK             0x0F
@@ -153,4 +157,8 @@ struct acm_msg {
 	};
 };
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* ACM_H */
diff --git a/ibacm/include/infiniband/acm_prov.h b/ibacm/include/infiniband/acm_prov.h
index 7dd07c75314b7c..691a00eac80b91 100644
--- a/ibacm/include/infiniband/acm_prov.h
+++ b/ibacm/include/infiniband/acm_prov.h
@@ -34,6 +34,10 @@
 #include <infiniband/umad.h>
 #include <infiniband/umad_sa.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define ACM_PROV_VERSION          1
 
 struct acm_device {
@@ -117,4 +121,8 @@ extern int acm_send_sa_mad(struct acm_sa_mad *mad);
 extern const char *acm_get_opts_file(void);
 extern void acm_increment_counter(int type);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* ACM_PROV_H */
diff --git a/providers/mlx4/mlx4dv.h b/providers/mlx4/mlx4dv.h
index 5312a866b6e281..2c42803dc3e23b 100644
--- a/providers/mlx4/mlx4dv.h
+++ b/providers/mlx4/mlx4dv.h
@@ -37,6 +37,10 @@
 #include <endian.h>
 #include <infiniband/verbs.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Always inline the functions */
 #ifdef __GNUC__
 #define MLX4DV_ALWAYS_INLINE inline __attribute__((always_inline))
@@ -529,4 +533,9 @@ enum mlx4dv_set_ctx_attr_type {
 int mlx4dv_set_context_attr(struct ibv_context *context,
 			    enum mlx4dv_set_ctx_attr_type attr_type,
 			    void *attr);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _MLX4DV_H_ */
diff --git a/providers/mlx5/mlx5dv.h b/providers/mlx5/mlx5dv.h
index de149ab4b8dee0..6a7e1d1f67ac5e 100644
--- a/providers/mlx5/mlx5dv.h
+++ b/providers/mlx5/mlx5dv.h
@@ -46,6 +46,10 @@
 #include <infiniband/verbs.h>
 #include <infiniband/tm_types.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Always inline the functions */
 #ifdef __GNUC__
 #define MLX5DV_ALWAYS_INLINE inline __attribute__((always_inline))
@@ -864,4 +868,8 @@ static inline uint64_t mlx5dv_ts_to_ns(struct mlx5dv_clock_info *clock_info,
 	return nsec;
 }
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _MLX5DV_H_ */
