diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5a54d02df357ccb4f9258a957a7002bc0aa82d6..0562da6d53aa86eeb12a212ea2d3c8d0600bc519 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -178,6 +178,19 @@ if(BUILD_WITH_HYDRA)
 	set(BUILD_DRIVER_HYDRA TRUE)
 endif()
 
+
+# Vulkan flags for the shared Vulkan code.
+if(BUILD_WITH_XCB)
+	add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
+endif()
+if(BUILD_WITH_XCB AND BUILD_WITH_XLIB)
+	add_definitions(-DVK_USE_PLATFORM_XLIB_XRANDR_EXT)
+endif()
+if(BUILD_WITH_WAYLAND)
+	add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR)
+endif()
+
+
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wall -Wextra -Wno-unused-parameter")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter")
 
diff --git a/meson.build b/meson.build
index a4748cdbbd81beff44378f04c6298449582a0cf5..99914f730f239b3e009fd7bd0e5f6c32b45ec0de 100644
--- a/meson.build
+++ b/meson.build
@@ -220,6 +220,18 @@ if sdl2.found()
 endif
 
 
+# Vulkan flags for the shared Vulkan code.
+if build_wayland
+	add_project_arguments('-DVK_USE_PLATFORM_WAYLAND_KHR', language: ['c', 'cpp'])
+endif
+if build_xcb
+	add_project_arguments('-DVK_USE_PLATFORM_XCB_KHR', language: ['c', 'cpp'])
+endif
+if build_xcb_xrandr_direct
+	add_project_arguments('-DVK_USE_PLATFORM_XLIB_XRANDR_EXT', language: ['c', 'cpp'])
+endif
+
+
 #
 # Go down sub directories
 #
diff --git a/src/xrt/auxiliary/CMakeLists.txt b/src/xrt/auxiliary/CMakeLists.txt
index f955103c8cf2c2d14f53c9b694baa42ba13aecf6..41de53ed61bc5895c54ea5e461494472e91cd367 100644
--- a/src/xrt/auxiliary/CMakeLists.txt
+++ b/src/xrt/auxiliary/CMakeLists.txt
@@ -86,6 +86,12 @@ set(UTIL_SOURCE_FILES
 	util/u_var.h
 	)
 
+set(VK_SOURCE_FILES
+	vk/vk_helpers.c
+	vk/vk_helpers.h
+	vk/vk_documentation.h
+	)
+
 # Common includes
 include_directories(
 	${CMAKE_CURRENT_SOURCE_DIR}/../include
@@ -136,3 +142,11 @@ if(BUILD_TRACKING)
 		${OpenCV_INCLUDE_DIRS}
 		)
 endif()
+
+# Vulkan library.
+# Use OBJECT to not create a archive, since it just gets in the way.
+add_library(aux_vk OBJECT ${VK_SOURCE_FILES})
+target_include_directories(aux_vk SYSTEM
+		PRIVATE
+		${CMAKE_CURRENT_SOURCE_DIR}/../../external
+		)
diff --git a/src/xrt/auxiliary/meson.build b/src/xrt/auxiliary/meson.build
index ccbcdde5a713a955b8286718cbcf836f8a65f3d1..0640cda3dbfa83f3e0f5e380faddf25db2bdeae6 100644
--- a/src/xrt/auxiliary/meson.build
+++ b/src/xrt/auxiliary/meson.build
@@ -147,6 +147,25 @@ aux_tracking = declare_dependency(
 	link_with: lib_aux_tracking,
 )
 
+lib_aux_vk = static_library(
+	'aux_vk',
+	files(
+		'vk/vk_helpers.h',
+		'vk/vk_helpers.c',
+		'vk/vk_documentation.h',
+	),
+	include_directories: [
+		xrt_include,
+		external_include,
+	],
+)
+
+aux_vk = declare_dependency(
+	include_directories: aux_include,
+	link_with: lib_aux_vk,
+)
+
+
 all_aux = [aux_util, aux_os, aux_math, aux_tracking]
 
 aux = declare_dependency(dependencies: all_aux)
