为cmake配置emacs

为cmake配置emacs,emacs,cmake,Emacs,Cmake,通用条款4.4.2 cmake 2.6 我刚刚开始使用cmake。来自我自己编写的makefile 但是,我有这个目录结构,并使用了源代码外构建。将源文件与生成文件分开 project src my_c_files.c CMakeLists.txt build Makefile 在我将自己的makefile写入src目录,然后按F5之前,我能够编译我的程序。emacs会列出任何警告或错误。但是,似乎我必须打开一个终端并转到buil

通用条款4.4.2 cmake 2.6

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

但是,我有这个目录结构,并使用了源代码外构建。将源文件与生成文件分开

project
    src
        my_c_files.c
        CMakeLists.txt
    build
        Makefile
在我将自己的makefile写入src目录,然后按F5之前,我能够编译我的程序。emacs会列出任何警告或错误。但是,似乎我必须打开一个终端并转到build目录才能运行

cmake ../src
然后

make
我想在emacs中运行make,与按F5相同。但是作为生成文件,Makefile已经在build目录中生成,emacs正在src目录中查找它


即使我将src目录中的Makefile软链接设置为build目录中的Makefile。所有这些只是给了我一个错误列表。

我正在使用Cedet中的EDE来配置与CMake一起工作的项目。看,从第105行开始,例如项目配置代码。我对不同的版本使用单独的调试和发布目录,默认情况下,编译仅在调试模式下运行。…

您可以更改emacs与
M-x cd一起使用的当前工作目录。在此之后,当您运行
M-x compile
时,将在新的工作目录中执行
make
。这实际上与在终端上运行build目录中的
make
是一样的,因此它对您来说应该可以正常工作。

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

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

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

出于完全相同的目的,我发现
.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\u locals.el
中指定路径,例如,一些构建
运行单元测试的测试,一些构建真正的目标等等

然后我在build目录中放置了一个伪
makefile
,如下所示:

all: run_tests

run_tests:
    @cmake ..
    @make -j 2
/project_root_dir
    /build
    /src
    /test
这样,我就可以进行签出,只需在我喜欢的任何文件中运行
M-x compile
,它就会做正确的事情。我使用git并让git从监视中忽略该Makefile,如下所示:

git更新索引--假定Makefile未更改

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

git更新索引——不假设Makefile未更改

这样,cmake Makefile新创建的文件就不会显示在修改后的
git status
中,我也不会意外地提交它

这种方法的好处:

  • 由于cmake在内部使用绝对路径,所以只需按enter键就可以跳过编译缓冲区中的编译错误

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

  • 您可以在不同的项目中指定任意数量的目标,甚至是目录,仍然使用相同的旧
    M-x compile
    (我将其绑定到
    C-cb
    )并让Emacs做正确的事情

唯一的缺点是在您的子目录中有
.dir locals.el
,我几乎不觉得这很糟糕

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

这里是每个目录的局部变量,正如他们在Emacs手册中所说的那样。它不是一个包,它是Emacs的一部分,尽管我不确定它是否在23之前的版本中可用,但我使用的是23.1.1

EDIT2:liwp,回答您的问题:

正如Charles已经指出的,正如文件所述:

如果你用一个特殊的名字放一个文件 目录中的.dir-locals.el,Emacs 将在访问任何文件时读取它 在该目录或其任何 子目录,并应用设置 它指定文件的缓冲区。 Emacs搜索.dir-locals.el 从 访问文件,并向上移动 目录树。(为了避免经济放缓, 已跳过此搜索以查找远程文件 文件。)

您不需要在项目树中的任何地方都使用
.dir locals.el
。但是,请注意,这可能取决于代码基结构的复杂性

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

all: run_tests

run_tests:
    @cmake ..
    @make -j 2
/project_root_dir
    /build
    /src
    /test

我会在不同的
.dir locals.el
中指定稍微不同的目标,比如在
/test
中,我只会构建
testrunner
并执行它,我会花费大部分开发时间构建这个目标。然后在
/src
中,我将首先构建相同的
testrunner
,并执行它,如果一切顺利,它将为我构建我的主要项目目标。如果您不需要这个,您可以只使用
/project\u root\u dir
下的一个
.dir locals.el
。如果您的源结构和需求更加复杂,则可能意味着您需要更多与路径和目标相关的向导。

将命令更改为使用绝对而不是相对pat。例如:

cmake ~/workspace/project/src && make

在make中使用-C选项如何

按F5或
M-x compile
,当emacs请求compile命令时,键入:

make -C ../build
简单解决方案: 安装,然后你就可以走了

说明: CMake已将所有信息放在生成目录中。如果您从cmake获得正确的信息,您只需要在
c++-mode-hook
c-mode-hook
中破解ELisp变量
compile命令

完美解决方案有两点:

  • 在破解
    compile命令之前,您应该通过扫描源目录来检测当前项目是否正在使用CMake

  • 源代码外生成目录