介绍了三种在 Emacs 编译 VS 项目的方案。
在 Windows 开发比较大型的 C/C++ 项目,往往还是得借助微软的 Visual Studio (C++),但对于重度 Emacs 使用者,离开了用起 VC 来总是各种蹩脚。关于如何在 Emacs 中搭建 VC 的开发环境,fangzhzh 的一篇博文 《Emacs 中开发 VC 程序》 已经做了比较好的讨论。唯一不足的地方是对 Emacs 调用 VC 编译缺乏更深入的探讨。编译 VC 基本上还是要靠微软自家的工具,经过我的摸索,一共有三种不同的方案,针对不同的需要,用户可以自行选择。
总体说来,这三种方案各自的特点比较如下:
序号 | 调用工具 | 读取文件格式 | 特点 |
---|---|---|---|
1 | envdev | *.sln |
可以编译整个VS的解决方案。缺点在于编译后没有给出错误提示。 |
2 | nmake | *.mak |
使用微软自家的 make 工具来编译单个工程。缺点在于生成 *.mak 文件比较麻烦。 |
3 | msdev | *.dsw |
VC 6.0 提供的单个工程编译工具。在VS 2005之后就被 envdev 取代了。 |
现在就让我们来深入探讨一下如何在 Emacs 中编译 Visual Studio (C++)
附图 1 Emacs的项目。在Visual Studio中,可以把所有的项目看作一个解决方案,这个解决方案就用
*.sln
文件来记录,并通过 devenv 工具来读取、分析和编译。它位于VS目录下的
Common7IDE
目录中。
为了方便直接在 Emacs 下调用 envdev ,可以先把 devenv 所在的目录加进系统 环境变量。例如,我的 devenv 所在的目录为“D:/Program Files/Microsoft Visual Studio 9.0/Common7/IDE”,则可以将该路径添加到 PATH 环境变量中。
附图 2 Visual Studio完成后,打开cmd,执行
1 | $ devenv -h |
将可以看到如下的提示:
1 | e://josephcodesCV_01CV_01>devenv -h |
按照提示,在VS中创建一个sln工程文件后,使用devenv编译的命令为:
1 | $ devenv solutionfile.sln /build [ solutionconfig ] [ /project projectnameorfile [ /projectconfig name ] ] |
其中的 /build
等选项可以替换成 /run
等其他选项。
之后可以配置 Emacs,让我们在按下 F7
键后选择各种编译选项。在 .emacs 文件中加入以下内容:
然后将 dev-studio-build
绑定到 F7
键上,例如:
1 | (defun my-c-mode-common-hook() |
直接编译*.sln文件的缺点在于编译后只会给出结果,而没有错误提示,这样不利于调试。除了直接编译*.sln文件之外,另外的选择是使用微软自家的 make 工具 —— nmake 来编译 Makefile 1 1这里指的 Makefile 是指适用于微软的 nmake 的 Makefile 文件。微软的 nmake 使用了自己的一套标准。如果需要得到适用于GNU Linux 的 Makefile,可以试试 sln2mak 工具。 或者 .mak 文件。但 VS 使用 *.sln 和 *.vcproj 来管理工程项目,并不提供 .mak 文件。为了得到这个文件,可以使用一个 python 脚本 vcproj2mak.py 。使用命令为:
1 | $ python vcproj2mak.py 工程文件.vcproj -O makefile文件.mak |
执行这个脚本需要满足两个条件:
在脚本执行过程中可能会报“unknown encoding”错误,这个原因是 vcproj 文件在
Windows 下的默认编码是 gb2312 的,而 python 似乎不支持 gb2312
。解决的方法是使用 Emacs 打开那个 vcproj 文件,然后 C-x Ret r
,选择
UTF-8
将文件编码改为 UTF-8 格式,并将第一行
1 |
中的 “gb2312” 改为 “utf-8” 即可。完成后可以调用 nmake 来执行编译,调用格式为:
1 | $ nmake -f mak文件名 编译选项 |
其中 编译选项
是你的编译方案,一般可以选择 Debug
或者 Release
。
另外一个问题是当调用过一次 nmake 后,nmake 就会在当前目录下创建 Debug 或者 Release 目录,此时再调用一次 nmake 会提示文件夹创建错误。例如:
1 | $ mkdir Debug |
解决这个问题的方法是修改生成的 .mak 文件,在其中的 “mkdir Debug” 和 “mkdir Release” 两行语句的前面加一个减号 “-” ,表示无论 mkdir 过程中出现什么错误,都不要报错继续执行。更一劳永逸的做法是修改那个 python 脚本,将第207行
1 | mkwrite ( fh, "tmkdir %s" % cfname ) |
改为
1 | mkwrite ( fh, "t-mkdir %s" % cfname ) |
即可。
到这里还没结束,为了让 Emacs 更方便的调用 nmake,可以将 nmake 作为主要的编译工具。在 .emacs 文件中加入这一行:
1 | ;; Set up for Visual C++ compiling |
还有一个更好的做法是再写一个总的 Makefile ,以便于选择编译选项:
1 | PROJECT=MyProject |
VC 6.0 使用一个更古老的工具 msdev.exe 来编译VC的工程文件。直接调用msdev.exe,即启动Visual studio的UI界面,同时msdev.exe也接受命令行调用。我们看其帮助。
1 | msdev /? |
示例语句:
1 | C:Program Files/Microsoft Visual Studio/VC98binmsdev.exe test2.dsw /Make /NORECURSE |
同样,使用clean,rebuild可以清除、重编译该工程。将test2 改为test21,test23,即改变编译对象。 总这样写也很麻烦,而且为了在Emacs中调用 ,我们将其写成一个批处理。
1 | d: |
保存为makTest2.bat。调用方式为:
1 | $ makeTest2 [工程 [目标]] |
默认为编译test2 的 /NORECURSE。如果要编译test23的rebuild,调用方式为:
1 | $ makeTest2 test23 /REBUILD |