9

我使用 emacs 进行一些编码和文本编辑。当我创建一个新的编码项目时,我只需创建一个新文件夹,并将源代码添加到其中。

问题是,对于多个文件夹,很难更改回顶部并运行 makefile。

有没有像eclipse或其他IDE这样的项目管理的好方法?

4

12 回答 12

7

我知道你的问题。如果您在与源代码相同的文件夹中有一个 Makefile,并且您在源缓冲区中,那么“编译”将正确构建。

但是,如果您的源代码位于不同的文件夹中,则 emacs 找不到 Makefile。

一种解决方案是通过将“默认目录”变量设置为每个源文件中的文件变量来指定 Makefile 的位置。

为此,您可以在文件顶部添加这样的一行(并重新加载它)。

// -*- mode: C++; default-directory: "c:/somewhere/yourmakefiledirectory/" -*-
于 2009-04-15T04:50:46.177 回答
7

下面是;; 我的 .emacs 文件的编译部分。我使用 CTRL+F7 进行 make,使用 F7 进行 make clean。它将在当前目录中搜索,然后在 .. 中搜索一个名为“Makefile”的文件以运行 make。

也不是 F8 将源窗口跳转到第一个错误,而 CTRL+F8 将您带到上一个错误。(顺便说一句,如果您认为这很棒,您应该看看我为 GDB 集成所做的工作)... :)

;; Compilation
(setq compilation-scroll-output 1) ;; automatically scroll the compilation windo
w
(setq compilation-window-height 10) ;; Set the compilation window height...
(setq compilation-finish-function ;; Auto-dismiss compilation buffer...
      (lambda (buf str)
        (if (string-match "exited abnormally" str)
            (message "compilation errors, press F6 to visit")
          ; no errors, make the compilation window go away after 2.5 sec
          (run-at-time 2.5 nil 'delete-windows-on buf)
          (message "No compilation errors!"))))

(require 'cl) ; If you don't have it already
(defun* get-closest-pathname (&optional (file "Makefile"))
  "This function walks up the current path until it finds Makefile and then retu
rns the path to it."
  (let ((root (expand-file-name "/")))
    (expand-file-name file
              (loop
            for d = default-directory then (expand-file-name ".." d)
            if (file-exists-p (expand-file-name file d))
            return d
            if (equal d root)
           return nil))))

(defun my-compile-func ()
  "This function does a compile."
  (interactive)
  (compile (format "make -C %s" (file-name-directory (get-closest-pathname)))))

(defun my-compile-clean-func ()
  "This function does a clean compile."
  (interactive)
  (compile (format "make -C %s clean" (file-name-directory (get-closest-pathname
)))))

(defun my-compile-package-func ()
  "This function builds an Endura package."
  (interactive)
  (compile (format "make -C %s package" (file-name-directory (get-closest-pathna
me)))))

(global-set-key [f7] 'my-compile-clean-func)
(global-set-key [C-f7] 'my-compile-func)
(global-set-key [S-f7] 'my-compile-package-func)
(global-set-key [f8] 'next-error)
(global-set-key [C-f8] 'previous-error)
于 2009-04-15T17:58:57.437 回答
7

只需M-x compile从根目录一次。这将创建一个*compilation*缓冲区,该缓冲区将记住调用它的目录和参数。

然后当你想重新编译时,只需发出M-x recompile. 这适用于任何地方。它会恢复您的原始*compilation*缓冲区并使用存储在该缓冲区中的目录来查找您的 Makefile。

还有其他方法可以从项目的根目录之外进行编译,但我想我会指出这一点,因为它开箱即用,零自定义。许多其他响应使解决方案听起来比实际更复杂。

编译缓冲区提示

如果您C-c C-f在编译缓冲区中键入,它将启用next-error-follow-minor-mode,因此当您在编译缓冲区的错误中导航时,第二个窗口将在其原始源缓冲区中显示错误。

M-n并将M-p在编译缓冲区的错误之间移动。

如果您已经在源缓冲区中,并且想要在那里的错误之间导航,请键入M-g nM-g p

语法错误突出显示

键入M-x flymake-mode以在您键入时进行动态语法检查。它将以红色突出显示语法错误。用鼠标悬停将显示错误消息。

为了使 flymake 工作,您必须在 makefile 中添加检查语法规则。

C++ 示例:

check-syntax:
    g++ -o nul -S ${CXXFLAGS} ${CHK_SOURCES}

此规则检查文件的语法,但不编译它,因此速度很快。

于 2011-11-30T23:56:11.427 回答
5

我通常不再从 emacs 中编译,但为什么不能在缓冲区中运行 shell 只是为了运行 make。将该外壳保存在顶级目录中。

至于项目管理,您在寻找哪些功能?

于 2009-04-15T00:58:18.077 回答
3

我使用 CEDET 包中的 EDE——它可以维护不同类型的项目。我使用它与 CMake 一起使用自定义编译命令(您可以在此处找到它- 请参阅 MyCompile 函数)

于 2009-04-15T05:37:40.980 回答
2

我最近开始使用project-root来管理我的各种目录树。我现在已经将 F5 绑定到 (with-project-root (compile)) 并且默认目录自动设置为我在 .emacs 中指定的任何项目的根目录,基于我调用的任何缓冲区编译自。

于 2009-04-15T04:53:19.387 回答
1

我不确定你在问什么,但你可能正在寻找Speedbar

于 2009-04-15T01:12:19.557 回答
1

于 2011-09-05T05:26:54.367 回答
0

取决于语言。JDE 是一个很好的 Java 环境,Distel 是一个很好的 Erlang 环境。我相信其他平台也有很好的环境。但是,与在 Eclipse 之类的 IDE 中相比,您必须在 emacs 中进行更多的配置。不过,IMO,回报是值得的。

于 2009-04-15T01:33:04.530 回答
0

在提示输入编译命令时输入以下内容如何:

“cd <root> ; 制作”

如果经常键入很麻烦,可以在“compile-command”变量中设置它——尽管在你键入一次后它会在会话中被记住。

于 2009-04-15T16:58:28.597 回答
0

当我使用 Java 执行此操作时,我使用了 ANT,而 ANT 使用“-find”开关优雅地处理了这个问题。

实际上,它所做的是在当前目录中查找 build.xml 文件,直到找到它。非常方便,尤其是在 Java 项目中,因为它们强制执行目录结构。

对于 Make,我会创建一个类似的替换:

#!/bin/sh
# mymake -- my "hunt the makefile" make command
if [ -f Makefile ]
then
    exec make
else
    cur=`pwd`
    if [ $cur = "/" ]
    then
        echo "Can not find Makefile"
        exit 1
    fi
    newdir=`dirname $cur`
    cd $newdir
    exec mymake
fi
于 2009-04-15T17:07:26.640 回答
0

我会使用eproject;http://github.com/jrockway/eproject

这是来自 SO 的一个例子:在某个地方有一个好的 Emacs 项目管理吗?

基本上,它统一了 CEDET、project-root 等的特性。您可以通过多种方式声明项目定义,并通过统一的 API 访问数据。它还带有一些不错的糖,包括 ibuffer 集成。(按项目过滤ibuffer,查看缓冲区名称旁边的项目名称等]

于 2009-06-11T23:30:33.550 回答