Is Emacs the fastest C ++ compilation process?

Here is a precedent: I read articles on technical blogs about C ++ (the failure of multiple inheritance is this and multithreading, etc. :). They usually come with a code. This is almost always a single file, and I almost always want to run it and play with it.

I want to do this with Emacs, and I want to do it FAST, as is the case with the smallest (or reasonable amount) keystrokes.

So, suppose I already created the multiple_inheritance.cc file in my own folder and pasted the code. How to quickly jump to an executable file?

Here is what I am doing now (I hope someone improves it.)

 (defun cpp-generate-makefile () (interactive) (let* ((n-buffer (buffer-file-name)) (n-file (file-name-nondirectory n-buffer)) (n-target (file-name-sans-extension n-file)) (n-makefile (concat (file-name-directory n-buffer) "Makefile"))) (if (file-exists-p n-makefile) (when (called-interactively-p 'any) (message "Makefile already exists")) (with-current-buffer (find-file-noselect n-makefile) (insert (concat n-target ": " n-file "\n\tg++ -g -O2 -std=c++0x -o $@ $^\n\n" "clean: \n\trm -f " n-target "\n")) (save-buffer))))) (defun cpp-run () (interactive) (save-buffer) (cpp-generate-makefile) (compile "make")) (add-hook 'c++-mode-hook (lambda() ;; ... (define-key c++-mode-map [f5] 'cpp-run))) 

Here are a few things that are slowing me down now:

  • compile asks if I want to keep any open files that are not completely C ++ related.
  • I would like to make sense in the *compilation* buffer in case of an error. I looked at compile.el , which has compilation-num-errors-found but this variable is not used anywhere in this file.
  • On the other hand, if there were no errors (I just need a predicate for this) why not start the term and run the program?
+4
source share
2 answers

I updated the code that was supposed to add run to the Makefile . I also added an extension to C:

 (defvar cpp-generate-compiler "g++ -g -O2 -std=c++0x") (defun cpp-generate-makefile () (interactive) (let* ((n-buffer (buffer-file-name)) (n-file (file-name-nondirectory n-buffer)) (n-target (file-name-sans-extension n-file)) (n-makefile (concat (file-name-directory n-buffer) "Makefile"))) (if (file-exists-p n-makefile) (when (called-interactively-p 'any) (message "Makefile already exists")) (with-current-buffer (find-file-noselect n-makefile) (insert (concat n-target ": " n-file (format "\n\t%s -o $@ $^" cpp-generate-compiler) "\n\nclean: \n\trm -f " n-target "\n\nrun: " n-target "\n\t ./" n-target "\n\n.PHONY: clean run\n")) (save-buffer))))) (defun cpp-run () (interactive) (save-buffer) (cpp-generate-makefile) (compile "make run")) (defun c-run () (interactive) (let ((cpp-generate-compiler "gcc -g -O2 -std=c99")) (cpp-run))) (add-hook 'c++-mode-hook (lambda() ;; ... (define-key c++-mode-map [f5] 'cpp-run))) (add-hook 'c-mode-hook (lambda() ;; ... (define-key c-mode-map [f5] 'c-run))) (setq compilation-ask-about-save nil) (setq compilation-finish-functions (list (lambda(buffer str) (unless (string= str "finished\n") (push-mark) (next-error))))) 

With (setq compilation-ask-about-save nil) there is no longer a save warning ( cpp-run automatically saved).

And I just have to remember that Mg n and Mg p go to the bugs.

Now my process is close to optimal: one key from the source will lead to the fact that there are no errors.

In case of errors there is an additional Mg n . Now, if only there was a compile way to call (push-mark)(next-error) ...

UPD:

Thanks to @ juanleon's suggestion, this is solved using

 (setq compilation-finish-functions (list (lambda(buffer str) (unless (string= str "finished\n") (push-mark) (next-error))))) 

But for some reason, push-mark does not work properly in this case.

0
source

To summarize the answers in the comments.

  • Change the value of compilation-ask-about-save . If you do not want to change this globally (using setq), you can only change it inside your function by wrapping it in the operator (let ((compilation-ask-about-save nil)) ...function contents...) .
  • Bind the following error to something quickly: (define-key c++-mode-map "\Mj" 'next-error) . I personally use the global key set for this, simply because it is useful in a number of modes.
  • Replace the compilation command in your function with (compile "make && ./a.out") (using, of course, the name of your executable file).

Hope this helps.

+2
source

Source: https://habr.com/ru/post/1490223/


All Articles