diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3f7eeb4b..86559f81 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -110,6 +110,7 @@ option(ENABLE_STUB_ONLY "Restrict resolution modes to STUB." ON)
 option(ENABLE_TCP_FAST_OPEN "Enable use of TCP Fast Open." ON)
 option(ENABLE_UNBOUND_EVENT_API "Enable usage of libunbound's event API." ON)
 
+option(BUILD_DOXYGEN "Build source documentation." OFF)
 option(BUILD_EXAMPLES "Compile the example programs." OFF)
 option(BUILD_GETDNS_QUERY "Compile and install the getdns_query tool." ON)
 option(BUILD_GETDNS_SERVER_MON "Compile and install the getdns_server_mon tool." ON)
@@ -1054,3 +1055,15 @@ To compile and run all examples from the spec, make sure \
 libevent is available and usable during configuration.")
   endif ()
 endif ()
+
+if (BUILD_DOXYGEN)
+  find_package(Doxygen REQUIRED)
+
+  set(srcdir ${CMAKE_CURRENT_SOURCE_DIR}/src)
+  configure_file(src/Doxyfile.in Doxyfile @ONLY)
+  add_custom_command(OUTPUT doc/html/index.html
+    COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
+    MAIN_DEPENDENCY Doxyfile
+    COMMENT "Generating Doxygen docs.")
+  add_custom_target(doc ALL DEPENDS doc/html/index.html)
+endif ()
diff --git a/src/Doxyfile.in b/src/Doxyfile.in
index 925dd994..b43e9448 100644
--- a/src/Doxyfile.in
+++ b/src/Doxyfile.in
@@ -58,7 +58,7 @@ PROJECT_LOGO           =
 # entered, it will be relative to the location where doxygen was started. If
 # left blank the current directory will be used.
 
-OUTPUT_DIRECTORY       = ../doc
+OUTPUT_DIRECTORY       = doc
 
 # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
 # directories (in 2 levels) under the output directory of each output format and