In cc-mode, when we go to compile, M-x followed by compile, the default option is make -k. If I hit the down arrow, I am told no defaults available.

Is it possible to add the option g++ -Wall currentfile.cpp -o currentfile -std=c++14 to the default compile options where currentfile is filled in by the name of the .cpp program I am editing?

If it is too difficult to have the currentfile populate, would it be possible to have g++ -Wall -std=c++14 come up? Then I can fill in x.cpp -o x. However, option is one is the most desirable.


Thanks to the University of Wyoming I have been able to achieve the result with:

;; Make M-x compile smarter in order to guess language
(require 'compile)
(defvar compile-guess-command-table
  '((c-mode       . "gcc -Wall -g %s -o %s -lm")
    (c++-mode     . "g++ -Wall %s -o %s -std=c++14")
    (fortran-mode . "gfortran -C %s -o %s")

(defun compile-guess-command ()
  (let ((command-for-mode (cdr (assq major-mode
    (if (and command-for-mode
             (stringp buffer-file-name))
        (let* ((file-name (file-name-nondirectory buffer-file-name))
               (file-name-sans-suffix (if (and (string-match "\\.[^.]*\\'"
                                               (> (match-beginning 0) 0))
                                          (substring file-name
                                                     0 (match-beginning 0))
          (if file-name-sans-suffix
                (make-local-variable 'compile-command)
                (setq compile-command
                      (if (stringp command-for-mode)
                          ;; Optimize the common case.
                          (format command-for-mode
                                  file-name file-name-sans-suffix)
                        (funcall command-for-mode
                                 file-name file-name-sans-suffix)))

;; Add the appropriate mode hooks.
(add-hook 'c-mode-hook       (function compile-guess-command))
(add-hook 'c++-mode-hook     (function compile-guess-command))
(add-hook 'fortran-mode-hook (function compile-guess-command))

Additionally, this solution also adds support for C and Fortran which I left in the solution.


The manual has a very useful entry on this, with an example of setting it based on the current file. (use Ctrl-h v compile-command)

Sometimes it is useful for files to supply local values for this variable. You might also use mode hooks to specify it in certain modes, like this:

(add-hook 'c-mode-hook
   (lambda ()
 (unless (or (file-exists-p "makefile")
         (file-exists-p "Makefile"))
   (set (make-local-variable 'compile-command)
    (concat "make -k "
        (file-name-sans-extension buffer-file-name))))))

Additionally, you can use set-file-local-variable-prop-line to save the compile command for a single file.


Install smart-compile package inside Emacs.

add this into your init.el or .emacs

(require 'compile)
(setq compilation-last-buffer nil)
;; save all modified buffers without asking before compilation
(setq compilation-ask-about-save nil)
(defun compile-again (ARG)
  "Run the same compile as the last time.

With a prefix argument or no last time, this acts like M-x compile,
and you can reconfigure the compile args."
  (interactive "p")
  ;; the following two lines create bug: split a new window every time
  ;; (if (not (get-buffer-window "*compilation*"))
  ;;      (split-window-below))
  (if (and (eq ARG 1) compilation-last-buffer)
    (call-interactively 'smart-compile)))
(bind-key* "C-x C-m" 'compile-again)
;; create a new small frame to show the compilation info
;; will be auto closed if no error
(setq special-display-buffer-names
      `(("*compilation*" . ((name . "*compilation*")
                            (left . (- 1))
                            (top . 0)))))
(setq compilation-finish-functions
      (lambda (buf str)
        (if (null (string-match ".*exited abnormally.*" str))
            ;;no errors, make the compilation window go away in a few seconds
               "1 sec" nil 'delete-windows-on
               (get-buffer-create "*compilation*"))
              (message "No Compilation Errors!")))))

Use C-x C-m to compile your source code, If you are the first time to execute C-x C-m, it will ask you to change the default command (which is usually enough), otherwise it will execute the command you just used to compile directly and you have to use C-u C-x C-m to change the command if you want. If you got a Makefile inside the current directory, it will notice and prompt to ask whether you want to use it.

Maybe this answer is too much for your question, but please try it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.