从Emacs的子目录中调用项目根目录中的makefile

时间:2009-11-03 17:32:52

标签: emacs makefile

我在项目根目录中有一个makefile。如果我正在编辑子目录中的文件,如何从EMACS调用 make M-x compile make 将无效,因为它在当前目录中查找makefile。但是我在项目根目录中有makefile。

有什么想法吗?

修改

正如所建议的那样, make -f fullpath_to_makefile 就可以了。但我在makefile中有一些包含“ tests / module.mk ”的包含失败。它正在子目录中寻找“ tests ”目录。这可以通过在makefile中指定完全限定的路径来解决。但我不认为这是一个很好的解决方案。有更好的方法吗?

10 个答案:

答案 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-pM-n在编译错误的历史记录中前后移动。