首先讲讲解决方案和项目之间的关系。
VS2010使用解决方案管理项目,解决方案包含一个或多个项目。
新建一个解决方案TestSolution,包含一个应用程序项目TestApp和一个动态链接库项目TestLib。
TestSolution解决方案的总目录结构如下:
TestSolution.sln为解决方案的配置文件。
TestApp文件夹和Testlib文件夹分别代表TestApp项目和TestLib项目
Debug文件夹以及Release文件夹,存放的是最终生成的结果exe或dll,要注意如果不使用Release生成,则不存在Release文件夹
TestSolution.sdf用来保存预编译的头文件和Intellisense用的,删除这些文件对于工程的开发完全没有影响,还有
项目TestApp的目录结构如下:
Debug文件夹和Release文件夹: 存放的是中间编译结果obj
TestApp.vcxproj:项目配置文件
TestApp:vcxproj.filters:用于项目下文件的虚拟目录 。关于vcxproj.filters文件的详细介绍,可以看这篇文章: http://www.cjjjs.cn/paper/xmkf/6242015223023494.aspx
TextApp.vcxproj.user:用户的一些相关配置
第二,常用项目属性和系统配置变量关系
$(SolutionDir):解决方案目录
$(Configuration):指Debug或Release
$(OutDir):在 “常规--输出目录 ”中定义的值,如$(SolutionDir)$(Configuration)\。所以调试时会在解决方案文件夹下建立一个Debug(Configuration的值为Debug)文件夹,并在此文件夹下生成 TestApp.lik链接器 和TestApp.exe文件 。
$(ProjectName):目标文件名
$(TargetExt):扩展名
默认“中间目录”为$(Configuration),所以会在TestApp项目文件夹下(即TestApp.vcxproj的项目配置文件所在位置)建立一个Debug文件夹,并在该文件夹下生成TestApp.obj二进制文件。
默认“链接器”栏目下的“常规”选项下的“输出文件”选项为:$(OutDir)$(TargetName)$(TargetExt)。其中$(OutDir)就已经在“常规”栏目的“输出目录”选项赋值了。【所以$(OutDir)的值是在“输出目录”属性中定义的】。
$(TargetName):目标输出名,不包括扩展名
$(TargetDir) 的值是在生成exe文件后自动赋予值为exe文件所在位置
$(TargetPath)的值是在$(TargetDir)值的基础上加上exe文件名。
总结上面的内容,默认情况下“输出目录”和“输出文件”两个属性对应的目录是一样的,这样用着方便(当然,输出文件的值在输出目录的值的基础上还包含有exe文件名)。如果两个不一样,则中间生成的链接器用的如xx.ilk和xx.pdb文件等在输出目录,而最终生成的xx.exe文件在“输出文件”属性设置的目录中。
“链接器”栏目下的“输入”选项下的“附加依赖项”项。此项是设置程序链接时使用的静态库。相当于链接已经编译好了的“代码”。由此我们可以简单的认为这些库就相当于我们自己写的.cpp文件,只不过这些库是编译好了的.cpp而已(这里只需要库名称即可,搜索路径在其他地方设置)。
“ 附加依赖性的设置”等同于在代码中写“#pragma comment(lib, "库名称.lib") ”语句,如果使用相对路径则如下:
#pragma comment(lib,"..\\debug\\TestLib.lib");其中的反斜杠要用双反斜杠,因为它是程序解释的双引号包括的字符串,需要转义一下,要区别include,#include "..\TestVideoApplication.h"中并不是由程序解释的字符串,所以不用转义。
“调试”栏目中的“工作目录”项,这个属性默认情况下是空的,但表示工作目录是工程目录,也就是项目配置文件TestApp.vcproj所在目录。
工作目录表示进行某项操作的目的目录,会随着OpenFileDialog、SaveFileDialog等对象所确定的目录而改变。“工作目录”属性作用是程序运行后唯一识别的默认目录,即工作后只认识这个目录,工作目录这个名字描述的就很形象,(可以将所依赖的lib和dll库文件所在目录设为工作目录,但一般是把lib放在解决方案下的Lib目录中,把dll放在解决方案下的Bin目录中),例如程序运行过程中生成一个txt文本文件,如果在创建文件过程中未指定绝对路径,只指定创建文件的文件名,那么这个文本文件默认就会建立在工作目录中,当然读取一些配置文件也在工作目录中查找,但要说明一下,生成的exe文件跟工作目录没任何关系,也不会放在工作目录中。
总的来说,工作目录就是程序运行过程中默认读取的目录。对于dll,如果是程序运行前就进入内存有点像静态链接那样,此时dll就可以放入exe所在的执行目录,如果dll是运行中动态加载的一般放在工作目录,比如插件就放在工作目录。即工作目录就是运行期间唯一能识别的默认目录,工作目录在代码中用GetCurrentDirectory之类的函数获取。工作目录与执行目录可以不同,例如一个人住在北京,但他的工作地点不一定在北京,可能在天津。
【对工作目录的补充:vs中工作目录的设置是给调试用的,也即你启动调试后,启动一个新进程,自动把这个新进程的工作目录设置为vs项目属性中的工作目录,然后新进程启动对应的exe程序。但是如果不使用vs的调试启动exe,而是直接双击exe文件启动一个新进程时,会自动把这个新进程的工作目录设置为exe文件所在的目录,这是和vs启动调试不同的地方。所以如果发布的时候不把工作目录内的东西拷到exe所在的目录内,就会运行出错,因为此时工作目录不再是vs中设置的了,而是exe文件所在的目录。最后,说一下,vs中默认的vc++工程的工作目录项目的值是空的,代表默认是vs工程所在目录即.vcproj文件所在目录,c#工程默认没测试,估计和vc的一样。】
【同样在调试选项下的和工作目录选项同一级的选项“命令”选项是设置,使用调试时,从哪里启动exe文件,因为一般生成的exe放在bin目录下的debug或release目录下,所以命令选项一般为“Bin\$(Configuration)\$(ProjectName).exe”,默认也是这个值,当然可以更改,但此时意味着调试状态下启动的exe为“命令”选项中设置的exe文件,而不是默认的bin目录下的debug或release下的exe文件了。最后说一下,上面所说的“调试”是指vs下启动exe,包括debug模式和release模式,不要把调试就理解为只有debug模式。】
“调试”栏目中的“命令(Command)”属性项,【这个属性表示调试器要启动的exe文件的全名】,包括路径名,默认为$(TargetPath),而TargetPath就表示目标输出文件的全路径名,所以一般情况下它代表的值就等于“输出文件”属性代表的值。当然你也可以人为的更改“命令”属性的值,比如更改为c:\aa.exe,而“输出文件”的值为c:\bb.exe,此时如果输出文件所在目录没有aa.exe的话(因链接器只生成bb.exe而根本不会生成aa.exe),调试器就不能启动aa.exe,提示找不到aa.exe。当然如果目录中已经有aa.exe文件(可以强制赋值一个bb.exe文件的副本并命名为aa.exe),此时调试器就可以正常调试通过。
来源:oschina
链接:https://my.oschina.net/u/171160/blog/657660