diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user-blk-server.c
index 62672d1cb95a37a104b9d4b2e91b92ab6ccfc929..a3d95ca012eec9a8b0fb0d460b7f9b593de08fcc 100644
--- a/block/export/vhost-user-blk-server.c
+++ b/block/export/vhost-user-blk-server.c
@@ -11,7 +11,7 @@
  */
 #include "qemu/osdep.h"
 #include "block/block.h"
-#include "contrib/libvhost-user/libvhost-user.h"
+#include "subprojects/libvhost-user/libvhost-user.h" /* only for the type definitions */
 #include "standard-headers/linux/virtio_blk.h"
 #include "qemu/vhost-user-server.h"
 #include "vhost-user-blk-server.h"
diff --git a/contrib/libvhost-user/meson.build b/contrib/libvhost-user/meson.build
deleted file mode 100644
index a261e7665f79cb88cfaa5f6b127afaa1b49e719b..0000000000000000000000000000000000000000
--- a/contrib/libvhost-user/meson.build
+++ /dev/null
@@ -1,4 +0,0 @@
-libvhost_user = static_library('vhost-user',
-                               files('libvhost-user.c', 'libvhost-user-glib.c'),
-                               build_by_default: false)
-vhost_user = declare_dependency(link_with: libvhost_user)
diff --git a/contrib/vhost-user-blk/meson.build b/contrib/vhost-user-blk/meson.build
index 5db8cc3fe2b3de5a67ab5cc8a81cad046d8e84fd..601ea15ef54a46086674acffd1940cba0e08b667 100644
--- a/contrib/vhost-user-blk/meson.build
+++ b/contrib/vhost-user-blk/meson.build
@@ -1,6 +1,5 @@
 # FIXME: broken on 32-bit architectures
 executable('vhost-user-blk', files('vhost-user-blk.c'),
-           link_with: libvhost_user,
-           dependencies: qemuutil,
+           dependencies: [qemuutil, vhost_user],
            build_by_default: false,
            install: false)
diff --git a/contrib/vhost-user-blk/vhost-user-blk.c b/contrib/vhost-user-blk/vhost-user-blk.c
index dc981bf945342090233f4f9d8768938dbc6efe6c..6abd7835a85dfecde30b56309e831e99271cd3d0 100644
--- a/contrib/vhost-user-blk/vhost-user-blk.c
+++ b/contrib/vhost-user-blk/vhost-user-blk.c
@@ -17,8 +17,7 @@
 
 #include "qemu/osdep.h"
 #include "standard-headers/linux/virtio_blk.h"
-#include "contrib/libvhost-user/libvhost-user-glib.h"
-#include "contrib/libvhost-user/libvhost-user.h"
+#include "libvhost-user-glib.h"
 
 #if defined(__linux__)
 #include <linux/fs.h>
diff --git a/contrib/vhost-user-gpu/meson.build b/contrib/vhost-user-gpu/meson.build
index c487ca72c1ff325ca476b93c519621d6ba5b1fd9..2fc2320b52fe830f8c0f6d15fabad910fdae8d4b 100644
--- a/contrib/vhost-user-gpu/meson.build
+++ b/contrib/vhost-user-gpu/meson.build
@@ -2,8 +2,7 @@ if 'CONFIG_TOOLS' in config_host and 'CONFIG_VIRGL' in config_host \
     and 'CONFIG_GBM' in config_host and 'CONFIG_LINUX' in config_host \
     and pixman.found()
   executable('vhost-user-gpu', files('vhost-user-gpu.c', 'virgl.c', 'vugbm.c'),
-             link_with: libvhost_user,
-             dependencies: [qemuutil, pixman, gbm, virgl],
+             dependencies: [qemuutil, pixman, gbm, virgl, vhost_user],
              install: true,
              install_dir: get_option('libexecdir'))
 
diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h
index 3153c9a6de1409b8a0f0bc16b287865973f01226..bdf9a74b46d2c98423f496a2a6edccf6b47953f2 100644
--- a/contrib/vhost-user-gpu/vugpu.h
+++ b/contrib/vhost-user-gpu/vugpu.h
@@ -17,7 +17,7 @@
 
 #include "qemu/osdep.h"
 
-#include "contrib/libvhost-user/libvhost-user-glib.h"
+#include "libvhost-user-glib.h"
 #include "standard-headers/linux/virtio_gpu.h"
 
 #include "qemu/queue.h"