diff --git a/src/xrt/auxiliary/vk/vk_documentation.h b/src/xrt/auxiliary/vk/vk_documentation.h
new file mode 100644
index 0000000000000000000000000000000000000000..9280eda14453b52dcc9edfafaf7de137c6cf2443
--- /dev/null
+++ b/src/xrt/auxiliary/vk/vk_documentation.h
@@ -0,0 +1,25 @@
+// Copyright 2020, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief  Header with just documentation.
+ * @author Jakob Bornecrantz <jakob@collabora.com>
+ * @ingroup aux_vk
+ */
+
+#pragma once
+
+
+/*!
+ * @defgroup aux_vk Vulkan helper code
+ * @ingroup aux
+ *
+ * @brief Vulkan helper structs and functions.
+ */
+
+/*!
+ * @dir auxiliary/vk
+ * @ingroup aux
+ *
+ * @brief Vulkan helper structs and functions.
+ */
diff --git a/src/xrt/compositor/common/comp_vk.c b/src/xrt/auxiliary/vk/vk_helpers.c
similarity index 99%
rename from src/xrt/compositor/common/comp_vk.c
rename to src/xrt/auxiliary/vk/vk_helpers.c
index 43c35e67fa019b3f9f10dbb5a2713e867d19a81a..b684237874bf2583b2417c91d5b8e20968ba9816 100644
--- a/src/xrt/compositor/common/comp_vk.c
+++ b/src/xrt/auxiliary/vk/vk_helpers.c
@@ -1,11 +1,11 @@
-// Copyright 2019, Collabora, Ltd.
+// Copyright 2019-2020, Collabora, Ltd.
 // SPDX-License-Identifier: BSL-1.0
 /*!
  * @file
  * @brief  Common Vulkan code.
  * @author Jakob Bornecrantz <jakob@collabora.com>
  * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 
 #include <stdio.h>
@@ -15,7 +15,7 @@
 #include "util/u_misc.h"
 #include "util/u_debug.h"
 
-#include "common/comp_vk.h"
+#include "vk/vk_helpers.h"
 
 
 /*
diff --git a/src/xrt/compositor/common/comp_vk.h b/src/xrt/auxiliary/vk/vk_helpers.h
similarity index 96%
rename from src/xrt/compositor/common/comp_vk.h
rename to src/xrt/auxiliary/vk/vk_helpers.h
index cf8ea4053d92c3db6dd33b528c8baf5add498da9..4956fccde71a3336ffc6582319571813fd42aeab 100644
--- a/src/xrt/compositor/common/comp_vk.h
+++ b/src/xrt/auxiliary/vk/vk_helpers.h
@@ -1,11 +1,11 @@
-// Copyright 2019, Collabora, Ltd.
+// Copyright 2019-2020, Collabora, Ltd.
 // SPDX-License-Identifier: BSL-1.0
 /*!
  * @file
  * @brief  Common Vulkan code header.
  * @author Jakob Bornecrantz <jakob@collabora.com>
  * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 
 #pragma once
@@ -29,7 +29,7 @@ extern "C" {
  * comp_client. Note that they both have different instances of the object and
  * as such VkInstance and so on.
  *
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 struct vk_bundle
 {
@@ -224,37 +224,37 @@ vk_color_space_string(VkColorSpaceKHR code);
 	} while (false)
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 void
 vk_init_validation_callback(struct vk_bundle *vk);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 void
 vk_destroy_validation_callback(struct vk_bundle *vk);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_get_loader_functions(struct vk_bundle *vk, PFN_vkGetInstanceProcAddr g);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_get_instance_functions(struct vk_bundle *vk);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_init_cmd_pool(struct vk_bundle *vk);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_create_device(struct vk_bundle *vk, int forced_index);
@@ -263,7 +263,7 @@ vk_create_device(struct vk_bundle *vk, int forced_index);
  * Initialize a bundle with objects given to us by client code,
  * used by @ref client_vk_compositor in @ref comp_client.
  *
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_init_from_given(struct vk_bundle *vk,
@@ -275,7 +275,7 @@ vk_init_from_given(struct vk_bundle *vk,
                    uint32_t queue_index);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 bool
 vk_get_memory_type(struct vk_bundle *vk,
@@ -313,7 +313,7 @@ vk_get_memory_type(struct vk_bundle *vk,
  * If this fails, you may want to destroy your VkImage as well, since this
  * routine is usually used in combination with vkCreateImage.
  *
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_alloc_and_bind_image_memory(struct vk_bundle *vk,
@@ -324,7 +324,7 @@ vk_alloc_and_bind_image_memory(struct vk_bundle *vk,
                                VkDeviceSize *out_size);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_create_image_from_fd(struct vk_bundle *vk,
@@ -339,7 +339,7 @@ vk_create_image_from_fd(struct vk_bundle *vk,
                         VkDeviceMemory *out_mem);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_create_image_simple(struct vk_bundle *vk,
@@ -350,13 +350,13 @@ vk_create_image_simple(struct vk_bundle *vk,
                        VkImage *out_image);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_create_sampler(struct vk_bundle *vk, VkSampler *out_sampler);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_create_view(struct vk_bundle *vk,
@@ -366,13 +366,13 @@ vk_create_view(struct vk_bundle *vk,
                VkImageView *out_view);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_init_cmd_buffer(struct vk_bundle *vk, VkCommandBuffer *out_cmd_buffer);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_set_image_layout(struct vk_bundle *vk,
@@ -385,7 +385,7 @@ vk_set_image_layout(struct vk_bundle *vk,
                     VkImageSubresourceRange subresource_range);
 
 /*!
- * @ingroup comp_common
+ * @ingroup aux_vk
  */
 VkResult
 vk_submit_cmd_buffer(struct vk_bundle *vk, VkCommandBuffer cmd_buffer);
