2 * Copyright (C) 2002 Patrik Stridvall
3 * Copyright (C) 2005 Royce Mitchell III
4 * Copyright (C) 2006 Hervé Poussineau
5 * Copyright (C) 2006 Christoph von Wittich
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #pragma warning ( disable : 4786 )
38 typedef set
<string
> StringSet
;
44 MSVCConfiguration::MSVCConfiguration ( const OptimizationType optimization
, const HeadersType headers
, const std::string
&name
)
46 this->optimization
= optimization
;
47 this->headers
= headers
;
52 std::string headers_name
;
53 if ( headers
== MSVCHeaders
)
56 headers_name
= " - Wine headers";
57 if ( optimization
== Debug
)
58 this->name
= "Debug" + headers_name
;
59 else if ( optimization
== Release
)
60 this->name
= "Release" + headers_name
;
61 else if ( optimization
== Speed
)
62 this->name
= "Speed" + headers_name
;
64 this->name
= "Unknown" + headers_name
;
69 MSVCBackend::_generate_vcproj ( const Module
& module
)
73 string vcproj_file
= VcprojFileName(module
);
75 string username
= getenv ( "USERNAME" );
76 string computername
= getenv ( "COMPUTERNAME" );
77 string vcproj_file_user
= "";
79 if ((computername
!= "") && (username
!= ""))
80 vcproj_file_user
= vcproj_file
+ "." + computername
+ "." + username
+ ".user";
82 printf ( "Creating MSVC.NET project: '%s'\n", vcproj_file
.c_str() );
83 FILE* OUT
= fopen ( vcproj_file
.c_str(), "wb" );
85 vector
<string
> imports
;
86 string module_type
= GetExtension(module
.GetTargetName());
87 bool lib
= (module
.type
== ObjectLibrary
) || (module
.type
== RpcClient
) ||(module
.type
== RpcServer
) || (module_type
== ".lib") || (module_type
== ".a");
88 bool dll
= (module_type
== ".dll") || (module_type
== ".cpl");
89 bool exe
= (module_type
== ".exe") || (module_type
== ".scr");
90 bool sys
= (module_type
== ".sys");
92 string path_basedir
= module
.GetPathToBaseDir ();
93 string intenv
= Environment::GetIntermediatePath ();
94 string outenv
= Environment::GetOutputPath ();
100 if ( intenv
== "obj-i386" )
101 intdir
= path_basedir
+ "obj-i386"; /* append relative dir from project dir */
105 if ( outenv
== "output-i386" )
106 outdir
= path_basedir
+ "output-i386";
110 if ( configuration
.UseVSVersionInPath
)
112 vcdir
= "\\" + _get_vc_dir();
114 // TODO FIXME - need more checks here for 'sys' and possibly 'drv'?
116 bool console
= exe
&& (module
.type
== Win32CUI
);
117 bool include_idl
= false;
119 string vcproj_path
= module
.GetBasePath();
120 vector
<string
> source_files
, resource_files
, includes
, includes_wine
, libraries
;
121 StringSet common_defines
;
122 vector
<const IfableData
*> ifs_list
;
123 ifs_list
.push_back ( &module
.project
.non_if_data
);
124 ifs_list
.push_back ( &module
.non_if_data
);
128 while ( ifs_list
.size() )
130 const IfableData
& data
= *ifs_list
.back();
132 for ( i
= 0; i
< data
.ifs
.size(); i
++ )
134 const Property
* property
= _lookup_property( module
, data
.ifs
[i
]->property
);
135 if ( property
!= NULL
)
137 if ( data
.ifs
[i
]->value
== property
->value
&& data
.ifs
[i
]->negated
== false ||
138 data
.ifs
[i
]->value
!= property
->value
&& data
.ifs
[i
]->negated
)
139 ifs_list
.push_back ( &data
.ifs
[i
]->data
);
142 const vector
<File
*>& files
= data
.files
;
143 for ( i
= 0; i
< files
.size(); i
++ )
145 // TODO FIXME - do we want the full path of the file here?
146 string file
= string(".") + &files
[i
]->name
[vcproj_path
.size()];
148 if ( !stricmp ( Right(file
,3).c_str(), ".rc" ) )
149 resource_files
.push_back ( file
);
151 source_files
.push_back ( file
);
153 const vector
<Include
*>& incs
= data
.includes
;
154 for ( i
= 0; i
< incs
.size(); i
++ )
156 string path
= Path::RelativeFromDirectory (
158 module
.GetBasePath() );
159 if ( module
.type
!= RpcServer
&& module
.type
!= RpcClient
)
161 if ( path
.find ("/include/reactos/idl") != string::npos
)
167 // add to another list win32api and include/wine directories
168 if ( !strncmp(incs
[i
]->directory
.c_str(), "include\\ddk", 11 ) ||
169 !strncmp(incs
[i
]->directory
.c_str(), "include\\crt", 11 ) ||
170 !strncmp(incs
[i
]->directory
.c_str(), "include\\GL", 10 ) ||
171 !strncmp(incs
[i
]->directory
.c_str(), "include\\ddk", 11 ) ||
172 !strncmp(incs
[i
]->directory
.c_str(), "include\\psdk", 12 ) ||
173 !strncmp(incs
[i
]->directory
.c_str(), "include\\reactos\\wine", 20 ) )
175 includes_wine
.push_back ( path
);
179 includes
.push_back ( path
);
182 const vector
<Library
*>& libs
= data
.libraries
;
183 for ( i
= 0; i
< libs
.size(); i
++ )
185 string libpath
= outdir
+ "\\" + libs
[i
]->importedModule
->GetBasePath() + "\\" + _get_vc_dir() + "\\---\\" + libs
[i
]->name
+ ".lib";
186 libraries
.push_back ( libpath
);
188 const vector
<Define
*>& defs
= data
.defines
;
189 for ( i
= 0; i
< defs
.size(); i
++ )
191 if ( defs
[i
]->value
[0] )
192 common_defines
.insert( defs
[i
]->name
+ "=" + defs
[i
]->value
);
194 common_defines
.insert( defs
[i
]->name
);
196 for ( i
= 0; i
< data
.properties
.size(); i
++ )
198 Property
& prop
= *data
.properties
[i
];
199 if ( strstr ( module
.baseaddress
.c_str(), prop
.name
.c_str() ) )
200 baseaddr
= prop
.value
;
204 vector
<string
> header_files
;
206 string include_string
;
208 fprintf ( OUT
, "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\r\n" );
209 fprintf ( OUT
, "<VisualStudioProject\r\n" );
210 fprintf ( OUT
, "\tProjectType=\"Visual C++\"\r\n" );
212 if (configuration
.VSProjectVersion
.empty())
213 configuration
.VSProjectVersion
= MS_VS_DEF_VERSION
;
215 fprintf ( OUT
, "\tVersion=\"%s\"\r\n", configuration
.VSProjectVersion
.c_str() );
216 fprintf ( OUT
, "\tName=\"%s\"\r\n", module
.name
.c_str() );
217 fprintf ( OUT
, "\tProjectGUID=\"%s\"\r\n", module
.guid
.c_str() );
218 fprintf ( OUT
, "\tKeyword=\"Win32Proj\">\r\n" );
220 fprintf ( OUT
, "\t<Platforms>\r\n" );
221 fprintf ( OUT
, "\t\t<Platform\r\n" );
222 fprintf ( OUT
, "\t\t\tName=\"Win32\"/>\r\n" );
223 fprintf ( OUT
, "\t</Platforms>\r\n" );
225 //fprintf ( OUT, "\t<ToolFiles>\r\n" );
226 //fprintf ( OUT, "\t\t<ToolFile\r\n" );
228 //string path = Path::RelativeFromDirectory ( ProjectNode.name, module.GetBasePath() );
229 //path.erase(path.find(ProjectNode.name, 0), ProjectNode.name.size() + 1);
231 //fprintf ( OUT, "\t\t\tRelativePath=\"%sgccasm.rules\"/>\r\n", path.c_str() );
232 //fprintf ( OUT, "\t</ToolFiles>\r\n" );
236 std::string output_dir
;
238 fprintf ( OUT
, "\t<Configurations>\r\n" );
239 for ( size_t icfg
= 0; icfg
< m_configurations
.size(); icfg
++ )
241 const MSVCConfiguration
& cfg
= *m_configurations
[icfg
];
243 bool debug
= ( cfg
.optimization
== Debug
);
244 bool release
= ( cfg
.optimization
== Release
);
245 bool speed
= ( cfg
.optimization
== Speed
);
247 fprintf ( OUT
, "\t\t<Configuration\r\n" );
248 fprintf ( OUT
, "\t\t\tName=\"%s|Win32\"\r\n", cfg
.name
.c_str() );
250 if ( configuration
.UseConfigurationInPath
)
252 fprintf ( OUT
, "\t\t\tOutputDirectory=\"%s\\%s%s\\%s\"\r\n", outdir
.c_str (), module
.GetBasePath ().c_str (), vcdir
.c_str (), cfg
.name
.c_str() );
253 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir
.c_str (), module
.GetBasePath ().c_str (), vcdir
.c_str (), cfg
.name
.c_str() );
257 fprintf ( OUT
, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir
.c_str (), module
.GetBasePath ().c_str (), vcdir
.c_str () );
258 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir
.c_str (), module
.GetBasePath ().c_str (), vcdir
.c_str () );
261 fprintf ( OUT
, "\t\t\tConfigurationType=\"%d\"\r\n", exe
? 1 : dll
? 2 : lib
? 4 : -1 );
262 fprintf ( OUT
, "\t\t\tCharacterSet=\"2\">\r\n" );
264 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
265 fprintf ( OUT
, "\t\t\t\tName=\"VCCLCompilerTool\"\r\n" );
266 fprintf ( OUT
, "\t\t\t\tOptimization=\"%d\"\r\n", release
? 2 : 0 );
268 fprintf ( OUT
, "\t\t\t\tAdditionalIncludeDirectories=\"" );
269 bool multiple_includes
= false;
270 fprintf ( OUT
, "./;" );
271 for ( i
= 0; i
< includes
.size(); i
++ )
273 const std::string
& include
= includes
[i
];
274 if ( strcmp ( include
.c_str(), "." ) )
276 if ( multiple_includes
)
277 fprintf ( OUT
, ";" );
278 fprintf ( OUT
, "%s", include
.c_str() );
279 include_string
+= " /I " + include
;
280 multiple_includes
= true;
285 if ( multiple_includes
)
286 fprintf ( OUT
, ";" );
288 if ( configuration
.UseConfigurationInPath
)
290 fprintf ( OUT
, "%s\\include\\reactos\\idl%s\\%s\r\n", intdir
.c_str (), vcdir
.c_str (), cfg
.name
.c_str() );
294 fprintf ( OUT
, "%s\\include\\reactos\\idl\r\n", intdir
.c_str () );
297 if ( cfg
.headers
== WineHeaders
)
299 for ( i
= 0; i
< includes_wine
.size(); i
++ )
301 const std::string
& include
= includes_wine
[i
];
302 if ( multiple_includes
)
303 fprintf ( OUT
, ";" );
304 fprintf ( OUT
, "%s", include
.c_str() );
305 //include_string += " /I " + include;
306 multiple_includes
= true;
309 fprintf ( OUT
, "\"\r\n" );
311 StringSet defines
= common_defines
;
315 defines
.insert ( "_DEBUG" );
318 if ( cfg
.headers
== MSVCHeaders
)
320 // this is a define in MinGW w32api, but not Microsoft's headers
321 defines
.insert ( "STDCALL=__stdcall" );
326 defines
.insert ( "_LIB" );
330 defines
.insert ( "_WINDOWS" );
331 defines
.insert ( "_USRDLL" );
334 fprintf ( OUT
, "\t\t\t\tPreprocessorDefinitions=\"" );
335 for ( StringSet::iterator it1
=defines
.begin(); it1
!=defines
.end(); it1
++ )
338 fprintf ( OUT
, ";" );
340 string unescaped
= *it1
;
341 defines
.erase(unescaped
);
342 const string
& escaped
= _replace_str(unescaped
, "\"",""");
344 defines
.insert(escaped
);
345 fprintf ( OUT
, "%s", escaped
.c_str() );
347 fprintf ( OUT
, "\"\r\n" );
348 fprintf ( OUT
, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h");
349 fprintf ( OUT
, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed
? "FALSE" : "TRUE" );
350 fprintf ( OUT
, "\t\t\t\tBasicRuntimeChecks=\"%s\"\r\n", sys
? 0 : (debug
? "3" : "0") );
351 fprintf ( OUT
, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug
? 1 : 5 ); // 1=/MTd 5=/MT
352 fprintf ( OUT
, "\t\t\t\tBufferSecurityCheck=\"%s\"\r\n", sys
? "FALSE" : (debug
? "TRUE" : "FALSE" ));
353 fprintf ( OUT
, "\t\t\t\tEnableFunctionLevelLinking=\"%s\"\r\n", debug
? "TRUE" : "FALSE" );
355 if ( module
.pch
!= NULL
)
357 fprintf ( OUT
, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" );
358 string pch_path
= Path::RelativeFromDirectory (
359 module
.pch
->file
.name
,
360 module
.GetBasePath() );
361 string::size_type pos
= pch_path
.find_last_of ("/");
362 if ( pos
!= string::npos
)
363 pch_path
.erase(0, pos
+1);
364 fprintf ( OUT
, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path
.c_str() );
368 fprintf ( OUT
, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" );
371 fprintf ( OUT
, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release
? "FALSE" : "FALSE");
374 fprintf ( OUT
, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" );
375 fprintf ( OUT
, "\t\t\t\tStringPooling=\"true\"\r\n" );
378 fprintf ( OUT
, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed
? "0" : "3" );
379 fprintf ( OUT
, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE");
380 if ( !module
.cplusplus
)
381 fprintf ( OUT
, "\t\t\t\tCompileAs=\"1\"\r\n" );
383 if ( module
.type
== Win32CUI
|| module
.type
== Win32GUI
)
385 fprintf ( OUT
, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 ); // 0=__cdecl
389 fprintf ( OUT
, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 ); // 2=__stdcall
392 fprintf ( OUT
, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed
? "0" : release
? "3": "4"); // 3=/Zi 4=ZI
394 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
395 fprintf ( OUT
, "\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n" );
399 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
400 fprintf ( OUT
, "\t\t\t\tName=\"VCLibrarianTool\"\r\n" );
401 fprintf ( OUT
, "\t\t\t\tOutputFile=\"$(OutDir)/%s.lib\"/>\r\n", module
.name
.c_str() );
405 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
406 fprintf ( OUT
, "\t\t\t\tName=\"VCLinkerTool\"\r\n" );
407 if (module
.GetEntryPoint(false) == "0")
408 fprintf ( OUT
, "AdditionalOptions=\"/noentry\"" );
410 if (module
.importLibrary
!= NULL
)
411 fprintf ( OUT
, "\t\t\t\tModuleDefinitionFile=\"%s\"\r\n", module
.importLibrary
->definition
.c_str());
412 fprintf ( OUT
, "\t\t\t\tAdditionalDependencies=\"" );
413 bool use_msvcrt_lib
= false;
414 for ( i
= 0; i
< libraries
.size(); i
++ )
417 fprintf ( OUT
, " " );
418 string libpath
= libraries
[i
].c_str();
419 libpath
= libpath
.erase (0, libpath
.find_last_of ("\\") + 1 );
420 if ( libpath
== "msvcrt.lib" )
422 use_msvcrt_lib
= true;
424 fprintf ( OUT
, "%s", libpath
.c_str() );
426 fprintf ( OUT
, "\"\r\n" );
428 fprintf ( OUT
, "\t\t\t\tAdditionalLibraryDirectories=\"" );
429 for (i
= 0; i
< libraries
.size (); i
++)
432 fprintf ( OUT
, ";" );
434 string libpath
= libraries
[i
].c_str();
435 libpath
.replace (libpath
.find("---"), 3, cfg
.name
);
436 libpath
= libpath
.substr (0, libpath
.find_last_of ("\\") );
437 fprintf ( OUT
, "%s", libpath
.c_str() );
439 fprintf ( OUT
, "\"\r\n" );
441 fprintf ( OUT
, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module
.name
.c_str(), module_type
.c_str() );
442 fprintf ( OUT
, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug
? 2 : 1 );
443 fprintf ( OUT
, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed
? "FALSE" : "TRUE" );
444 fprintf ( OUT
, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release
? 0 : 0); // whole program optimization
447 fprintf ( OUT
, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module
.name
.c_str() );
451 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
452 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
453 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
454 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
455 fprintf ( OUT
, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
456 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module
.GetEntryPoint(false) == "" ? "DriverEntry" : module
.GetEntryPoint(false).c_str ());
457 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
== "" ? "0x10000" : baseaddr
.c_str ());
461 if ( module
.type
== Kernel
)
463 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" );
464 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
465 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
466 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
467 fprintf ( OUT
, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
468 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" );
469 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
.c_str ());
471 else if ( module
.type
== NativeCUI
)
473 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" );
474 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 );
475 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
476 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
477 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" );
478 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
.c_str ());
480 else if ( module
.type
== Win32CUI
|| module
.type
== Win32GUI
|| module
.type
== Win32SCR
)
482 if ( use_msvcrt_lib
)
484 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
486 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", console
? 1 : 2 );
491 if (module
.GetEntryPoint(false) == "0")
492 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
495 // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12
497 if (module
.GetEntryPoint(false) == "DllMain@12")
498 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
500 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module
.GetEntryPoint(false).c_str ());
502 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
== "" ? "0x40000" : baseaddr
.c_str ());
503 if ( use_msvcrt_lib
)
505 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
508 fprintf ( OUT
, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 );
511 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
512 fprintf ( OUT
, "\t\t\t\tName=\"VCResourceCompilerTool\"\r\n" );
513 fprintf ( OUT
, "\t\t\t\tAdditionalIncludeDirectories=\"" );
514 multiple_includes
= false;
515 fprintf ( OUT
, "./;" );
516 for ( i
= 0; i
< includes
.size(); i
++ )
518 const std::string
& include
= includes
[i
];
519 if ( strcmp ( include
.c_str(), "." ) )
521 if ( multiple_includes
)
522 fprintf ( OUT
, ";" );
523 fprintf ( OUT
, "%s", include
.c_str() );
524 multiple_includes
= true;
527 if ( cfg
.headers
== WineHeaders
)
529 for ( i
= 0; i
< includes_wine
.size(); i
++ )
531 const std::string
& include
= includes_wine
[i
];
532 if ( multiple_includes
)
533 fprintf ( OUT
, ";" );
534 fprintf ( OUT
, "%s", include
.c_str() );
535 multiple_includes
= true;
538 fprintf ( OUT
, "\"/>\r\n " );
540 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
541 fprintf ( OUT
, "\t\t\t\tName=\"VCMIDLTool\"/>\r\n" );
542 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
543 if (configuration
.VSProjectVersion
== "8.00")
545 fprintf ( OUT
, "\t\t\t\tName=\"VCManifestTool\"\r\n" );
546 fprintf ( OUT
, "\t\t\t\tEmbedManifest=\"false\"/>\r\n" );
548 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
549 fprintf ( OUT
, "\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n" );
550 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
551 fprintf ( OUT
, "\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n" );
552 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
553 fprintf ( OUT
, "\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n" );
554 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
555 fprintf ( OUT
, "\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n" );
556 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
557 fprintf ( OUT
, "\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n" );
558 fprintf ( OUT
, "\t\t</Configuration>\r\n" );
562 fprintf ( OUT
, "\t</Configurations>\r\n" );
564 fprintf ( OUT
, "\t<Files>\r\n" );
567 fprintf ( OUT
, "\t\t<Filter\r\n" );
568 fprintf ( OUT
, "\t\t\tName=\"Source Files\"\r\n" );
569 fprintf ( OUT
, "\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;S\">\r\n" );
570 for ( size_t isrcfile
= 0; isrcfile
< source_files
.size(); isrcfile
++ )
572 string source_file
= DosSeparator(source_files
[isrcfile
]);
573 fprintf ( OUT
, "\t\t\t<File\r\n" );
574 fprintf ( OUT
, "\t\t\t\tRelativePath=\"%s\">\r\n", source_file
.c_str() );
576 for ( size_t iconfig
= 0; iconfig
< m_configurations
.size(); iconfig
++ )
578 const MSVCConfiguration
& config
= *m_configurations
[iconfig
];
580 if (( isrcfile
== 0 ) && ( module
.pch
!= NULL
))
582 /* little hack to speed up PCH */
583 fprintf ( OUT
, "\t\t\t\t<FileConfiguration\r\n" );
584 fprintf ( OUT
, "\t\t\t\t\tName=\"" );
585 fprintf ( OUT
, config
.name
.c_str() );
586 fprintf ( OUT
, "|Win32\">\r\n" );
587 fprintf ( OUT
, "\t\t\t\t\t<Tool\r\n" );
588 fprintf ( OUT
, "\t\t\t\t\t\tName=\"VCCLCompilerTool\"\r\n" );
589 fprintf ( OUT
, "\t\t\t\t\t\tUsePrecompiledHeader=\"1\"/>\r\n" );
590 fprintf ( OUT
, "\t\t\t\t</FileConfiguration>\r\n" );
593 //if (configuration.VSProjectVersion < "8.00") {
594 if ((source_file
.find(".idl") != string::npos
) || ((source_file
.find(".asm") != string::npos
|| tolower(source_file
.at(source_file
.size() - 1)) == 's')))
596 fprintf ( OUT
, "\t\t\t\t<FileConfiguration\r\n" );
597 fprintf ( OUT
, "\t\t\t\t\tName=\"" );
598 fprintf ( OUT
, config
.name
.c_str() );
599 fprintf ( OUT
, "|Win32\">\r\n" );
600 fprintf ( OUT
, "\t\t\t\t\t<Tool\r\n" );
601 if (source_file
.find(".idl") != string::npos
)
603 string src
= source_file
.substr (0, source_file
.find(".idl"));
605 if ( src
.find (".\\") != string::npos
)
608 fprintf ( OUT
, "\t\t\t\t\t\tName=\"VCCustomBuildTool\"\r\n" );
610 if ( module
.type
== RpcClient
)
612 fprintf ( OUT
, "\t\t\t\t\t\tCommandLine=\"midl.exe /cstub %s_c.c /header %s_c.h /server none "$(InputPath)" /out "$(IntDir)"", src
.c_str (), src
.c_str () );
613 fprintf ( OUT
, "
");
614 fprintf ( OUT
, "cl.exe /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WIN32_WINNT=0x502" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Fo"$(IntDir)\\%s.obj" /W3 /c /Wp64 /ZI /TC "$(IntDir)\\%s_c.c" /nologo /errorReport:prompt", src
.c_str (), src
.c_str () );
618 fprintf ( OUT
, "\t\t\t\t\t\tCommandLine=\"midl.exe /sstub %s_s.c /header %s_s.h /client none "$(InputPath)" /out "$(IntDir)"", src
.c_str (), src
.c_str () );
619 fprintf ( OUT
, "
");
620 fprintf ( OUT
, "cl.exe /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_WIN32_WINNT=0x502" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Fo"$(IntDir)\\%s.obj" /W3 /c /Wp64 /ZI /TC "$(IntDir)\\%s_s.c" /nologo /errorReport:prompt", src
.c_str (), src
.c_str () );
623 fprintf ( OUT
, "
");
624 fprintf ( OUT
, "lib.exe /OUT:"$(OutDir)\\%s.lib" "$(IntDir)\\%s.obj"
\"\r\n", module
.name
.c_str (), src
.c_str () );
625 fprintf ( OUT
, "\t\t\t\t\t\tOutputs=\"$(IntDir)\\$(InputName).obj\"/>\r\n" );
627 else if ((source_file
.find(".asm") != string::npos
))
629 fprintf ( OUT
, "\t\t\t\t\t\tName=\"VCCustomBuildTool\"\r\n" );
630 fprintf ( OUT
, "\t\t\t\t\t\tCommandLine=\"nasmw $(InputPath) -f coff -o "$(OutDir)\\$(InputName).obj"\"\r\n");
631 fprintf ( OUT
, "\t\t\t\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n" );
633 else if ((tolower(source_file
.at(source_file
.size() - 1)) == 's'))
635 fprintf ( OUT
, "\t\t\t\t\t\tName=\"VCCustomBuildTool\"\r\n" );
636 fprintf ( OUT
, "\t\t\t\t\t\tCommandLine=\"cl /E "$(InputPath)" %s /D__ASM__ | as -o "$(OutDir)\\$(InputName).obj"\"\r\n",include_string
.c_str() );
637 fprintf ( OUT
, "\t\t\t\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n" );
639 fprintf ( OUT
, "\t\t\t\t</FileConfiguration>\r\n" );
643 fprintf ( OUT
, "\t\t\t</File>\r\n" );
645 fprintf ( OUT
, "\t\t</Filter>\r\n" );
648 fprintf ( OUT
, "\t\t<Filter\r\n" );
649 fprintf ( OUT
, "\t\t\tName=\"Header Files\"\r\n" );
650 fprintf ( OUT
, "\t\t\tFilter=\"h;hpp;hxx;hm;inl\">\r\n" );
651 for ( i
= 0; i
< header_files
.size(); i
++ )
653 const string
& header_file
= header_files
[i
];
654 fprintf ( OUT
, "\t\t\t<File\r\n" );
655 fprintf ( OUT
, "\t\t\t\tRelativePath=\"%s\">\r\n", header_file
.c_str() );
656 fprintf ( OUT
, "\t\t\t</File>\r\n" );
658 fprintf ( OUT
, "\t\t</Filter>\r\n" );
661 fprintf ( OUT
, "\t\t<Filter\r\n" );
662 fprintf ( OUT
, "\t\t\tName=\"Resource Files\"\r\n" );
663 fprintf ( OUT
, "\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\">\r\n" );
664 for ( i
= 0; i
< resource_files
.size(); i
++ )
666 const string
& resource_file
= resource_files
[i
];
667 fprintf ( OUT
, "\t\t\t<File\r\n" );
668 fprintf ( OUT
, "\t\t\t\tRelativePath=\"%s\">\r\n", resource_file
.c_str() );
669 fprintf ( OUT
, "\t\t\t</File>\r\n" );
671 fprintf ( OUT
, "\t\t</Filter>\r\n" );
673 fprintf ( OUT
, "\t</Files>\r\n" );
674 fprintf ( OUT
, "\t<Globals>\r\n" );
675 fprintf ( OUT
, "\t</Globals>\r\n" );
676 fprintf ( OUT
, "</VisualStudioProject>\r\n" );
679 /* User configuration file */
680 if (vcproj_file_user
!= "")
682 OUT
= fopen ( vcproj_file_user
.c_str(), "wb" );
683 fprintf ( OUT
, "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\r\n" );
684 fprintf ( OUT
, "<VisualStudioUserFile\r\n" );
685 fprintf ( OUT
, "\tProjectType=\"Visual C++\"\r\n" );
686 fprintf ( OUT
, "\tVersion=\"%s\"\r\n", configuration
.VSProjectVersion
.c_str() );
687 fprintf ( OUT
, "\tShowAllFiles=\"false\"\r\n" );
688 fprintf ( OUT
, "\t>\r\n" );
690 fprintf ( OUT
, "\t<Configurations>\r\n" );
691 for ( size_t icfg
= 0; icfg
< m_configurations
.size(); icfg
++ )
693 const MSVCConfiguration
& cfg
= *m_configurations
[icfg
];
694 fprintf ( OUT
, "\t\t<Configuration\r\n" );
695 fprintf ( OUT
, "\t\t\tName=\"%s|Win32\"\r\n", cfg
.name
.c_str() );
696 fprintf ( OUT
, "\t\t\t>\r\n" );
697 fprintf ( OUT
, "\t\t\t<DebugSettings\r\n" );
698 if ( module_type
== ".cpl" )
700 fprintf ( OUT
, "\t\t\t\tCommand=\"rundll32.exe\"\r\n" );
701 fprintf ( OUT
, "\t\t\t\tCommandArguments=\" shell32,Control_RunDLL "$(TargetPath)",@\"\r\n" );
705 fprintf ( OUT
, "\t\t\t\tCommand=\"$(TargetPath)\"\r\n" );
706 fprintf ( OUT
, "\t\t\t\tCommandArguments=\"\"\r\n" );
708 fprintf ( OUT
, "\t\t\t\tAttach=\"false\"\r\n" );
709 fprintf ( OUT
, "\t\t\t\tDebuggerType=\"3\"\r\n" );
710 fprintf ( OUT
, "\t\t\t\tRemote=\"1\"\r\n" );
711 string remote_machine
= "\t\t\t\tRemoteMachine=\"" + computername
+ "\"\r\n";
712 fprintf ( OUT
, remote_machine
.c_str() );
713 fprintf ( OUT
, "\t\t\t\tRemoteCommand=\"\"\r\n" );
714 fprintf ( OUT
, "\t\t\t\tHttpUrl=\"\"\r\n" );
715 fprintf ( OUT
, "\t\t\t\tPDBPath=\"\"\r\n" );
716 fprintf ( OUT
, "\t\t\t\tSQLDebugging=\"\"\r\n" );
717 fprintf ( OUT
, "\t\t\t\tEnvironment=\"\"\r\n" );
718 fprintf ( OUT
, "\t\t\t\tEnvironmentMerge=\"true\"\r\n" );
719 fprintf ( OUT
, "\t\t\t\tDebuggerFlavor=\"\"\r\n" );
720 fprintf ( OUT
, "\t\t\t\tMPIRunCommand=\"\"\r\n" );
721 fprintf ( OUT
, "\t\t\t\tMPIRunArguments=\"\"\r\n" );
722 fprintf ( OUT
, "\t\t\t\tMPIRunWorkingDirectory=\"\"\r\n" );
723 fprintf ( OUT
, "\t\t\t\tApplicationCommand=\"\"\r\n" );
724 fprintf ( OUT
, "\t\t\t\tApplicationArguments=\"\"\r\n" );
725 fprintf ( OUT
, "\t\t\t\tShimCommand=\"\"\r\n" );
726 fprintf ( OUT
, "\t\t\t\tMPIAcceptMode=\"\"\r\n" );
727 fprintf ( OUT
, "\t\t\t\tMPIAcceptFilter=\"\"\r\n" );
728 fprintf ( OUT
, "\t\t\t/>\r\n" );
729 fprintf ( OUT
, "\t\t</Configuration>\r\n" );
731 fprintf ( OUT
, "\t</Configurations>\r\n" );
732 fprintf ( OUT
, "</VisualStudioUserFile>\r\n" );
739 MSVCBackend::_replace_str(std::string string1
, const std::string
&find_str
, const std::string
&replace_str
)
741 std::string::size_type pos
= string1
.find(find_str
, 0);
742 int intLen
= find_str
.length();
744 while(std::string::npos
!= pos
)
746 string1
.replace(pos
, intLen
, replace_str
);
747 pos
= string1
.find(find_str
, intLen
+ pos
);
754 MSVCBackend::_get_solution_verion ( void )
758 if (configuration
.VSProjectVersion
.empty())
759 configuration
.VSProjectVersion
= MS_VS_DEF_VERSION
;
761 if (configuration
.VSProjectVersion
== "7.00")
764 if (configuration
.VSProjectVersion
== "7.10")
767 if (configuration
.VSProjectVersion
== "8.00")
774 MSVCBackend::_generate_sln_header ( FILE* OUT
)
776 fprintf ( OUT
, "Microsoft Visual Studio Solution File, Format Version %s\r\n", _get_solution_verion().c_str() );
777 fprintf ( OUT
, "# Visual Studio 2005\r\n" );
778 fprintf ( OUT
, "\r\n" );
783 MSVCBackend::_generate_sln_project (
785 const Module
& module
,
786 std::string vcproj_file
,
787 std::string sln_guid
,
788 std::string vcproj_guid
,
789 const std::vector
<Library
*>& libraries
)
791 vcproj_file
= DosSeparator ( std::string(".\\") + vcproj_file
);
793 fprintf ( OUT
, "Project(\"%s\") = \"%s\", \"%s\", \"%s\"\r\n", sln_guid
.c_str() , module
.name
.c_str(), vcproj_file
.c_str(), vcproj_guid
.c_str() );
795 //FIXME: only omit ProjectDependencies in VS 2005 when there are no dependencies
796 //NOTE: VS 2002 do not use ProjectSection; it uses GlobalSection instead
797 if ((configuration
.VSProjectVersion
== "7.10") || (libraries
.size() > 0)) {
798 fprintf ( OUT
, "\tProjectSection(ProjectDependencies) = postProject\r\n" );
799 for ( size_t i
= 0; i
< libraries
.size(); i
++ )
801 const Module
& module
= *libraries
[i
]->importedModule
;
802 fprintf ( OUT
, "\t\t%s = %s\r\n", module
.guid
.c_str(), module
.guid
.c_str() );
804 fprintf ( OUT
, "\tEndProjectSection\r\n" );
807 fprintf ( OUT
, "EndProject\r\n" );
812 MSVCBackend::_generate_sln_footer ( FILE* OUT
)
814 fprintf ( OUT
, "Global\r\n" );
815 fprintf ( OUT
, "\tGlobalSection(SolutionConfiguration) = preSolution\r\n" );
816 for ( size_t i
= 0; i
< m_configurations
.size(); i
++ )
817 fprintf ( OUT
, "\t\t%s = %s\r\n", m_configurations
[i
]->name
.c_str(), m_configurations
[i
]->name
.c_str() );
818 fprintf ( OUT
, "\tEndGlobalSection\r\n" );
819 fprintf ( OUT
, "\tGlobalSection(ProjectConfiguration) = postSolution\r\n" );
820 for ( size_t i
= 0; i
< ProjectNode
.modules
.size(); i
++ )
822 Module
& module
= *ProjectNode
.modules
[i
];
823 std::string guid
= module
.guid
;
824 _generate_sln_configurations ( OUT
, guid
.c_str() );
826 fprintf ( OUT
, "\tEndGlobalSection\r\n" );
827 fprintf ( OUT
, "\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n" );
828 fprintf ( OUT
, "\tEndGlobalSection\r\n" );
829 fprintf ( OUT
, "\tGlobalSection(ExtensibilityAddIns) = postSolution\r\n" );
830 fprintf ( OUT
, "\tEndGlobalSection\r\n" );
832 if (configuration
.VSProjectVersion
== "7.00") {
833 fprintf ( OUT
, "\tGlobalSection(ProjectDependencies) = postSolution\r\n" );
834 //FIXME: Add dependencies for VS 2002
835 fprintf ( OUT
, "\tEndGlobalSection\r\n" );
838 if (configuration
.VSProjectVersion
== "8.00") {
839 fprintf ( OUT
, "\tGlobalSection(SolutionProperties) = preSolution\r\n" );
840 fprintf ( OUT
, "\t\tHideSolutionNode = FALSE\r\n" );
841 fprintf ( OUT
, "\tEndGlobalSection\r\n" );
844 fprintf ( OUT
, "EndGlobal\r\n" );
845 fprintf ( OUT
, "\r\n" );
850 MSVCBackend::_generate_sln_configurations ( FILE* OUT
, std::string vcproj_guid
)
852 for ( size_t i
= 0; i
< m_configurations
.size (); i
++)
854 const MSVCConfiguration
& cfg
= *m_configurations
[i
];
855 fprintf ( OUT
, "\t\t%s.%s|Win32.ActiveCfg = %s|Win32\r\n", vcproj_guid
.c_str(), cfg
.name
.c_str(), cfg
.name
.c_str() );
856 fprintf ( OUT
, "\t\t%s.%s|Win32.Build.0 = %s|Win32\r\n", vcproj_guid
.c_str(), cfg
.name
.c_str(), cfg
.name
.c_str() );
861 MSVCBackend::_generate_sln ( FILE* OUT
)
863 string sln_guid
= "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
864 vector
<string
> guids
;
866 _generate_sln_header(OUT
);
867 // TODO FIXME - is it necessary to sort them?
868 for ( size_t i
= 0; i
< ProjectNode
.modules
.size(); i
++ )
870 Module
& module
= *ProjectNode
.modules
[i
];
872 std::string vcproj_file
= VcprojFileName ( module
);
873 _generate_sln_project ( OUT
, module
, vcproj_file
, sln_guid
, module
.guid
, module
.non_if_data
.libraries
);
875 _generate_sln_footer ( OUT
);
879 MSVCBackend::_lookup_property ( const Module
& module
, const std::string
& name
) const
881 /* Check local values */
882 for ( size_t i
= 0; i
< module
.non_if_data
.properties
.size(); i
++ )
884 const Property
& property
= *module
.non_if_data
.properties
[i
];
885 if ( property
.name
== name
)
888 // TODO FIXME - should we check local if-ed properties?
889 for ( size_t i
= 0; i
< module
.project
.non_if_data
.properties
.size(); i
++ )
891 const Property
& property
= *module
.project
.non_if_data
.properties
[i
];
892 if ( property
.name
== name
)
895 // TODO FIXME - should we check global if-ed properties?