我在项目根目录中有一个makefile。如果我正在编辑子目录中的文件,如何从EMACS调用 make ? M-x compile make 将无效,因为它在当前目录中查找makefile。但是我在项目根目录中有makefile。
有什么想法吗?
修改
正如所建议的那样, make -f fullpath_to_makefile 就可以了。但我在makefile中有一些包含“ tests / module.mk ”的包含失败。它正在子目录中寻找“ tests ”目录。这可以通过在makefile中指定完全限定的路径来解决。但我不认为这是一个很好的解决方案。有更好的方法吗?
答案 0 :(得分:5)
M-x compile
函数查找您可以在promt上覆盖的compile-command-variable
- 所以只需将其替换为类似
(cd ../.. && make && cd -)
让它运行。
我也经常使用文件头(第1行),例如
// -*- compile-command: "g++ -o myprog myprog.ccc -lfoo -lbar && ./myprog"; -*-
您可以随意使用不同的选项进行概括。重新加载文件后,M-x compile
将执行您认为非常有用的自定义编译命令。
答案 1 :(得分:3)
(我使用scons,但原理是一样的。将SConstruct更改为Makefile和scons来制作......)
我已经通过.emacs进行了自定义,因此它总是编译包含当前缓冲区文件的项目,但是深度嵌套;它向上搜索第一个SConstruct并将其用作项目根目录。
这是一些搜索目录层次结构的函数,用于查找SConstruct。
;; inspired by jds-find-tags-file in http://www.emacswiki.org/emacs/EmacsTags
(defun find-sconstruct ()
"recursively searches upwards from buffer's current dir for file named SConstruct and returns that dir. Or nil if not found or if buffer is not visiting a file"
(labels
((find-sconstruct-r (path)
(let* ((parent (file-name-directory path))
(possible-file (concat parent "SConstruct")))
(cond
((file-exists-p possible-file)
(throw 'found-it possible-file))
((string= "/SConstruct" possible-file)
(error "No SConstruct found"))
(t (find-sconstruct-r (directory-file-name parent)))))))
(if (buffer-file-name)
(catch 'found-it
(find-sconstruct-r (buffer-file-name)))
(error "Buffer is not visiting a file"))))
(defun project-root ()
(file-name-directory (find-sconstruct)))
然后,您可以将compile-command
更改为使用project-root
,例如
(concat "cd " (project-root) " && scons")
答案 2 :(得分:2)
我使用EDE(来自CEDET)来定义项目,并在项目定义中存储编译命令。查看my config示例:第105-133行 - 项目示例,第135-165行 - 代码,定义编译函数,第168-189行 - 不同类型项目的函数 - 标准(从根目录编译)和cmake(在单独目录中编译)
答案 3 :(得分:2)
另一种方法是设置变量 compilation-process-setup-function ,记录为:
调用函数来自定义编译过程。这个功能 在编译过程开始之前立即调用。它 可用于设置在使用时使用的任何变量或函数 处理编译过程的输出。功能是 用变量
compilation-buffer' and
compilation-window'调用 分别绑定到编译缓冲区和窗口。
我使用Maven很多并编写了这个库来支持你的Maven上下文问题。在下文中,根据需要更改变量 compile-search-file 的值:
;;; Support for Maven 2
(require 'compile)
(setq compile-search-file "pom.xml")
(defun find-search-file ()
;; Search for the pom file traversing up the directory tree.
(setq dir (expand-file-name default-directory))
(let ((parent (file-name-directory (directory-file-name dir))))
(while (and (not (file-readable-p (concat dir compile-search-file)))
(not (string= parent dir)))
(setq dir parent
parent (file-name-directory (directory-file-name dir))))
(if (string= dir parent)
(error "Search file %s is missing" compile-search-file)
(with-current-buffer compilation-last-buffer
(message "Test %s %s." compilation-buffer compilation-window)
(setq default-directory dir)))))
;; Add the following to support Emacs' compile mode:
(add-to-list
'compilation-error-regexp-alist-alist
'(mvn "^\\(.*\\):\\[\\([0-9]*\\),\\([0-9]*\\)\\]" 1 2 3))
(add-to-list 'compilation-error-regexp-alist 'mvn)
(setq compilation-process-setup-function 'find-search-file)
(provide 'maven-support)
答案 4 :(得分:1)
当我使用Emacs编译迷你缓冲区时,看起来像这样;
make -k
我只是添加我喜欢的任何文字,例如-f ../../root/Makefile。这可能适合你。
标记
答案 5 :(得分:1)
我不是一个emacs用户,但是你可以通过make -C ../或者你需要的目录吗?
答案 6 :(得分:1)
经过一段时间尝试让EDE按照我想要的方式工作,我选择 .dir-locals.el :
((c++-mode . ((compile-command . "make -C ../build -j2 whatever"))))
我发现它比在每个文件的标题中都有// -*- -*-
稍微好一些,
并且比在我的init.el(或任何其他配置)中指定具有项目完整路径的那些ede-cpp-root-project
要好得多,我要么经常创建,要么突然移动:)
该方案的好处是cmake,这使得编译错误“可以正确跳转”,因为它在生成的makefile中使用完整路径。
答案 7 :(得分:1)
我刚刚开始研究一种更通用,可扩展且更健壮但仍然合理的快速和肮脏的解决方案。它有点基于上面的Maven示例,但我不喜欢使用全局变量,因此我更多地使用let或let *特殊形式。当然它使用make。
现在它只支持Makefile,但如果你想支持一个或多个其他不同的构建系统,你可以在`my-compilation-process-setup-function'函数中为(cond)特殊形式添加一个子句。 / p>
它甚至还有doc字符串!
你最终会在my Github看到它。
答案 8 :(得分:0)
这应该这样做:
make -f path_to_rootdir/Makefile -I path_to_rootdir/tests
-f告诉它使用什么makefile,-I告诉它在哪里查找要包含在makefile中的文件(不在本地目录中)。
答案 9 :(得分:0)
从M-x compile RET
开始。当它提示输入命令时,只需输入cd /path/to/root && make
并点击返回。此命令适用于make的所有变体,并且在没有任何额外标志的情况下处理“包含的makefile”问题。
下次键入M-x compile RET
时,此新字符串将显示为默认字符串,因此您只需点击返回。如果您在emacs中积极编译多个项目,则可以使用M-p
和M-n
在编译错误的历史记录中前后移动。