diff --git a/contrib/vhost-user-input/main.c b/contrib/vhost-user-input/main.c
index 6020c6f33a464d376b053ab69204f77663415334..3ea840cf44f9960a763f56c0d705a668b9d4dfab 100644
--- a/contrib/vhost-user-input/main.c
+++ b/contrib/vhost-user-input/main.c
@@ -12,8 +12,7 @@
 #include "qemu/iov.h"
 #include "qemu/bswap.h"
 #include "qemu/sockets.h"
-#include "contrib/libvhost-user/libvhost-user.h"
-#include "contrib/libvhost-user/libvhost-user-glib.h"
+#include "libvhost-user-glib.h"
 #include "standard-headers/linux/virtio_input.h"
 #include "qapi/error.h"
 
diff --git a/contrib/vhost-user-input/meson.build b/contrib/vhost-user-input/meson.build
index 1eeb1329d9e220c4caf87d38526650dac08a7a89..21a9ed4f15ec239b29118bc28e6ef130ec1b3995 100644
--- a/contrib/vhost-user-input/meson.build
+++ b/contrib/vhost-user-input/meson.build
@@ -1,5 +1,4 @@
 executable('vhost-user-input', files('main.c'),
-           link_with: libvhost_user,
-           dependencies: qemuutil,
+           dependencies: [qemuutil, vhost_user],
            build_by_default: targetos == 'linux',
            install: false)
diff --git a/contrib/vhost-user-scsi/meson.build b/contrib/vhost-user-scsi/meson.build
index 257cbffc8e5b1972de1bbb8bf28765d37cf7420e..044c50bf437e11e33d7aae7c6775f3400b9b8b31 100644
--- a/contrib/vhost-user-scsi/meson.build
+++ b/contrib/vhost-user-scsi/meson.build
@@ -1,7 +1,6 @@
 if 'CONFIG_LIBISCSI' in config_host
   executable('vhost-user-scsi', files('vhost-user-scsi.c'),
-             link_with: libvhost_user,
-             dependencies: [qemuutil, libiscsi],
+             dependencies: [qemuutil, libiscsi, vhost_user],
              build_by_default: targetos == 'linux',
              install: false)
 endif
diff --git a/contrib/vhost-user-scsi/vhost-user-scsi.c b/contrib/vhost-user-scsi/vhost-user-scsi.c
index 4639440a70b7487e6ae61c377be70de565608c65..4f6e3e2a24bc28b41e6236c1d90c01d0bb2184e8 100644
--- a/contrib/vhost-user-scsi/vhost-user-scsi.c
+++ b/contrib/vhost-user-scsi/vhost-user-scsi.c
@@ -15,7 +15,7 @@
 #define inline __attribute__((gnu_inline))  /* required for libiscsi v1.9.0 */
 #include <iscsi/scsi-lowlevel.h>
 #undef inline
-#include "contrib/libvhost-user/libvhost-user-glib.h"
+#include "libvhost-user-glib.h"
 #include "standard-headers/linux/virtio_scsi.h"
 
 
diff --git a/include/qemu/vhost-user-server.h b/include/qemu/vhost-user-server.h
index 0da4c2cc4ccc6545e459d4454277dfa963e9308d..121ea1dedf3ab6b509c048529c8c1308d403d202 100644
--- a/include/qemu/vhost-user-server.h
+++ b/include/qemu/vhost-user-server.h
@@ -11,7 +11,7 @@
 #ifndef VHOST_USER_SERVER_H
 #define VHOST_USER_SERVER_H
 
-#include "contrib/libvhost-user/libvhost-user.h"
+#include "subprojects/libvhost-user/libvhost-user.h" /* only for the type definitions */
 #include "io/channel-socket.h"
 #include "io/channel-file.h"
 #include "io/net-listener.h"
diff --git a/meson.build b/meson.build
index e3386196ba4106a973edb7f9d07ce9576c11981c..732b29a1f3780057a7fa46957e5dc8c5e7caef0d 100644
--- a/meson.build
+++ b/meson.build
@@ -1475,7 +1475,12 @@ trace_events_subdirs += [
   'util',
 ]
 
-subdir('contrib/libvhost-user')
+vhost_user = not_found
+if 'CONFIG_VHOST_USER' in config_host
+  libvhost_user = subproject('libvhost-user')
+  vhost_user = libvhost_user.get_variable('vhost_user_dep')
+endif
+
 subdir('qapi')
 subdir('qobject')
 subdir('stubs')
