[RBUILD]
[reactos.git] / reactos / tools / rbuild / backend / msvc / propsmaker.cpp
1 #ifdef _MSC_VER
2 #pragma warning ( disable : 4786 )
3 #endif//_MSC_VER
4
5 #include <string>
6 #include <vector>
7 #include <set>
8 #include <algorithm>
9 #include <fstream>
10 #include <iostream>
11
12 #include <stdio.h>
13
14 #include "msvc.h"
15
16 using std::string;
17 using std::vector;
18 using std::set;
19
20 typedef set<string> StringSet;
21
22 #ifdef OUT
23 #undef OUT
24 #endif//OUT
25
26
27 PropsMaker::PropsMaker (Project* ProjectNode,
28 std::string filename_props,
29 std::vector<MSVCConfiguration*> configurations)
30 {
31 m_ProjectNode = ProjectNode;
32 m_configurations = configurations;
33
34 OUT = fopen ( filename_props.c_str(), "wb" );
35
36 if ( !OUT )
37 {
38 printf ( "Could not create file '%s'.\n", filename_props.c_str() );
39 }
40 }
41
42 PropsMaker::~PropsMaker ( )
43 {
44 fclose ( OUT );
45 }
46
47 void
48 PropsMaker::_generate_header()
49 {
50 fprintf ( OUT, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n");
51 fprintf ( OUT, "<Project ");
52 fprintf ( OUT, "DefaultTargets=\"Build\" ");
53 fprintf ( OUT, "ToolsVersion=\"4.0\" ");
54 fprintf ( OUT, "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\r\n");
55 }
56
57 void
58 PropsMaker::_generate_footer()
59 {
60 fprintf ( OUT, "</Project>\r\n");
61 }
62
63 void
64 PropsMaker::_generate_macro(std::string Name, std::string Value)
65 {
66 fprintf ( OUT, "\t\t<%s>%s</%s>\r\n", Name.c_str(), Value.c_str(), Name.c_str());
67 }
68
69 void
70 PropsMaker::_generate_global_includes(bool debug, bool use_ros_headers)
71 {
72 fprintf ( OUT, "\t\t<globalIncludes>");
73
74 const IfableData& data = m_ProjectNode->non_if_data;
75 //const vector<File*>& files = data.files;
76 size_t i;
77 const vector<Include*>& incs = data.includes;
78 for ( i = 0; i < incs.size(); i++ )
79 {
80 if ((incs[i]->directory->relative_path == "include\\crt" ||
81 incs[i]->directory->relative_path == "include\\ddk" ||
82 incs[i]->directory->relative_path == "include\\GL" ||
83 incs[i]->directory->relative_path == "include\\psdk") &&
84 ! use_ros_headers)
85 {
86 continue;
87 }
88
89 if(incs[i]->directory->directory == SourceDirectory)
90 fprintf ( OUT, "\"$(RootSrcDir)\\");
91 else if (incs[i]->directory->directory == IntermediateDirectory)
92 fprintf ( OUT, "\"$(RootIntDir)\\");
93 else if (incs[i]->directory->directory == OutputDirectory)
94 fprintf ( OUT, "\"$(RootOutDir)\\");
95 else
96 continue;
97
98 fprintf ( OUT, "%s\" ; ", incs[i]->directory->relative_path.c_str());
99 }
100
101 fprintf ( OUT, "\"$(RootIntDir)\\include\" ; ");
102 fprintf ( OUT, "\"$(RootIntDir)\\include\\reactos\" ; ");
103
104 if ( !use_ros_headers )
105 {
106 // Add WDK or PSDK paths, if user provides them
107 if (getenv ( "BASEDIR" ) != NULL)
108 {
109 string WdkBase = getenv ( "BASEDIR" );
110 fprintf ( OUT, "\"%s\\inc\\api\" ; ", WdkBase.c_str());
111 fprintf ( OUT, "\"%s\\inc\\crt\" ; ", WdkBase.c_str());
112 fprintf ( OUT, "\"%s\\inc\\ddk\" ; ", WdkBase.c_str());
113 }
114 }
115 fprintf ( OUT, "\t</globalIncludes>\r\n");
116 }
117
118 void
119 PropsMaker::_generate_global_definitions(bool debug, bool use_ros_headers)
120 {
121 fprintf ( OUT, "\t\t<globalDefines>");
122
123 // Always add _CRT_SECURE_NO_WARNINGS to disable warnings about not
124 // using the safe functions introduced in MSVC8.
125 fprintf ( OUT, "_CRT_SECURE_NO_WARNINGS ; ") ;
126
127 if ( debug )
128 {
129 fprintf ( OUT, "_DEBUG ; ");
130 }
131
132 if ( !use_ros_headers )
133 {
134 // this is a define in MinGW w32api, but not Microsoft's headers
135 fprintf ( OUT, "STDCALL=__stdcall ; ");
136 }
137
138 const IfableData& data = m_ProjectNode->non_if_data;
139 const vector<Define*>& defs = data.defines;
140 size_t i;
141
142 for ( i = 0; i < defs.size(); i++ )
143 {
144 if ( defs[i]->backend != "" && defs[i]->backend != "msvc" )
145 continue;
146
147 if ( defs[i]->value != "" )
148 fprintf ( OUT, "%s=%s ; ",defs[i]->name.c_str(), defs[i]->value.c_str());
149 else
150 fprintf ( OUT, "%s ; ", defs[i]->name.c_str());
151 }
152
153 fprintf ( OUT, "\t</globalDefines>\r\n");
154 }
155
156 void
157 PropsMaker::_generate_props ( std::string solution_version, std::string studio_version )
158 {
159
160 string srcdir = Environment::GetSourcePath();
161 string intdir = Environment::GetIntermediatePath ();
162 string outdir = Environment::GetOutputPath ();
163 string rosbedir = Environment::GetVariable("_ROSBE_BASEDIR");
164
165 if ( intdir == "obj-i386" )
166 intdir = srcdir + "\\obj-i386"; /* append relative dir from project dir */
167
168 if ( outdir == "output-i386" )
169 outdir = srcdir + "\\output-i386";
170
171 _generate_header();
172
173 fprintf ( OUT, "\t<PropertyGroup Label=\"UserMacros\">\r\n");
174 _generate_macro("RootSrcDir", srcdir);
175 _generate_macro("RootOutDir", outdir);
176 _generate_macro("RootIntDir", intdir);
177 _generate_macro("Tools", "$(RootOutDir)\\tools");
178 _generate_macro("RosBE", rosbedir);
179 fprintf ( OUT, "\t</PropertyGroup>\r\n");
180
181 for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ )
182 {
183 MSVCConfiguration* cfg = m_configurations[icfg];
184
185 if(cfg->optimization == RosBuild)
186 continue;
187
188 fprintf ( OUT, "\t<PropertyGroup Condition=\"'$(Configuration)'=='%s'\">\r\n", cfg->name.c_str() );
189 _generate_global_includes(cfg->optimization == Debug, cfg->headers == ReactOSHeaders);
190 _generate_global_definitions(cfg->optimization == Debug, cfg->headers == ReactOSHeaders);
191 fprintf ( OUT, "\t</PropertyGroup>\r\n");
192 }
193
194 _generate_footer();
195 }