* Bring back rbuild build to be used until bug 6372 is fixed.
[reactos.git] / tools / rbuild / backend / msvc / vspropsmaker.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 VSPropsMaker::VSPropsMaker ( Configuration& buildConfig,
27 Project* ProjectNode,
28 std::string filename_props,
29 MSVCConfiguration* msvc_configs)
30 {
31 m_configuration = buildConfig;
32 m_ProjectNode = ProjectNode;
33
34 m_msvc_config = msvc_configs;
35
36 debug = ( m_msvc_config->optimization == Debug );
37 release = ( m_msvc_config->optimization == Release );
38 speed = ( m_msvc_config->optimization == Speed );
39 use_ros_headers = (m_msvc_config->headers == ReactOSHeaders);
40
41 OUT = fopen ( filename_props.c_str(), "wb" );
42
43 if ( !OUT )
44 {
45 printf ( "Could not create file '%s'.\n", filename_props.c_str() );
46 }
47 }
48
49 VSPropsMaker::~VSPropsMaker ( )
50 {
51 fclose ( OUT );
52 }
53
54 void
55 VSPropsMaker::_generate_header()
56 {
57 fprintf ( OUT, "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\r\n" );
58 fprintf ( OUT, "<VisualStudioPropertySheet\r\n" );
59 fprintf ( OUT, "\tProjectType=\"Visual C++\"\r\n" );
60
61 //Both visual studio 2005 and 2008 use vsprops files with version 8.00
62 fprintf ( OUT, "\tVersion=\"%s\"\r\n", "8.00" );
63 fprintf ( OUT, "\tName=\"%s\">\r\n", m_msvc_config->name.c_str() );
64 }
65
66 void
67 VSPropsMaker::_generate_tools_defaults()
68 {
69 fprintf ( OUT, "\t<Tool\r\n");
70 fprintf ( OUT, "\t\tName=\"VCCLCompilerTool\"\r\n");
71 fprintf ( OUT, "\t\tAdditionalIncludeDirectories=\"$(globalIncludes)\"\r\n");
72 fprintf ( OUT, "\t\tPreprocessorDefinitions=\"$(globalDefines)\"\r\n");
73 if (use_ros_headers)
74 fprintf ( OUT, "\t\tIgnoreStandardIncludePath=\"true\"\r\n");
75 fprintf ( OUT, "\t\tBufferSecurityCheck=\"false\"\r\n");
76 if(use_ros_headers) //this works only with reactos headers
77 fprintf ( OUT, "\t\tForcedIncludeFiles=\"warning.h\"\r\n");
78 fprintf ( OUT, "\t\tMinimalRebuild=\"%s\"\r\n", speed ? "TRUE" : "FALSE" );
79 fprintf ( OUT, "\t\tBasicRuntimeChecks=\"0\"\r\n" );
80 fprintf ( OUT, "\t\tRuntimeLibrary=\"%d\"\r\n", debug ? 3 : 2 ); // 3=/MDd 2=/MD
81 fprintf ( OUT, "\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" );
82 fprintf ( OUT, "\t\tUsePrecompiledHeader=\"0\"\r\n" );
83 fprintf ( OUT, "\t\tWholeProgramOptimization=\"%s\"\r\n", release ? "FALSE" : "FALSE");
84 fprintf ( OUT, "\t\tOptimization=\"%d\"\r\n", release ? 2 : 0 );
85 if ( release )
86 {
87 fprintf ( OUT, "\t\tFavorSizeOrSpeed=\"1\"\r\n" );
88 fprintf ( OUT, "\t\tStringPooling=\"true\"\r\n" );
89 }
90 fprintf ( OUT, "\t\tWarningLevel=\"%s\"\r\n", speed ? "0" : "3" );
91 fprintf ( OUT, "\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE");
92 fprintf ( OUT, "\t\tCallingConvention=\"%d\"\r\n", 0 ); // 0=__cdecl
93 fprintf ( OUT, "\t\tDebugInformationFormat=\"%s\"\r\n", speed ? "0" : release ? "3": "4"); // 3=/Zi 4=ZI
94 fprintf ( OUT, "\t\tCompileAs=\"1\"\r\n" );
95 fprintf ( OUT, "\t/>\r\n");
96
97 //Linker
98 fprintf ( OUT, "\t<Tool\r\n" );
99 fprintf ( OUT, "\t\tName=\"VCLinkerTool\"\r\n" );
100 fprintf ( OUT, "\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 );
101 fprintf ( OUT, "\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" );
102 fprintf ( OUT, "\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 0 : 0); // whole program optimization
103 fprintf ( OUT, "\t\tTargetMachine=\"%d\"\r\n", 1 );
104 if ( debug )
105 fprintf ( OUT, "\t\tProgramDatabaseFile=\"$(OutDir)/$(ProjectName).pdb\"\r\n");
106 fprintf ( OUT, "\t/>\r\n");
107
108 //Librarian
109 fprintf ( OUT, "\t<Tool\r\n" );
110 fprintf ( OUT, "\t\tName=\"VCLibrarianTool\"\r\n" );
111 fprintf ( OUT, "\t\tOutputFile=\"$(OutDir)\\$(ProjectName).lib\"\r\n");
112 fprintf ( OUT, "\t/>\r\n");
113
114 //Resource compiler
115 fprintf ( OUT, "\t\t\t<Tool\r\n" );
116 fprintf ( OUT, "\t\tName=\"VCResourceCompilerTool\"\r\n" );
117 fprintf ( OUT, "\t\tAdditionalIncludeDirectories=\"$(globalIncludes)\"\n" );
118 fprintf ( OUT, "\t/>\r\n");
119 }
120
121 void
122 VSPropsMaker::_generate_macro(std::string Name,
123 std::string Value,
124 bool EvairomentVariable)
125 {
126 fprintf ( OUT, "\t<UserMacro\r\n");
127 fprintf ( OUT, "\t\tName=\"%s\"\r\n", Name.c_str());
128 fprintf ( OUT, "\t\tValue=\"%s\"\r\n", Value.c_str());
129 if(EvairomentVariable)
130 fprintf ( OUT, "\t\tPerformEnvironmentSet=\"%s\"\r\n", "true");
131 fprintf( OUT, "\t/>\r\n");
132 }
133
134 void
135 VSPropsMaker::_generate_global_includes()
136 {
137 //Generate global includes
138 //they will be used by the c compiler, the resource compiler
139 //and the preprocessor for .s and .pspec files
140
141 fprintf ( OUT, "\t<UserMacro\r\n");
142 fprintf ( OUT, "\t\tName=\"globalIncludes\"\r\n");
143 fprintf ( OUT, "\t\tValue=\"");
144
145 const IfableData& data = m_ProjectNode->non_if_data;
146 //const vector<File*>& files = data.files;
147 size_t i;
148 const vector<Include*>& incs = data.includes;
149 for ( i = 0; i < incs.size(); i++ )
150 {
151 if ((incs[i]->directory->relative_path == "include\\crt" ||
152 incs[i]->directory->relative_path == "include\\ddk" ||
153 incs[i]->directory->relative_path == "include\\GL" ||
154 incs[i]->directory->relative_path == "include\\psdk") &&
155 ! use_ros_headers)
156 {
157 continue;
158 }
159
160 if(incs[i]->directory->directory == SourceDirectory)
161 fprintf ( OUT, "$(RootSrcDir)\\");
162 else if (incs[i]->directory->directory == IntermediateDirectory)
163 fprintf ( OUT, "$(RootIntDir)\\");
164 else if (incs[i]->directory->directory == OutputDirectory)
165 fprintf ( OUT, "$(RootOutDir)\\");
166 else
167 continue;
168
169 fprintf ( OUT, "%s ; ", incs[i]->directory->relative_path.c_str());
170 }
171
172 fprintf ( OUT, "$(RootIntDir)\\include ; ");
173 fprintf ( OUT, "$(RootIntDir)\\include\\reactos ; ");
174
175 if ( !use_ros_headers )
176 {
177 // Add WDK or PSDK paths, if user provides them
178 if (getenv ( "BASEDIR" ) != NULL)
179 {
180 string WdkBase = getenv ( "BASEDIR" );
181 fprintf ( OUT, "%s\\inc\\api ; ", WdkBase.c_str());
182 fprintf ( OUT, "%s\\inc\\crt ; ", WdkBase.c_str());
183 fprintf ( OUT, "%s\\inc\\ddk ; ", WdkBase.c_str());
184 }
185 }
186 fprintf ( OUT, "\"\r\n");
187 fprintf ( OUT, "\t\tPerformEnvironmentSet=\"true\"\r\n");
188 fprintf( OUT, "\t/>\r\n");
189 }
190
191 void
192 VSPropsMaker::_generate_global_definitions()
193 {
194 fprintf ( OUT, "\t<UserMacro\r\n");
195 fprintf ( OUT, "\t\tName=\"globalDefines\"\r\n");
196 fprintf ( OUT, "\t\tValue=\"");
197
198 // Always add _CRT_SECURE_NO_WARNINGS to disable warnings about not
199 // using the safe functions introduced in MSVC8.
200 fprintf ( OUT, "_CRT_SECURE_NO_WARNINGS ; ") ;
201
202 if ( debug )
203 {
204 fprintf ( OUT, "_DEBUG ; ");
205 }
206
207 if ( !use_ros_headers )
208 {
209 // this is a define in MinGW w32api, but not Microsoft's headers
210 fprintf ( OUT, "STDCALL=__stdcall ; ");
211 }
212
213 const IfableData& data = m_ProjectNode->non_if_data;
214 const vector<Define*>& defs = data.defines;
215 size_t i;
216
217 for ( i = 0; i < defs.size(); i++ )
218 {
219 if ( defs[i]->backend != "" && defs[i]->backend != "msvc" )
220 continue;
221
222 if ( defs[i]->value != "" )
223 fprintf ( OUT, "%s=%s ; ",defs[i]->name.c_str(), defs[i]->value.c_str());
224 else
225 fprintf ( OUT, "%s ; ", defs[i]->name.c_str());
226 }
227
228 fprintf ( OUT, "\"\r\n");
229 fprintf ( OUT, "\t\tPerformEnvironmentSet=\"true\"\r\n");
230 fprintf( OUT, "\t/>\r\n");
231 }
232
233 void
234 VSPropsMaker::_generate_footer()
235 {
236 fprintf ( OUT, "</VisualStudioPropertySheet>\r\n");
237 }
238
239
240 void
241 VSPropsMaker::_generate_props ( std::string solution_version,
242 std::string studio_version )
243 {
244 _generate_header();
245 _generate_tools_defaults();
246
247 string srcdir = Environment::GetSourcePath();
248 string intdir = Environment::GetIntermediatePath ();
249 string outdir = Environment::GetOutputPath ();
250 string rosbedir = Environment::GetVariable("_ROSBE_BASEDIR");
251
252 if ( intdir == "obj-i386" )
253 intdir = srcdir + "\\obj-i386"; /* append relative dir from project dir */
254
255 if ( outdir == "output-i386" )
256 outdir = srcdir + "\\output-i386";
257
258 //Generate global macros
259 _generate_macro("RootSrcDir", srcdir, true);
260 _generate_macro("RootOutDir", outdir, true);
261 _generate_macro("RootIntDir", intdir, true);
262 _generate_macro("Tools", "$(RootOutDir)\\tools", true);
263 _generate_macro("RosBE", rosbedir, true);
264
265 _generate_global_includes();
266 _generate_global_definitions();
267 _generate_footer();
268 }