diff --git a/.gitignore b/.gitignore
index a75bb34530ef01c54d3be529df9c76b587933161..38fc753943bf740dea78cb8fdbe951a5d9ec6cb8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,4 +31,5 @@
 build-doc
 
 # Emacs stuff
+TAGS
 scripts/dynare.elc
diff --git a/meson.build b/meson.build
index e9ce6d58f9e5a4a147d829791e57baac4bebca97..8b09500f0d93f92bcadeaa9944fc754f03410047 100644
--- a/meson.build
+++ b/meson.build
@@ -1825,3 +1825,23 @@ foreach t : mod_and_m_tests
   test(test_name, test_driver_exe, args : test_driver_args, suite : test_suite,
        should_fail : t.get('should_fail', false), timeout : 0)
 endforeach
+
+
+### Developper stuff
+
+## Tag file for Emacs (created in *source* directory)
+
+git_exe = find_program('git', required : false)
+etags_exe = find_program('etags', required : false)
+
+if git_exe.found() and etags_exe.found()
+  all_files = run_command(git_exe,
+                          [ '--git-dir=@0@/.git'.format(meson.project_source_root()),
+                            'ls-files', '--recurse-submodules',
+                            ':/*.cc', ':/*.hh', ':/*.[fF]08', ':/*.[ch]' ],
+                          check : true)
+  all_files = files(all_files.stdout().split())
+
+  custom_target('tags', output : 'tags', # Dummy output argument to make Meson happy
+                command : [etags_exe, '-o', '@0@/TAGS'.format(meson.project_source_root())] + all_files)
+endif