一个大型项目可能有几个级别深度的目录。Emacs 的默认编译命令是"make -k"
,如果我修改了某个源代码,然后键入"M-x compile RET RET"
,它将"make -k"
在源代码所在的目录下执行。
我想我可以写一个函数来判断Makefile是否存在于当前目录下,如果存在,则继续在父目录下搜索直到找到最顶层目录,然后执行构建命令,这和我的预期一样。
但是,我不太清楚如何开始,有人可以给我一些开始的提示吗?就像我可能遇到的函数或变量一样。谢谢。
一个大型项目可能有几个级别深度的目录。Emacs 的默认编译命令是"make -k"
,如果我修改了某个源代码,然后键入"M-x compile RET RET"
,它将"make -k"
在源代码所在的目录下执行。
我想我可以写一个函数来判断Makefile是否存在于当前目录下,如果存在,则继续在父目录下搜索直到找到最顶层目录,然后执行构建命令,这和我的预期一样。
但是,我不太清楚如何开始,有人可以给我一些开始的提示吗?就像我可能遇到的函数或变量一样。谢谢。
您可以尝试使用类似的东西:
(setq compile-command
'(let ((mf (locate-dominating-file default-directory "Makefile")))
(if mf (setq mf (file-name-directory mf)))
(concat (if (and mf (not (equal mf default-directory)))
(format "cd %s; "
(shell-quote-argument
(file-relative-name
(directory-file-name mf)))))
"make -k ")))
果酱中有一个更智能的编译器。
从文档中......当您需要它时,您可以指定一个 cons 单元格列表,每个单元格都像(TEST . COMMAND)
.
COMMAND 用于compile-command
测试成功的时间。
测试可以是:
一个字符串。在这种情况下,它用作正则表达式,并与与缓冲区关联的文件名匹配。当正则表达式匹配时,TEST 成功。
一个符号,代表主模式。在这种情况下,如果缓冲区使用该主要模式,则 TEST 成功。
一个符号,表示名称不以 \"-mode\" 结尾的任何函数。在这种情况下,调用该函数,如果它返回非零,则 TEST 成功。
表格列表。在这种情况下,表单是 eval'd,如果返回值不是 nil,则 TEST 成功。
因此,您可以生成一个函数来扫描父目录中的 makefile,并将其用作您的测试。
根据文档,如果 COMMAND 为 nil,则包使用 TEST 的结果作为编译命令。这意味着您只需要一个函数,返回一个引用相应目录中的 makefile 的 make 命令。
看看:http ://emacswiki.org/emacs/CompileCommand
直接来自 emacs 的“Ch v compile-command”。
对于那些喜欢 bash 脚本而不是 Emacs Lisp 的人来说,这是一个解决方案。在我的 .emacs 中,我定义了一个保存所有缓冲区并运行编译项目的 bash 脚本的命令。
(defun save-all-and-compile () (interactive)
(save-some-buffers 1)
(shell-command "make-and-run.sh &"))
(add-hook 'c-mode-common-hook (lambda ()
(local-set-key (kbd "<f5>") 'save-all-and-compile)))
对于小型项目,脚本可能很简单
#!/bin/bash
make -j && ./<main>
其中“main”是可执行文件的名称。对于较大的项目,首先需要找到根目录。同样,您可以使用不同的脚本(绑定到不同的键)来构建和运行程序。然后是一些用于测试项目不同部分的脚本。但这些只是一个可以自己弄清楚的细节。
确保使用“&”异步运行脚本。这样,Async Shell 命令缓冲区将使用 make 和您的项目的输出打开,并将保持打开状态。
编辑
根据下面的讨论,我最初似乎想多了,解决方案非常简单。与其将通常的“make”或“make -k”传递给编译命令,不如使用一个 shell 脚本,它首先导航到项目的根目录和构建。
(setq compile-command "script.sh")