diff --git a/contrib/libvhost-user/libvhost-user-glib.c b/subprojects/libvhost-user/libvhost-user-glib.c
similarity index 100%
rename from contrib/libvhost-user/libvhost-user-glib.c
rename to subprojects/libvhost-user/libvhost-user-glib.c
diff --git a/contrib/libvhost-user/libvhost-user-glib.h b/subprojects/libvhost-user/libvhost-user-glib.h
similarity index 100%
rename from contrib/libvhost-user/libvhost-user-glib.h
rename to subprojects/libvhost-user/libvhost-user-glib.h
diff --git a/contrib/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c
similarity index 100%
rename from contrib/libvhost-user/libvhost-user.c
rename to subprojects/libvhost-user/libvhost-user.c
diff --git a/contrib/libvhost-user/libvhost-user.h b/subprojects/libvhost-user/libvhost-user.h
similarity index 100%
rename from contrib/libvhost-user/libvhost-user.h
rename to subprojects/libvhost-user/libvhost-user.h
diff --git a/subprojects/libvhost-user/meson.build b/subprojects/libvhost-user/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..f9ecc534cf6247b3648044874bb75c028effcb25
--- /dev/null
+++ b/subprojects/libvhost-user/meson.build
@@ -0,0 +1,20 @@
+project('libvhost-user', 'c',
+        license: 'GPL-2.0-or-later',
+        default_options: ['c_std=gnu99'])
+
+glib = dependency('glib-2.0')
+inc = include_directories('../../include', '../../linux-headers')
+
+vhost_user = static_library('vhost-user',
+                            files('libvhost-user.c'),
+                            include_directories: inc,
+                            c_args: '-D_GNU_SOURCE')
+
+vhost_user_glib = static_library('vhost-user-glib',
+                                 files('libvhost-user-glib.c'),
+                                 include_directories: inc,
+                                 link_with: vhost_user,
+                                 dependencies: glib)
+
+vhost_user_dep = declare_dependency(link_with: vhost_user_glib,
+                                    include_directories: include_directories('.'))
diff --git a/tests/meson.build b/tests/meson.build
index afeb6be689407feef77fb05c39fb9d5409652c15..1fa068f27b645b6854eab8d8b157e9a67d7f29f2 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -264,8 +264,7 @@ endforeach
 if have_tools and 'CONFIG_VHOST_USER' in config_host and 'CONFIG_LINUX' in config_host
   executable('vhost-user-bridge',
              sources: files('vhost-user-bridge.c'),
-             link_with: [libvhost_user],
-             dependencies: [qemuutil])
+             dependencies: [qemuutil, vhost_user])
 endif
 
 if have_system and 'CONFIG_POSIX' in config_host
diff --git a/tests/vhost-user-bridge.c b/tests/vhost-user-bridge.c
index bd43607a4d3bda78cfbfe263319334408047eeac..24815920b2ba20c87ce18c38430c281c789b5572 100644
--- a/tests/vhost-user-bridge.c
+++ b/tests/vhost-user-bridge.c
@@ -34,7 +34,7 @@
 #include "qemu/ctype.h"
 #include "qemu/iov.h"
 #include "standard-headers/linux/virtio_net.h"
-#include "contrib/libvhost-user/libvhost-user.h"
+#include "libvhost-user.h"
 
 #define VHOST_USER_BRIDGE_DEBUG 1
 
diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
index 83ba07c6cd8023727917cb0efa83ff283691a3b6..623812c432aae2ac9dad7df0b9d412cbe182467c 100644
--- a/tools/virtiofsd/fuse_virtio.c
+++ b/tools/virtiofsd/fuse_virtio.c
@@ -35,7 +35,7 @@
 #include <grp.h>
 #include <unistd.h>
 
-#include "contrib/libvhost-user/libvhost-user.h"
+#include "libvhost-user.h"
 
 struct fv_VuDev;
 struct fv_QueueInfo {
diff --git a/tools/virtiofsd/meson.build b/tools/virtiofsd/meson.build
index 17edecf55c0aee51b2b3327fd62389ea15df2644..c134ba633f07f12d5433fd7ce0c041b17b127735 100644
--- a/tools/virtiofsd/meson.build
+++ b/tools/virtiofsd/meson.build
@@ -8,8 +8,7 @@ executable('virtiofsd', files(
   'helper.c',
   'passthrough_ll.c',
   'passthrough_seccomp.c'),
-  link_with: libvhost_user,
-  dependencies: [seccomp, qemuutil, libcap_ng],
+  dependencies: [seccomp, qemuutil, libcap_ng, vhost_user],
   install: true,
   install_dir: get_option('libexecdir'))