diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54432ccda2a91688e093de6d37cdafac5702ab5a..50e68ba79d4ae207081cc4cfc8a207837daebf9a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+Changes in dune-contact v2.6.0
+==============================
+
+* There is now a subdirectory `src`, and some of the compilable source code
+  files have moved there.  This makes `dune-contact` more consistent with
+  other Dune modules.
+
 Changes in dune-contact v2.5.0
 ==============================
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e554fa9cd35ff819519405b32b7e38713daca4fe..cd1ee0a6c65e50572c6e1cdcecd03775d8f17c86 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,13 +13,11 @@ dune_project()
 
 add_subdirectory(doc)
 add_subdirectory(dune)
+add_subdirectory(src)
 add_subdirectory(test)
 dune_symlink_to_source_files(FILES resources)
 
 set(programs "")
-if(HAVE_AMIRAMESH)
-  list(APPEND programs 2bcontact)
-endif()
 if(HAVE_AMIRAMESH AND HAVE_IPOPT)
   list(APPEND programs 1badaptmeasure 1bcontact het2bcontact 2bnonlincontact 2bmgnonlincontact)
 endif()
diff --git a/2bcontact.cc b/src/2bcontact.cc
similarity index 100%
rename from 2bcontact.cc
rename to src/2bcontact.cc
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d08c09cf243d062bebcbee147979dc4b01d5cb4a
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,16 @@
+set(programs "")
+#if(HAVE_AMIRAMESH)
+  list(APPEND programs 2bcontact)
+#endif()
+
+foreach(_program ${programs})
+  add_executable(${_program} ${_program}.cc)
+  target_link_dune_default_libraries(${_program})
+  add_dune_amiramesh_flags(${_program})
+  add_dune_ipopt_flags(${_program})
+  add_dune_ug_flags(${_program})
+  add_dune_psurface_flags(${_program})
+  add_dune_mpi_flags(${_program})
+  target_compile_options(${_program} PRIVATE "-fpermissive")
+endforeach()
+