diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3c2447ab6da41649c32ce486af5ebcdedd4307f3..289feab9c34a8a7c69c68ac254bbbb0b899aec29 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1559,7 +1559,12 @@ set(LICENSE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/doc/LICENSE.txt)
 set(CREDITS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/doc/CREDITS.txt)
 set(ONELAB_PY ${CMAKE_CURRENT_SOURCE_DIR}/contrib/onelab/python/onelab.py)
 file(GLOB TUTORIAL_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tutorial/?*.*)
-file(GLOB DEMO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/demos/?*.*)
+file(GLOB DEMOS ${CMAKE_CURRENT_SOURCE_DIR}/demos/*)
+foreach(SUBDIR ${DEMOS})
+  if(IS_DIRECTORY ${SUBDIR})
+    list(APPEND DEMOS_DIRS ${SUBDIR})
+  endif()
+endforeach()
 set(TEX_DIR ${CMAKE_CURRENT_SOURCE_DIR}/doc/texinfo)
 file(GLOB TEX_SRC ${TEX_DIR}/*.texi)
 set(TEX_OBJ ${TEX_DIR}/gmsh.aux ${TEX_DIR}/gmsh.cp ${TEX_DIR}/gmsh.cps
@@ -1602,7 +1607,10 @@ if(WIN32 OR CYGWIN)
     unix2dos(LICENSE_FILE)
     unix2dos(CREDITS_FILE)
     unix2dos(TUTORIAL_FILES)
-    unix2dos(DEMO_FILES)
+    foreach(DIR ${DEMOS_DIRS})
+      file(GLOB DEMO_FILES ${DIR}/?*.*)
+      unix2dos(DEMO_FILES)
+    endforeach()
   endif(CYGWIN)
 elseif(APPLE AND ENABLE_OS_SPECIFIC_INSTALL)
   # set these so that the files get installed nicely in the MacOSX
@@ -1672,7 +1680,11 @@ install(FILES ${WELCOME_FILE} DESTINATION ${GMSH_DOC} RENAME README.txt)
 install(FILES ${LICENSE_FILE} DESTINATION ${GMSH_DOC})
 install(FILES ${CREDITS_FILE} DESTINATION ${GMSH_DOC})
 install(FILES ${TUTORIAL_FILES} DESTINATION ${GMSH_DOC}/tutorial)
-install(FILES ${DEMO_FILES} DESTINATION ${GMSH_DOC}/demos)
+foreach(DIR ${DEMOS_DIRS})
+  get_filename_component(DEMOS_DIR_NAME ${DIR} NAME)
+  file(GLOB DEMO_FILES ${DIR}/?*.*)
+  install(FILES ${DEMO_FILES} DESTINATION ${GMSH_DOC}/demos/${DEMOS_DIR_NAME})
+endforeach()
 if(UNIX AND NOT CYGWIN)
   install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/doc/gmsh.1 DESTINATION ${GMSH_MAN})
 endif(UNIX AND NOT CYGWIN)