使用VisualStudio完成自动化C++代码生成和编译工作(GacUI)
GacUI终于进入制作dll的阶段了。昨天上传了一个新的工程,在 Vczh Library++3.0(E:\Codeplex\vlpp\Workspace\Tools\Release\SideProjects\GacUI\GacUI.sln)。这里面一共有三个工程,有两个是工具,一个是dll。
为了编译出带反射的控件库,因此每一个控件都可以获得一个ITypeDescriptor对象。但是控件库一共有几十个类上千个函数,我不可能一个一个去实现的(请想想实现IDispatcher的时候)。根据 上一篇博客讨论过技术,我将使用一个程序来读pdb生成C++代码。详细的计划如下:
1:制作一个_GacPDB工程。这是一个exe,但是是没用的,唯一的用处就是他引用了GacUI.dll所需要的所有源代码,然后靠编译器产生PDB文件。
2:制作一个_TranslatePDBtoXML工程。这是一个exe,从PDB抽取类声明。
3:制作一个_TranslateXMltoCode。顾名思义,不过现在还没做,原理是一样的。
4:GacUI.dll。这个dll包含了所有的控件的实现,还有_TranslateXMLtoCode产生的所有代码。
现在我的目标是,先编译_Translate*工程,然后编译_GacPDB产生pdb后自动调用它们,生成代码结束之后开始合并编译GacUI.dll。所有的这些东西都需要在VisualStudio的“Rebuild Solution”里面完成。为了完成这个目标,我创建这些工程之后,按照下面的方法修改了工程属性:
1:工程A引用了工程B的话,那么只有当B完全编译好之后才会编译A。因此上面的配置将阻止三个工程平行编译,强制他们按照_TranslatePDBtoXML、_GenPDB和GacUI的顺序来。
2:_TranslatePDBtoXML编译好之后,会把它依赖的msdia100.dll复制到编译出来的exe旁边,以供接下来调用。
3:_GenPDB编译好之后,pdb已经产生了。这个时候它会自动调用上一步编译出来的_TranslatePDBtoXML,读取pdb,输出xml
4:(接下来要做的)调用_TranslateXMLtoCode,输入xml,输出C++代码
5:这个时候,生成的C++代码已经就绪了,所以开始编译GacUI。
附加的好处还有一个。因为_GenPDB引用了GacUI的cpp,所以当GacUI的源代码修改的时候,_GenPDB也会感应到,从而在下次编译GacUI的时候先开始编译_GenPDB。并且因为GacUI依赖了_GenPDB,所以_GenPDB仍然会先编译。而且这种依赖关系是无害的,因为_GenPDB没有输出lib,因此GacUI.dll在运行的时候完全不需要_GenPDB.exe的存在。
好了。那把一个个的cpp文件添加到_GenPDB也是在太麻烦了,所以我投机取巧了一下:
为了编译出带反射的控件库,因此每一个控件都可以获得一个ITypeDescriptor对象。但是控件库一共有几十个类上千个函数,我不可能一个一个去实现的(请想想实现IDispatcher的时候)。根据 上一篇博客讨论过技术,我将使用一个程序来读pdb生成C++代码。详细的计划如下:
1:制作一个_GacPDB工程。这是一个exe,但是是没用的,唯一的用处就是他引用了GacUI.dll所需要的所有源代码,然后靠编译器产生PDB文件。
2:制作一个_TranslatePDBtoXML工程。这是一个exe,从PDB抽取类声明。
3:制作一个_TranslateXMltoCode。顾名思义,不过现在还没做,原理是一样的。
4:GacUI.dll。这个dll包含了所有的控件的实现,还有_TranslateXMLtoCode产生的所有代码。
现在我的目标是,先编译_Translate*工程,然后编译_GacPDB产生pdb后自动调用它们,生成代码结束之后开始合并编译GacUI.dll。所有的这些东西都需要在VisualStudio的“Rebuild Solution”里面完成。为了完成这个目标,我创建这些工程之后,按照下面的方法修改了工程属性:
1
_TranslatePDBtoXML:
2 post build action:
3 copy $(ProjectDir)msdia100.dll $(SolutionDir)$(Configuration)\msdia100.dll
4 _GenPDB:
5 references:
6 _TranslatePDBtoXML
7 post build action:
8 $(SolutionDir)$(Configuration)\_TranslatePDBtoXML.exe $(SolutionDir)Debug\_GenPDB.pdb $(SolutionDir)_GenPDB.xml
9 GacUI:
10 references:
11 _GenPDB
2 post build action:
3 copy $(ProjectDir)msdia100.dll $(SolutionDir)$(Configuration)\msdia100.dll
4 _GenPDB:
5 references:
6 _TranslatePDBtoXML
7 post build action:
8 $(SolutionDir)$(Configuration)\_TranslatePDBtoXML.exe $(SolutionDir)Debug\_GenPDB.pdb $(SolutionDir)_GenPDB.xml
9 GacUI:
10 references:
11 _GenPDB
1:工程A引用了工程B的话,那么只有当B完全编译好之后才会编译A。因此上面的配置将阻止三个工程平行编译,强制他们按照_TranslatePDBtoXML、_GenPDB和GacUI的顺序来。
2:_TranslatePDBtoXML编译好之后,会把它依赖的msdia100.dll复制到编译出来的exe旁边,以供接下来调用。
3:_GenPDB编译好之后,pdb已经产生了。这个时候它会自动调用上一步编译出来的_TranslatePDBtoXML,读取pdb,输出xml
4:(接下来要做的)调用_TranslateXMLtoCode,输入xml,输出C++代码
5:这个时候,生成的C++代码已经就绪了,所以开始编译GacUI。
附加的好处还有一个。因为_GenPDB引用了GacUI的cpp,所以当GacUI的源代码修改的时候,_GenPDB也会感应到,从而在下次编译GacUI的时候先开始编译_GenPDB。并且因为GacUI依赖了_GenPDB,所以_GenPDB仍然会先编译。而且这种依赖关系是无害的,因为_GenPDB没有输出lib,因此GacUI.dll在运行的时候完全不需要_GenPDB.exe的存在。
好了。那把一个个的cpp文件添加到_GenPDB也是在太麻烦了,所以我投机取巧了一下:
1
#include
"
..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiApplication.cpp
"
2 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiBasicControls.cpp "
3 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiListControls.cpp "
4 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiTextControls.cpp "
5 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiWindowControls.cpp "
6 // ---------------------------------------------------------------
7 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiComboControls.cpp "
8 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiContainerControls.cpp "
9 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiListViewControls.cpp "
10 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiMenuControls.cpp "
11 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiTextListControls.cpp "
12 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiTreeViewControls.cpp "
13 // ---------------------------------------------------------------
14 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\Styles\GuiCommonStyles.cpp "
15 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\Styles\GuiWin7Styles.cpp "
16 // ---------------------------------------------------------------
17 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsComposition.cpp "
18 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsElement.cpp "
19 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsEventReceiver.cpp "
20 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsHost.cpp "
21 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsTextElement.cpp "
22 // ---------------------------------------------------------------
23 #include " ..\..\..\..\..\Candidate\GUI\GUI\NativeWindow\GuiNativeWindow.cpp "
24 #include " ..\..\..\..\..\Candidate\GUI\GUI\NativeWindow\Windows\WinNativeWindow.cpp "
25 // ---------------------------------------------------------------
26 #include " ..\..\..\..\..\Candidate\GUI\GUI\Reflection\GuiTypeDescriptor.cpp "
27 // ---------------------------------------------------------------
28 #include " ..\..\..\..\..\Library\Basic.cpp "
29 #include " ..\..\..\..\..\Library\Exception.cpp "
30 #include " ..\..\..\..\..\Library\String.cpp "
31 #include " ..\..\..\..\..\Library\Threading.cpp "
32 #include " ..\..\..\..\..\Library\Collections\Operation.cpp "
33 // ---------------------------------------------------------------
34 #include < Windows.h >
35
36 int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow)
37 {
38 return 0 ;
39 }
2 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiBasicControls.cpp "
3 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiListControls.cpp "
4 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiTextControls.cpp "
5 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\GuiWindowControls.cpp "
6 // ---------------------------------------------------------------
7 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiComboControls.cpp "
8 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiContainerControls.cpp "
9 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiListViewControls.cpp "
10 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiMenuControls.cpp "
11 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiTextListControls.cpp "
12 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\ExtendedControls\GuiTreeViewControls.cpp "
13 // ---------------------------------------------------------------
14 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\Styles\GuiCommonStyles.cpp "
15 #include " ..\..\..\..\..\Candidate\GUI\GUI\Controls\Styles\GuiWin7Styles.cpp "
16 // ---------------------------------------------------------------
17 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsComposition.cpp "
18 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsElement.cpp "
19 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsEventReceiver.cpp "
20 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsHost.cpp "
21 #include " ..\..\..\..\..\Candidate\GUI\GUI\GraphicsElement\GuiGraphicsTextElement.cpp "
22 // ---------------------------------------------------------------
23 #include " ..\..\..\..\..\Candidate\GUI\GUI\NativeWindow\GuiNativeWindow.cpp "
24 #include " ..\..\..\..\..\Candidate\GUI\GUI\NativeWindow\Windows\WinNativeWindow.cpp "
25 // ---------------------------------------------------------------
26 #include " ..\..\..\..\..\Candidate\GUI\GUI\Reflection\GuiTypeDescriptor.cpp "
27 // ---------------------------------------------------------------
28 #include " ..\..\..\..\..\Library\Basic.cpp "
29 #include " ..\..\..\..\..\Library\Exception.cpp "
30 #include " ..\..\..\..\..\Library\String.cpp "
31 #include " ..\..\..\..\..\Library\Threading.cpp "
32 #include " ..\..\..\..\..\Library\Collections\Operation.cpp "
33 // ---------------------------------------------------------------
34 #include < Windows.h >
35
36 int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow)
37 {
38 return 0 ;
39 }
啊哈哈哈哈(拖走
VisualStudio的功能是强大的。只要善于使用,或者配合MSBuild,所起到的威力将毫不亚于某些著名工具链。而且VisualStudio编译器产生的文件,基本上VisualStudio都有提供API供你阅读,所以也可以做很多事情,譬如我这篇文章说的这样,充当了一个编译器的扩展,而且完美集成。