diff --git a/.gitignore b/.gitignore
index 355164c126511e7d9f9896171414647f098dd30e..0fb8073a26afaccc89ce7943d484350dc6be929a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-*/
+/*/
+!/cmake/
+*.swp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8c5f143b074ea68c4a1a86f60060115a10056e8d..45cb35ceb9c8ece9a52405d5029d175feca43ac8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,13 +32,8 @@ ExternalProject_Add(TUnfold
     URL                 https://www.desy.de/~sschmitt/TUnfold/TUnfold_V17.9.tgz
     URL_HASH            SHA256=d7f66f6a0e007eb946180643b8879bb2b8918441106bc0305b82a97391a391dc
     SOURCE_DIR          "${CMAKE_SOURCE_DIR}/TUnfold"
-    CONFIGURE_COMMAND   ""
-    BUILD_COMMAND       make lib TUNFOLDVERSION='V17'
-    BUILD_IN_SOURCE     TRUE
-    INSTALL_COMMAND     install -DT libunfold.so <INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/libtunfold.so
-            COMMAND     install TUnfoldV17Dict_rdict.pcm <INSTALL_DIR>/${CMAKE_INSTALL_LIBDIR}/
-            COMMAND     install -d <INSTALL_DIR>/${CMAKE_INSTALL_INCLUDEDIR}/TUnfold
-            COMMAND     install ${TUNFOLD_HEADERS} <INSTALL_DIR>/${CMAKE_INSTALL_INCLUDEDIR}/TUnfold/
+    PATCH_COMMAND       "${CMAKE_COMMAND}" -E copy_directory_if_different ${CMAKE_SOURCE_DIR}/cmake/TUnfold <SOURCE_DIR>
+    CMAKE_ARGS          -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
     INSTALL_DIR         "${CMAKE_INSTALL_PREFIX}"
 )
 configure_file(tunfold.xml.in tunfold.xml)
diff --git a/cmake/TUnfold/CMakeLists.txt b/cmake/TUnfold/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8da8289a86e82b15a7b39ded5f24bbe3631c7e47
--- /dev/null
+++ b/cmake/TUnfold/CMakeLists.txt
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPLv3-or-later
+#
+# SPDX-FileCopyrightText: Louis Moureaux <louis.moureaux@cern.ch>
+
+cmake_minimum_required(VERSION 3.17..3.26 FATAL_ERROR)
+project(TUnfold VERSION 17.9 LANGUAGES CXX)
+
+find_package(ROOT 6.24 REQUIRED)
+
+set(classes
+    TUnfoldBinning
+    TUnfoldBinningXML
+    TUnfoldDensity
+    TUnfoldIterativeEM
+    TUnfoldSys
+    TUnfold)
+
+# Library
+set(sources ${classes})
+list(TRANSFORM sources APPEND V${TUnfold_VERSION_MAJOR}.cxx)
+
+set(headers ${classes})
+list(TRANSFORM headers APPEND .h)
+
+add_library(TUnfold SHARED ${sources})
+target_sources(TUnfold PUBLIC FILE_SET HEADERS FILES ${headers})
+target_link_libraries(TUnfold PUBLIC ROOT::Hist ROOT::XMLParser)
+
+# Install
+include(GNUInstallDirs)
+set(include_dir "${CMAKE_INSTALL_INCLUDEDIR}/TUnfold")
+install(TARGETS TUnfold
+        EXPORT TUnfoldTargets
+        COMPONENT TUnfold
+        FILE_SET HEADERS DESTINATION "${include_dir}"
+        RUNTIME  DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+        INCLUDES DESTINATION "${include_dir}")
+
+# Dictionary
+configure_file(LinkDef.h.in LinkDef.h)
+# https://github.com/root-project/root/issues/8308#issuecomment-1143791946
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+root_generate_dictionary(TUnfoldV${TUnfold_VERSION_MAJOR}Dict
+                         ${headers}
+                         MODULE TUnfold
+                         LINKDEF "${CMAKE_CURRENT_BINARY_DIR}/LinkDef.h")
+
+# Export
+include(CMakePackageConfigHelpers)
+set(CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/TUnfold")
+configure_package_config_file(
+    "${CMAKE_CURRENT_SOURCE_DIR}/TUnfoldConfig.cmake.in"
+    "${CMAKE_CURRENT_BINARY_DIR}/TUnfoldConfig.cmake"
+    INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+)
+write_basic_package_version_file(
+    TUnfoldConfigVersion.cmake
+    COMPATIBILITY SameMajorVersion
+)
+install(FILES
+        "${CMAKE_CURRENT_BINARY_DIR}/TUnfoldConfig.cmake"
+        "${CMAKE_CURRENT_BINARY_DIR}/TUnfoldConfigVersion.cmake"
+        DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+        COMPONENT Devel)
+install(EXPORT TUnfoldTargets
+        NAMESPACE TUnfold::
+        DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+        FILE TUnfoldTargets.cmake)
diff --git a/cmake/TUnfold/LinkDef.h.in b/cmake/TUnfold/LinkDef.h.in
new file mode 100644
index 0000000000000000000000000000000000000000..a5bf752dd542787d1c595ca778db7bb6c3b00f65
--- /dev/null
+++ b/cmake/TUnfold/LinkDef.h.in
@@ -0,0 +1,8 @@
+#ifdef __CLING__
+#pragma link C++ class TUnfoldV@TUnfold_VERSION_MAJOR@+;
+#pragma link C++ class TUnfoldIterativeEMV@TUnfold_VERSION_MAJOR@+;
+#pragma link C++ class TUnfoldSysV@TUnfold_VERSION_MAJOR@+;
+#pragma link C++ class TUnfoldDensityV@TUnfold_VERSION_MAJOR@+;
+#pragma link C++ class TUnfoldBinningV@TUnfold_VERSION_MAJOR@+;
+#pragma link C++ class TUnfoldBinningXMLV@TUnfold_VERSION_MAJOR@+;
+#endif
diff --git a/cmake/TUnfold/TUnfoldConfig.cmake.in b/cmake/TUnfold/TUnfoldConfig.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..fe637809a5022308419bd94434365c48dbbbcb10
--- /dev/null
+++ b/cmake/TUnfold/TUnfoldConfig.cmake.in
@@ -0,0 +1,3 @@
+include(CMakeFindDependencyMacro)
+find_dependency(ROOT @ROOT_VERSION@)
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")