为cmake配置emacs

时间:2010-01-23 15:40:34

标签: emacs cmake

gcc 4.4.2 cmake 2.6

我刚开始使用cmake。来自写我自己的Makefiles。

但是,我有这个目录结构并使用out-of-source构建。将源文件与构建文件分开。

project
    src
        my_c_files.c
        CMakeLists.txt
    build
        Makefile

在我在src目录中编写自己的Makefile然后按F5然后我能够编译我的程序之前。 emacs会列出任何警告或错误。但是,似乎我必须打开终端并转到构建目录才能运行

cmake ../src

然后

make

我想在emacs中运行make,就像按F5一样。但是当makefile在build目录中生成时,emacs正在src目录中查找它。

即使我在src目录中设置了Makefile的软链接,也链接到build目录中的Makefile。所有这一切都给了我一个错误列表。

7 个答案:

答案 0 :(得分:24)

出于完全相同的目的,我发现.dir-locals.el 非常非常有用,以下是我的一个看法:

((nil . ((tab-width . 8)
     (indent-tabs-mode . t)))
 (c++-mode . ((c-basic-offset . 8)
          (tab-width . 8)
          (indent-tabs-mode . t)
          (compile-command . "make -C ../build -j 2 run_tests")))
 ((c-mode . ((c-basic-offset . 8)
         (tab-width . 8)
         (indent-tabs-mode . t)
         (compile-command . "make -C ../build -j 2 run_tests")))))

显然,我可以根据位置在不同的.dir_locals.el中指定路径,例如,某些构建run_tests用于单元测试,有些构建真实目标等等。

然后我在构建目录中放置一个虚拟makefile,如下所示:

all: run_tests

run_tests:
    @cmake ..
    @make -j 2

通过这种方式,我可以结帐,只需在我喜欢的任何文件中运行M-x compile,它就会做正确的事情。我使用git并通过git进行监视,使得Makefile 忽略,如下所示:

git update-index --assume-unchanged Makefile

如果我想修改并提交它,我会

git update-index --no-assume-unchanged Makefile

这样cmake Makefile新创建的方法不会在git status中显示为已修改,我不会意外提交。

这种方法的好处:

  • 因为cmake在内部使用绝对路径,所以只需按下输入就可以跳过编译缓冲区中的编译错误。

  • 你可以指定你想要的任何缩进规则,如果你愿意,它们可以在不同的项目甚至目录中有所不同:)

  • 您可以在不同的项目中指定任何数量的目标,甚至是目录,仍然使用相同的旧M-x compile(我将其绑定到C-c b)并让Emacs执行< em>正确的事。

唯一的缺点是你的子目录中有.dir-locals.el,我几乎找不到它。

编辑: robUK,回答您的评论:

以下是 Per-Directory Local Variables documentation,因为他们在Emacs手册中调用它。它不是一个包,它是Emacs的一部分,虽然我不确定它是否在23之前的版本中可用,我使用的是23.1.1。

EDIT2: liwp,回答你的问题:

正如查尔斯已经指出的那样,正如文件所说:

  

如果您放置一个带有特殊名称的文件   目录中的.dir-locals.el,Emacs   会在访问任何文件时读取它   在该目录或其任何目录中   子目录,并应用设置   它指定文件的缓冲区。   Emacs搜索.dir-locals.el   从目录开始   访问过的文件,并向上移动   目录树。 (为避免减速,   远程跳过此搜索   文件。)

项目树中无处不在.dir-locals.el。但请注意,它可能取决于代码库结构的复杂性。

我通常会选择这样一个相当简单的布局:

/project_root_dir
    /build
    /src
    /test

我会在不同的.dir-locals.el中指定稍微不同的目标,比如/test我只会构建testrunner并执行它,我会花费大部分开发时间来构建这个目标。然后在/src我首先构建相同的testrunner,让它执行,如果一切顺利,它将构建我的主要项目目标。如果您不需要此功能,那么.dir-locals.el下只有一个/project_root_dir即可。如果您的源结构和要求更加复杂,那么可能意味着您需要更多与路径和目标相关的魔法。

答案 1 :(得分:9)

编译命令的更通用的解决方案是:

cd ${PWD%/src/*}/build && cmake ../src && make

环境变量PWD保存您正在编辑的文件所在的目录;使用%/src/*扩展它会让您回到项目根目录,而不必担心需要多少../

答案 2 :(得分:5)

简单的解决方案: 安装cpputils-cmake,然后你就可以了。

说明: CMake已经将所有信息都放在了构建目录中。如果从cmake获得正确的信息,您只需要在compile-commandc++-mode-hook中修改ELisp变量c-mode-hook

完美解决方案有两点:

  1. 您的elisp代码应该在黑客攻击之前通过扫描源目录来检测当前项目是否正在使用CMake compile-command

  2. 源外构建目录的完整路径应自动检测并附加到make -C命令。

  3. 我写了一个emacs插件cpputils-cmake https://github.com/redguardtoo/cpputils-cmake,它将解决这两个问题。检查我的代码,你可以通过Emacs的包管理器安装它。

    顺便说一句, 构建目录由cmake创建后,通常不应在命令行中显式调用cmake。 make -C out-of-source-build-dir足够聪明,因为该目录中的Makefile无论如何都会调用cmake。即使您更改了CMakeLists.txt,调用make -C out-of-source-build-dir仍然足够。我很确定这一点,因为我已经使用cmake四年了。

    之前的许多答案都不起作用,因为:

    1. 关于源树布局的任何假设都可能是错误的。例如,我将我的根源目录命名为“mysrc”而不是“src”

    2. 我如何使用源外策略很复杂。例如,我可以通过使用out-of-source来构建一个组件。

答案 3 :(得分:4)

我正在使用Cedet的EDE配置与CMake一起工作的项目。查看into my CEDET config,从第105行开始,例如项目配置的代码。我使用单独的Debug&amp;释放不同构建的目录,默认情况下,编译仅在调试模式下运行....

答案 4 :(得分:2)

您可以更改emacs与M-x cd<enter> <path to build dir><enter>一起使用的当前工作目录。在此之后,当您运行M-x compile时,make将在新的工作目录中执行。这实际上与在构建目录中的终端上运行make相同,所以它应该对你有用。

答案 5 :(得分:2)

如何使用-C选项进行制作?

按下 F5 M-x compile,当emacs询问compile-command时,键入:

make -C ../build

答案 6 :(得分:1)

更改命令以使用绝对而不是相对pat。 EG:

cmake ~/workspace/project/src && make