Emacs 最快的 C++ 编译过程?

2022-01-02 00:00:00 makefile c++ emacs

这是用例:我在技术博客上阅读了有关 C++ 的文章(多重继承失败和多线程失败等等:).通常它们带有一些代码.它几乎总是一个文件而我几乎总是想运行它并玩弄它.

Here's the use case: I read an articles on tech blogs about C++ (fails of multiple inheritance this and multi-threading that etc.:). Usually they come with some code. It's almost always one file and I almost always want to run it and play around with it.

我想用 Emacs 来做,我想快点做,就像使用最少(或相当少)的按键一样.

I want to do it with Emacs and I want to do it FAST, as in with the least (or reasonably few) keystrokes.

所以假设我已经在它自己的文件夹中创建了一个 multiple_inheritance.cc 文件并粘贴了代码.如何真正快速地获得可执行文件?

So suppose I've already created a multiple_inheritance.cc file in its own folder and pasted the code. How do I get to an executable really fast?

这是我现在正在做的事情(希望有人能改进它.)

Here's what I'm doing now (hopefully someone will improve 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 
                 "
	g++ -g -O2 -std=c++0x -o $@ $^

"
                 "clean: 
	rm -f " n-target "
"))
        (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's a few things that SLOW me down currently:

  1. compile 询问我是否要保存任何与 C++ 完全无关的打开文件.
  2. 我想在 *compilation* 缓冲区中有一点,以防出现错误.我查看了 compile.el,其中定义了 compilation-num-errors-found,但该变量并未在该文件中的任何地方使用.
  3. 另一方面,如果没有错误(我只需要一个谓词),为什么不启动 term 并运行程序?
  1. compile asks if I want to save any open files that are totally unrelated to C++.
  2. I'd like to have the point in *compilation* buffer in case there was an error. I've looked into compile.el, which has compilation-num-errors-found defined, but that variable isn't used anywhere in that file.
  3. On the other hand, if there were no errors (I just need a predicate for this), why not launch term and run the program?

推荐答案

我已经更新了代码,我必须将 run 目标添加到 Makefile.我还添加了一个扩展到 C:

I've updated the code I had to add a run target to Makefile. I've 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 "
	%s -o $@ $^"
                   cpp-generate-compiler)
                 "

clean: 
	rm -f " n-target
                 "

run: " n-target "
	 ./" n-target
                 "

.PHONY: clean run
"))
        (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
")
                (push-mark)
                (next-error)))))

有了 (setq compiler-ask-about-save nil) 就没有了关于保存的警告(cpp-run 自动保存).

With (setq compilation-ask-about-save nil) there's no more warnings about saving (cpp-run saves automatically).

我只需要记住 M-g nM-g p导航错误.

And I just have to remember that M-g n and M-g p navigate the errors.

现在我的过程几乎是最佳的:从源到结果的一个关键,以防万一没有错误.

Now my process is neary optimal: one key from source to result in case there are no errors.

如果有错误,它是一个额外的M-g n.现在,如果 compile 有一种方法可以调用 (push-mark)(next-error)...

In case there are errors, it's an extra M-g n. Now, if only there was a way for compile to call (push-mark)(next-error)...

感谢@juanleon 的建议,解决了:

Thanks to suggestion of @juanleon, this is solved with:

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

但由于某种原因,push-mark 在这种情况下无法正常工作.

But for some reason, push-mark doesn't work properly in this case.

相关文章