用NMAKE创建VS2012 C++工程二 创建目录结构

本文介绍使用NMAKE工具为VS2012 C++项目构建HelloWorld工程的方法。通过定制Makefile,实现源文件与目标文件的分离,指定输出路径及文件名,并管理依赖关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

紧接前文用NMAKE创建VS2012 C++工程 HelloWorld

现在想做一些改进

1. 不使用根据obj文件默认生成的exe文件名,并且放在bin目录下

用link的 /out参数


2. obj文件放到独立的obj目录下

需要用copy命令,


3. 改变obj文件名

默认和.cpp文件名相同,修改文件名可以用cl /Fe参数,注意/Fe后面不能有空格,紧跟要输出的文件名,并且仅生成在当前运行nmake的目录下。

这里我没有使用/Fe,仅用默认规则。


4. 头文件放在include目录下,.cpp文件放在src目录下。用cl的/I参数


5. makefile文件应该放在build目录下(题外话:一般我喜欢创建一个builder目录,里面有我自己的newlisp编译脚本)


6. 去掉上一篇里面的exception handling warning 用/EHsc


7. 添加一个Pseudotargets: all, 以便运行make all


慢慢来,首先知道如何定义宏,参考文档:http://msdn.microsoft.com/en-us/library/y2be734c.aspx

其实很简单,形如:

A=B, 或者 A = B
用空格看上去更舒服点。

宏的值可以包含多个用空格间隔的字符串,也可以换行,换行符是\,比如:

A = B\
C\
D

NMAKE提供了一些预处理指令,参考文档:http://msdn.microsoft.com/en-us/library/7y32zxwh.aspx

比如可以用下面的指令取消宏A的定义

!UNDEF A

使用宏很简单,如下:

$(macroname)
会在该处用宏的值来做文本替换。


有了宏,我就可以在makefile中用其定义几个目录, 定义输出的exe文件名称等。


现在来看一下目录结构:

step2

  -bin

  -build

  -include

  -obj

  -src

在src目录下,main.cpp文件代码:

#include "printer.h"

int main()
{
  print();
  return 0;
}
printer.cpp文件代码:
#include "printer.h"
#include <iostream>

using namespace std;

void print() {
  cout << "HelloWorld step2" << endl;
}

include\printer.h文件代码:

#ifndef STEP2_INCLUDE_PRINTER_H_
#define STEP2_INCLUDE_PRINTER_H_

void print();

#endif


build\makfile文件内容:

INCLUDE_DIR = ..\include
OBJ_DIR = ..\obj
BIN_DIR = ..\bin
SRC_DIR = ..\src
EXE_NAME = step.exe

OBJ_FILES = \
	$(OBJ_DIR)\main.obj \
	$(OBJ_DIR)\printer.obj

$(OBJ_DIR)\main.obj: $(SRC_DIR)\main.cpp
	cl /c /EHsc /I$(INCLUDE_DIR) $(SRC_DIR)\main.cpp
	copy main.obj $(OBJ_DIR)
	del main.obj

$(OBJ_DIR)\printer.obj: $(SRC_DIR)\printer.cpp
	cl /c /EHsc /I$(INCLUDE_DIR) $(SRC_DIR)\printer.cpp
	copy printer.obj $(OBJ_DIR)
	del printer.obj

$(EXE_NAME): $(OBJ_FILES)
	link /out:$(BIN_DIR)\$(EXE_NAME) $(OBJ_FILES)

all: $(EXE_NAME)


当在build目录下运行nmake all的时候,target all将会被执行,all依赖target $(EXE_NAME),因此该target被执行,又依赖$(OBJ_FILES),因此OBJ_FILES里面的每个obj都会被执行,最后回到link命令进行连接。这是一个按照依赖顺序反向执行过程。

这里看到几个系统命令,都是VS2012提供的:

cl, link, copy和del

cl可以参考我的博客常用cl编译命令参数解释

link参考另一篇VS 2012 显示Link的参数

Pseudotargets参考文档:http://msdn.microsoft.com/en-us/library/7sb2acw1.aspx

也就是这个target实际上是个不存在的文件,也不会创建它。pseudotarget必须依赖某个target,但是在pseudotarget所在的description block中不能拥有command block.


在build目录下,运行命令编译好后,执行step.exe,成功。

c:\study\nmake\step2\build>nmake all

Microsoft (R) Program Maintenance Utility Version 11.00.60610.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        cl /c /EHsc /I..\include ..\src\main.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
        copy main.obj ..\obj
        1 file(s) copied.
        del main.obj
        cl /c /EHsc /I..\include ..\src\printer.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

printer.cpp
        copy printer.obj ..\obj
        1 file(s) copied.
        del printer.obj
        link /out:..\bin\step.exe ..\obj\main.obj  ..\obj\printer.obj
Microsoft (R) Incremental Linker Version 11.00.60610.1
Copyright (C) Microsoft Corporation.  All rights reserved.




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值