diff --git a/src/xrt/compositor/CMakeLists.txt b/src/xrt/compositor/CMakeLists.txt
index 8527ff95eb33d9d6ece924ef2aa98a011d4f5957..1522e0bee5d419a4b242e7c6f806b62ba1a0b084 100644
--- a/src/xrt/compositor/CMakeLists.txt
+++ b/src/xrt/compositor/CMakeLists.txt
@@ -13,8 +13,6 @@ spirv_shaders(SHADER_HEADERS
 set(SOURCE_FILES
 	client/comp_vk_client.c
 	client/comp_vk_client.h
-	common/comp_vk.c
-	common/comp_vk.h
 	common/comp_vk_swapchain.h
 	common/comp_vk_swapchain.c
 	main/comp_client_interface.h
@@ -33,11 +31,9 @@ set(SOURCE_FILES
 	)
 
 if(BUILD_WITH_XCB)
-	add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
 	list(APPEND SOURCE_FILES main/comp_window_xcb.cpp)
 endif()
 if(BUILD_WITH_XCB AND BUILD_WITH_XLIB)
-	add_definitions(-DVK_USE_PLATFORM_XLIB_XRANDR_EXT)
 	list(APPEND SOURCE_FILES main/comp_window_direct_mode.cpp)
 endif()
 if(BUILD_WITH_OPENGL)
@@ -84,8 +80,6 @@ if(BUILD_WITH_WAYLAND)
 
 	set(WL_PROTOS_SRC ${WL_PROTOS_C} ${WL_PROTOS_H})
 	list(APPEND SOURCE_FILES main/comp_window_wayland.c)
-
-	add_definitions(-DVK_USE_PLATFORM_WAYLAND_KHR)
 endif()
 
 if (${VULKAN_ENABLE_VALIDATION})
diff --git a/src/xrt/compositor/client/comp_vk_client.h b/src/xrt/compositor/client/comp_vk_client.h
index ff09d7b13c7760d06446fc736410f0b8e3d84cf1..7c2f6e653f85d9c8377780a33ae7b0ca60f85995 100644
--- a/src/xrt/compositor/client/comp_vk_client.h
+++ b/src/xrt/compositor/client/comp_vk_client.h
@@ -10,7 +10,7 @@
 
 #pragma once
 
-#include "common/comp_vk.h"
+#include "vk/vk_helpers.h"
 #include "xrt/xrt_gfx_vk.h"
 
 #ifdef __cplusplus
diff --git a/src/xrt/compositor/common/comp_vk_swapchain.h b/src/xrt/compositor/common/comp_vk_swapchain.h
index 5e9d86b9f906078e702f66e046c34e8ffae3cc18..f1d174d3c1df221547c6badde35514f88c22db2f 100644
--- a/src/xrt/compositor/common/comp_vk_swapchain.h
+++ b/src/xrt/compositor/common/comp_vk_swapchain.h
@@ -10,7 +10,7 @@
 
 #pragma once
 
-#include "common/comp_vk.h"
+#include "vk/vk_helpers.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/src/xrt/compositor/meson.build b/src/xrt/compositor/meson.build
index b1926efcab5259953d22665342f6c39b22e867f4..2792aa300d54bd4d0b808ddde0d6bcc7ef0b02c0 100644
--- a/src/xrt/compositor/meson.build
+++ b/src/xrt/compositor/meson.build
@@ -9,8 +9,6 @@ compositor_deps = [aux, shaders, vulkan]
 compositor_srcs = [
 	'client/comp_vk_client.c',
 	'client/comp_vk_client.h',
-	'common/comp_vk.c',
-	'common/comp_vk.h',
 	'common/comp_vk_swapchain.h',
 	'common/comp_vk_swapchain.c',
 	'main/comp_client_interface.h',
@@ -31,13 +29,11 @@ compositor_srcs = [
 compile_args = []
 
 if build_xcb
-	compile_args += ['-DVK_USE_PLATFORM_XCB_KHR']
 	compositor_srcs += ['main/comp_window_xcb.cpp']
 	compositor_deps += [xcb]
 endif
 
 if build_xcb_xrandr_direct
-	compile_args += ['-DVK_USE_PLATFORM_XLIB_XRANDR_EXT']
 	compositor_srcs += ['main/comp_window_direct_mode.cpp']
 	compositor_deps += [xcb_randr]
 endif
@@ -103,7 +99,6 @@ if build_wayland
 		sources: wl_protos_headers,
 	)
 
-	compile_args += ['-DVK_USE_PLATFORM_WAYLAND_KHR']
 	compositor_srcs += ['main/comp_window_wayland.c']
 	compositor_deps += [wayland, wl_protos]
 endif
diff --git a/src/xrt/targets/openxr/CMakeLists.txt b/src/xrt/targets/openxr/CMakeLists.txt
index fb6b46e525c851e8a077e42c86b59080a1fc4802..4c4808165e4784d7dd40f08ac040bc35f3082a52 100644
--- a/src/xrt/targets/openxr/CMakeLists.txt
+++ b/src/xrt/targets/openxr/CMakeLists.txt
@@ -34,6 +34,7 @@ add_library(${RUNTIME_TARGET} SHARED
 	${MANIFEST_DEV_PATH}
 	${MANIFEST_PATH}
 	${SOURCE_FILES}
+	$<TARGET_OBJECTS:aux_vk>
 	$<TARGET_OBJECTS:aux_os>
 	$<TARGET_OBJECTS:aux_ogl>
 	$<TARGET_OBJECTS:aux_util>
diff --git a/src/xrt/targets/openxr/meson.build b/src/xrt/targets/openxr/meson.build
index c46710cfc4682412d7cedc840b46c98f5bc548fd..54b1fb8b76f8ac7511adff063c2dddd79be1fac4 100644
--- a/src/xrt/targets/openxr/meson.build
+++ b/src/xrt/targets/openxr/meson.build
@@ -69,6 +69,7 @@ openxr = library(
 		hack_src,
 	),
 	link_whole: [
+		lib_aux_vk,
 		lib_aux_os,
 		lib_aux_ogl,
 		lib_aux_util,