C++ Primer:源码编译运行说明
1. 背景
最近刚看完《C++ primer 中文版(第5版)》第一章,写完源码后想比较一下官方示例的源码,发现其说明文档是英文,大致看懂后记录一下官方是如何编译运行它的源码。
2. 相关资料与环境
C++ primer源码官方下载地址:
http://www.informit.com/store/c-plus-plus-primer-9780321714114
下载版本 | 说明 |
---|---|
GCC 4.7.0 | 适用于gcc 4.7.0及以上的版本 |
MS Visual Studio 2012 | 适用于VS2012及以上的版本 |
GCC pre-C++ 11 compilers 2012 | 适用于VS2012以下的版本 |
Microsoft pre-C++ 11 compilers | 适用于gcc 4.7.0以下的版本 |
由于电脑中VS2017,故直接下载MS Visual Studio 2012。以下的编译运行在VS环境下运行。
MS Visual Studio 2012文件目录说明:
- 文件夹1~文件夹19代表C++ primer19个章节的源码。
- Version_test.h是部分源码所需头文件,如文件夹1的Sales_data.h就引用Version_test.h。
- CompilerNotes.pdf和Visual Studio 2012 README.pdf是总体文档说明。
- runpgms.bat从文件夹1遍历到文件夹19,runp.bat跳转到各个文件夹内部,执行里面runpgms.bat。
- makefile和MS_makefile_template是nmake默认执行文件,用于编译目录下所有源码,并生成对应.exe文件。
第1章节文件夹目录说明:
- data文件夹存放部分cpp文件执行所需输入的数据。
- .cpp文件是第一章所有源码。
- Sales_item.h是部分cpp文件执行所需头文件。
- runpgms.bat用于执行.exe文件,它会自动导入data文件夹中的数据并输出结果。若此文件夹中无对应的.exe文件,runpgms.bat执行失败。
- README.txt章节文档说明
- makefile是nmake默认执行文件,用于编译此目录下所有源码,并生成对应.exe文件。
由此文件夹中所有的makefile都是用nmake运行,故需要创建compile.bat来调用VS的vsvars32.bat搭建nmake运行环境。当双击compile.bat时,系统打开cmd,所有编译命令都是在上面执行。
compile.bat代码:
@echo off
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"
cmd
提示:使用需修改vsvars32.bat地址,本文所用vsvars32.bat地址如下:
3. 编译运行
3.1 单文件编译运行
将compile.bat复制粘贴到文件所在的目录,双击运行compile.bat,在弹出的cmd窗口输入编译命令即可。编译命令如下所示,其中/EHsc启动异常处理,/nologo禁止版权声明。
// add.cpp编译成add.obj
cl /EHsc /nologo /c add.cpp
// add.obj编译成add.exe
cl /EHsc /nologo add.obj
// 一步到位,add.cpp编译成add.exe
cl /EHsc /nologo add.cpp
多步编译:
单步编译:
编译结果:
3.2 文件重定向
通过文件重定向可以在运行.exe时,无需输入,直接将data文件夹中的文件作为输入文件,并计算输出结果。
data/add_item数据:
0-201-78345-X 3 20.00
0-201-78345-X 2 25.00
编译命令:
// add_item.cpp编译成add_item.exe
cl /EHsc /nologo add_item.cpp
// 自动导入data/add_item计算结果
add_item.exe <data/add_item
编译结果:
注意:如果出现如下编译错误,其原因是add_item.cpp中引用#include “Sales_item.h”,而Sales_item.h又引用#include “Version_test.h”。故需要在编译命令中添加"/I…",表示引用上级目录,即主目录。也可以将主目录的Version_test.h拷贝到本目录上。
修改后的编译命令:
cl /EHsc /nologo /I.. add_item.cpp
编译结果:
当文件夹下所有.cpp都存在对应.exe时,点击runpgms.bat便可输出多个.exe文件重定向后的计算结果。若cmd一闪而过,需要在runpgms.bat最后一行加上“pause”用于暂停。
runpgms.bat修改前:
echo on
add < data/add
add_item < data/add_item
add_item2 < data/add_item
avg_price < data/book_sales
item_io < data/book_sales
occurs < data/occurs
mysum < data/mysum
for %%i in ( for_ex forcount main_only whilecount) do %%i
runpgms.bat修改后:
echo on
add < data/add
add_item < data/add_item
add_item2 < data/add_item
avg_price < data/book_sales
item_io < data/book_sales
occurs < data/occurs
mysum < data/mysum
for %%i in ( for_ex forcount main_only whilecount) do %%i
pause
3.3 多文件编译运行
若觉得一个文件一个文件的编译运行太麻烦,可以使用compile.bat运行makefile,通过以下三个命令实现对所有源码的编译,对.obj和.exe的清除。
// 编译目录下所有源码
nmake
// 删除文件夹下所有.obj
nmake clean
// 删除文件夹下所有.obj和.exe
namke clobber
注意:在编译运行第2章节文件夹中的inits.cpp时,会出现“error C2732: 链接规范与“lround” 的早期规范冲突”的错误,这需将Version_test.h中的“#ifndef LROUND”修改为“#ifdef LROUND”。
修改前:
#ifndef LROUND
inline long lround(double d)
{
return (d >= 0) ? long(d + 0.5) : long(d - 0.5);
}
#endif
修改后:
// #ifndef LROUND
#ifdef LROUND
inline long lround(double d)
{
return (d >= 0) ? long(d + 0.5) : long(d - 0.5);
}
#endif
4. 总结
- 编译环境不重要,用gcc,g++或cl都可以,重要的是代码编写和程序编译过程。
- 了解文件重定向和makefile的使用,会让编程更高效。