diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h
index 94aaad4365c26b10b6882cb074c854d31d46b5a0..7861e0e6b45e86ea10a910fc8b10ce6527107bf8 100644
--- a/inc/lektor/cmd.h
+++ b/inc/lektor/cmd.h
@@ -21,3 +21,7 @@ struct lkt_cmd_opt {
 /* Parse the command line with the list of options. No parameter may be NULL.
    Does not return. */
 noreturn void lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **argv);
+
+/* Must be setted for the lkt_cmd_parse function to display the correct help
+   in case of errors. */
+extern const char *executable_name;
diff --git a/meson.build b/meson.build
index 687f30d178f4a1d97faa5fb72ac3fdc8ca5ac5a2..a4d6b21e6540a57a1dad0a57f177def74df1204c 100644
--- a/meson.build
+++ b/meson.build
@@ -84,16 +84,21 @@ mthread_deps = [ declare_dependency( link_with: static_library( 'mthread'
                                    , include_directories: includes
                                    , dependencies: [ common_deps ] ) ]
 
-initsql_deps = [ declare_dependency( link_with: static_library( 'initsql'
-                                                              , [ custom_target('init.c'
-                                                                               , output: 'sql_init.c'
-                                                                               , input: 'scripts/init.sql'
-                                                                               , command: [ find_program('xxd'), '-i', '@INPUT@', '@OUTPUT@']) ] ) ) ]
+generated_deps = [ declare_dependency( link_with: static_library( 'generated'
+                                                                , [ custom_target( 'sqlinit'
+                                                                                 , output: 'sqlinit.c'
+                                                                                 , input: 'scripts/init.sql'
+                                                                                 , command: [ find_program('xxd'), '-i', '@INPUT@', '@OUTPUT@' ] ) ]
+                                                                , [ custom_target( 'manpath'
+                                                                                 , output: 'manpath.c'
+                                                                                 , input: 'scripts/getmanpath.sh'
+                                                                                 , command: [ find_program('scripts/getmanpath.sh'), '@OUTPUT@' ] ) ]
+                                                                ) ) ]
 
 lib = static_library( 'lektor'
                     , files(core_sources)
                     , include_directories: includes
-                    , dependencies: [ core_deps, libdl, common_deps, mthread_deps, initsql_deps ] )
+                    , dependencies: [ core_deps, libdl, common_deps, mthread_deps, generated_deps ] )
 
 bin_deps = [ declare_dependency( link_with: lib, include_directories: includes) ]
 
@@ -114,6 +119,7 @@ lktadm = executable( 'lktadm'
 lkt = executable( 'lkt'
                 , files('src/main/lkt.c', 'src/cmd.c', 'src/common.c')
                 , include_directories: includes
+                , dependencies: [ generated_deps ]
                 , install: true )
 
 # X11 window module
diff --git a/scripts/getmanpath.sh b/scripts/getmanpath.sh
new file mode 100644
index 0000000000000000000000000000000000000000..84a088cea05c9aa6c413fb4700f32ecc11574b2e
--- /dev/null
+++ b/scripts/getmanpath.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# $1: output file
+[ $# -ne 1 ] && exit 1
+echo "const char *man_executable_path = \"$(which man)\";" > "$1"
diff --git a/src/cmd.c b/src/cmd.c
index b34047edfd6fc7a339bf19059ec3be17d1b9c0d4..4a38bddccedf921471fde4fc149ccc5fc8f28a01 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -9,6 +9,19 @@
 #include <stdio.h>
 #include <unistd.h>
 
+const char *executable_name = NULL;
+extern const char *man_executable_path;
+
+noreturn void
+help__()
+{
+    if (!executable_name)
+        exit(EXIT_FAILURE);
+    const char *const args[] = { man_executable_path, executable_name };
+    execv(args[0], (char *const *) args);
+    exit(EXIT_FAILURE);
+}
+
 noreturn void
 lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **argv)
 {
@@ -16,8 +29,9 @@ lkt_cmd_parse(struct lkt_cmd_opt *opts, int argc, const char **argv)
     struct lkt_cmd_opt *it = opts;
     lkt_cmd_callback call[2] = { NULL, NULL };
 
-    if (argc == 0 || *argv == NULL)
-        goto no_args;
+    if (argc == 0 || *argv == NULL || strcasecmp(argv[0], "help") ||
+        strcasecmp(argv[0], "--help") || strcasecmp(argv[0], "-help"))
+        goto help;
 
     /* Find the command */
     while (it && it->name) {
@@ -56,8 +70,8 @@ not_found:
     LOG_ERROR_SCT("COMMAND", "Command '%s' could not be found", argv[0]);
     exit(EXIT_FAILURE);
 
-no_args:
-    exit(EXIT_SUCCESS);
+help:
+    help__();
 
 not_exclusive:
     LOG_ERROR_SCT("COMMAND", "Failed to determine option, '%s' not exclusive", argv[0]);
diff --git a/src/main/lkt.c b/src/main/lkt.c
index f16b2d934d43b0a69bcc5708e5631741c3bd53c1..8ea952bd2556dd90061d75f69a3ad4465eed3293 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -1083,6 +1083,7 @@ parse_args(args_t *args, int argc, const char **argv)
 int
 main(int argc, const char **argv)
 {
+    executable_name = "lkt";
     assert(NULL != setlocale(LC_ALL, "en_US.UTF-8"));   /* BECAUSE!         */
     assert(!signal(SIGPIPE, sigpipe__));                /* Argument checks. */
 
diff --git a/src/main/lktadm.c b/src/main/lktadm.c
index 13100cd5aa637535cea835be4b7759a307f06cbb..e1f7cf0c992829e21800a072dfc2ce0c16199340 100644
--- a/src/main/lktadm.c
+++ b/src/main/lktadm.c
@@ -254,5 +254,6 @@ static struct lkt_cmd_opt options[] = {
 int
 main(int argc, const char **argv)
 {
+    executable_name = "lktadm";
     lkt_cmd_parse(options, argc - 1, argv + 1);
 }