为cmake配置emacs

ant*_*009 22 emacs cmake

gcc 4.4.2 cmake 2.6

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

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

project
    src
        my_c_files.c
        CMakeLists.txt
    build
        Makefile
Run Code Online (Sandbox Code Playgroud)

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

cmake ../src
Run Code Online (Sandbox Code Playgroud)

然后

make
Run Code Online (Sandbox Code Playgroud)

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

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

Dmi*_*try 25

对于完全相同的目的,我发现.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")))))
Run Code Online (Sandbox Code Playgroud)

显然我可以.dir_locals.el根据它们的位置指定不同的路径,比如说一些构建run_tests单元测试,一些构建真实目标等等.

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

all: run_tests

run_tests:
    @cmake ..
    @make -j 2
Run Code Online (Sandbox Code Playgroud)

通过这种方式,我可以进行结账,只需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做正确的事情.

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

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

下面是文档每目录局部变量,因为他们把它叫做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
Run Code Online (Sandbox Code Playgroud)

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


Por*_*lus 9

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

cd ${PWD%/src/*}/build && cmake ../src && make
Run Code Online (Sandbox Code Playgroud)

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


che*_*bin 5

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

说明:CMake已将所有信息放在构建目录中.你只需要破解的elisp变量compile-command在你c++-mode-hookc-mode-hook如果你从C进行正确的信息.

两点是完美的解决方案:

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

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

我写了一个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策略很复杂.例如,我可以使用out-of-source构建一个组件.