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
6 * Copyright (C) 2009 Ged Murphy
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #pragma warning ( disable : 4786 )
42 typedef set
<string
> StringSet
;
48 struct SortFilesAscending
50 bool operator()(const string
& rhs
, const string
& lhs
)
57 VCProjMaker::VCProjMaker ( )
62 VCProjMaker::VCProjMaker ( Configuration
& buildConfig
,
63 const std::vector
<MSVCConfiguration
*>& msvc_configs
,
64 std::string filename
)
66 configuration
= buildConfig
;
67 m_configurations
= msvc_configs
;
68 vcproj_file
= filename
;
70 OUT
= fopen ( vcproj_file
.c_str(), "wb" );
74 printf ( "Could not create file '%s'.\n", vcproj_file
.c_str() );
78 VCProjMaker::~VCProjMaker()
84 VCProjMaker::_generate_proj_file ( const Module
& module
)
91 // make sure the containers are empty
96 common_defines
.clear();
98 if (getenv ( "USERNAME" ) != NULL
)
99 username
= getenv ( "USERNAME" );
100 if (getenv ( "COMPUTERNAME" ) != NULL
)
101 computername
= getenv ( "COMPUTERNAME" );
102 else if (getenv ( "HOSTNAME" ) != NULL
)
103 computername
= getenv ( "HOSTNAME" );
105 string vcproj_file_user
= "";
107 if ((computername
!= "") && (username
!= ""))
108 vcproj_file_user
= vcproj_file
+ "." + computername
+ "." + username
+ ".user";
110 printf ( "Creating MSVC project: '%s'\n", vcproj_file
.c_str() );
112 string path_basedir
= module
.GetPathToBaseDir ();
113 string intenv
= Environment::GetIntermediatePath ();
114 string outenv
= Environment::GetOutputPath ();
119 if ( intenv
== "obj-i386" )
120 intdir
= path_basedir
+ "obj-i386"; /* append relative dir from project dir */
124 if ( outenv
== "output-i386" )
125 outdir
= path_basedir
+ "output-i386";
129 if ( configuration
.UseVSVersionInPath
)
131 vcdir
= DEF_SSEP
+ _get_vc_dir();
134 bool include_idl
= false;
136 vector
<string
> source_files
, resource_files
;
137 vector
<const IfableData
*> ifs_list
;
138 ifs_list
.push_back ( &module
.project
.non_if_data
);
139 ifs_list
.push_back ( &module
.non_if_data
);
141 while ( ifs_list
.size() )
143 const IfableData
& data
= *ifs_list
.back();
145 const vector
<File
*>& files
= data
.files
;
146 for ( i
= 0; i
< files
.size(); i
++ )
148 if (files
[i
]->file
.directory
!= SourceDirectory
)
151 // We want the full path here for directory support later on
152 string path
= Path::RelativeFromDirectory (
153 files
[i
]->file
.relative_path
,
154 module
.output
->relative_path
);
155 string file
= path
+ std::string("\\") + files
[i
]->file
.name
;
157 if ( !stricmp ( Right(file
,3).c_str(), ".rc" ) )
158 resource_files
.push_back ( file
);
159 else if ( !stricmp ( Right(file
,2).c_str(), ".h" ) )
160 header_files
.push_back ( file
);
162 source_files
.push_back ( file
);
164 const vector
<Include
*>& incs
= data
.includes
;
165 for ( i
= 0; i
< incs
.size(); i
++ )
167 string path
= Path::RelativeFromDirectory (
168 incs
[i
]->directory
->relative_path
,
169 module
.output
->relative_path
);
170 if ( module
.type
!= RpcServer
&& module
.type
!= RpcClient
)
172 if ( path
.find ("/include/reactos/idl") != string::npos
)
178 // switch between general headers and ros headers
179 if ( !strncmp(incs
[i
]->directory
->relative_path
.c_str(), "include\\crt", 11 ) ||
180 !strncmp(incs
[i
]->directory
->relative_path
.c_str(), "include\\ddk", 11 ) ||
181 !strncmp(incs
[i
]->directory
->relative_path
.c_str(), "include\\GL", 10 ) ||
182 !strncmp(incs
[i
]->directory
->relative_path
.c_str(), "include\\psdk", 12 ) ||
183 !strncmp(incs
[i
]->directory
->relative_path
.c_str(), "include\\reactos\\wine", 20 ) )
185 if (strncmp(incs
[i
]->directory
->relative_path
.c_str(), "include\\crt", 11 ))
187 includes_ros
.push_back ( path
);
191 includes
.push_back ( path
);
194 const vector
<Library
*>& libs
= data
.libraries
;
195 for ( i
= 0; i
< libs
.size(); i
++ )
197 string libpath
= outdir
+ "\\" + libs
[i
]->importedModule
->output
->relative_path
+ "\\" + _get_vc_dir() + "\\---\\" + libs
[i
]->name
+ ".lib";
198 libraries
.push_back ( libpath
);
200 const vector
<Define
*>& defs
= data
.defines
;
201 for ( i
= 0; i
< defs
.size(); i
++ )
203 if ( defs
[i
]->backend
!= "" && defs
[i
]->backend
!= "msvc" )
206 if ( defs
[i
]->value
[0] )
207 common_defines
.insert( defs
[i
]->name
+ "=" + defs
[i
]->value
);
209 common_defines
.insert( defs
[i
]->name
);
211 for ( std::map
<std::string
, Property
*>::const_iterator p
= data
.properties
.begin(); p
!= data
.properties
.end(); ++ p
)
213 Property
& prop
= *p
->second
;
214 if ( strstr ( module
.baseaddress
.c_str(), prop
.name
.c_str() ) )
215 baseaddr
= prop
.value
;
218 /* include intermediate path for reactos.rc */
219 string version
= intdir
+ "\\include";
220 includes
.push_back (version
);
221 version
+= "\\reactos";
222 includes
.push_back (version
);
224 string include_string
;
226 fprintf ( OUT
, "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\r\n" );
227 fprintf ( OUT
, "<VisualStudioProject\r\n" );
228 fprintf ( OUT
, "\tProjectType=\"Visual C++\"\r\n" );
230 if (configuration
.VSProjectVersion
.empty())
231 configuration
.VSProjectVersion
= MS_VS_DEF_VERSION
;
233 fprintf ( OUT
, "\tVersion=\"%s\"\r\n", configuration
.VSProjectVersion
.c_str() );
234 fprintf ( OUT
, "\tName=\"%s\"\r\n", module
.name
.c_str() );
235 fprintf ( OUT
, "\tProjectGUID=\"%s\"\r\n", module
.guid
.c_str() );
236 fprintf ( OUT
, "\tKeyword=\"Win32Proj\">\r\n" );
238 fprintf ( OUT
, "\t<Platforms>\r\n" );
239 fprintf ( OUT
, "\t\t<Platform\r\n" );
240 fprintf ( OUT
, "\t\t\tName=\"Win32\"/>\r\n" );
241 fprintf ( OUT
, "\t</Platforms>\r\n" );
243 // Set the binary type
244 string module_type
= GetExtension(*module
.output
);
245 BinaryType binaryType
;
246 if ((module
.type
== ObjectLibrary
) || (module
.type
== RpcClient
) ||(module
.type
== RpcServer
) || (module_type
== ".lib") || (module_type
== ".a"))
248 else if ((module_type
== ".dll") || (module_type
== ".cpl"))
250 else if ((module_type
== ".exe") || (module_type
== ".scr"))
252 else if (module_type
== ".sys")
255 binaryType
= BinUnknown
;
257 // Write out all the configurations
258 fprintf ( OUT
, "\t<Configurations>\r\n" );
259 for ( size_t icfg
= 0; icfg
< m_configurations
.size(); icfg
++ )
261 const MSVCConfiguration
& cfg
= *m_configurations
[icfg
];
263 if ( cfg
.optimization
== RosBuild
)
265 _generate_makefile_configuration( module
, cfg
);
269 _generate_standard_configuration( module
, cfg
, binaryType
);
272 fprintf ( OUT
, "\t</Configurations>\r\n" );
274 // Write out the project files
275 fprintf ( OUT
, "\t<Files>\r\n" );
278 fprintf ( OUT
, "\t\t<Filter\r\n" );
279 fprintf ( OUT
, "\t\t\tName=\"Source Files\"\r\n" );
280 fprintf ( OUT
, "\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;S\">\r\n" );
282 std::sort(source_files
.begin(), source_files
.end(), SortFilesAscending());
283 vector
<string
> last_folder
;
284 vector
<string
> split_path
;
285 string
indent_tab("\t\t\t");
287 for ( size_t isrcfile
= 0; isrcfile
< source_files
.size(); isrcfile
++ )
289 string source_file
= DosSeparator(source_files
[isrcfile
]);
291 Path::Split(split_path
, source_file
, false);
292 size_t same_folder_index
= 0;
293 for ( size_t ifolder
= 0; ifolder
< last_folder
.size(); ifolder
++ )
295 if ( ifolder
< split_path
.size() && last_folder
[ifolder
] == split_path
[ifolder
] )
301 if ( same_folder_index
< split_path
.size() || last_folder
.size() > split_path
.size() )
304 if ( split_path
.size() > last_folder
.size() )
306 for ( size_t ifolder
= last_folder
.size(); ifolder
< split_path
.size(); ifolder
++ )
307 indent_tab
.push_back('\t');
308 tabStart
= split_path
.size() - last_folder
.size() + 1;
310 else if ( split_path
.size() < last_folder
.size() )
312 indent_tab
.resize( split_path
.size() + 3 );
313 tabStart
= split_path
.size() - last_folder
.size() + 1;
316 for ( size_t ifolder
= last_folder
.size(), itab
= tabStart
; ifolder
> same_folder_index
; ifolder
--, itab
++ )
318 fprintf ( OUT
, "%s</Filter>\r\n", indent_tab
.substr(0, indent_tab
.size() - itab
).c_str() );
321 for ( size_t ifolder
= same_folder_index
, itab
= split_path
.size() - same_folder_index
; ifolder
< split_path
.size(); ifolder
++, itab
-- )
323 const string tab
= indent_tab
.substr(0, indent_tab
.size() - itab
);
324 fprintf ( OUT
, "%s<Filter\r\n", tab
.c_str() );
325 fprintf ( OUT
, "%s\tName=\"%s\">\r\n", tab
.c_str(), split_path
[ifolder
].c_str() );
328 last_folder
= split_path
;
331 fprintf ( OUT
, "%s<File\r\n", indent_tab
.c_str() );
332 fprintf ( OUT
, "%s\tRelativePath=\"%s\">\r\n", indent_tab
.c_str(), source_file
.c_str() );
334 for ( size_t iconfig
= 0; iconfig
< m_configurations
.size(); iconfig
++ )
336 const MSVCConfiguration
& config
= *m_configurations
[iconfig
];
338 if (( isrcfile
== 0 ) && ( module
.pch
!= NULL
))
340 /* little hack to speed up PCH */
341 fprintf ( OUT
, "%s\t<FileConfiguration\r\n", indent_tab
.c_str() );
342 fprintf ( OUT
, "%s\t\tName=\"", indent_tab
.c_str() );
343 fprintf ( OUT
, config
.name
.c_str() );
344 fprintf ( OUT
, "|Win32\">\r\n" );
345 fprintf ( OUT
, "%s\t\t<Tool\r\n", indent_tab
.c_str() );
346 fprintf ( OUT
, "%s\t\t\tName=\"VCCLCompilerTool\"\r\n", indent_tab
.c_str() );
347 fprintf ( OUT
, "%s\t\t\tUsePrecompiledHeader=\"1\"/>\r\n", indent_tab
.c_str() );
348 fprintf ( OUT
, "%s\t</FileConfiguration>\r\n", indent_tab
.c_str() );
351 //if (configuration.VSProjectVersion < "8.00") {
352 if ((source_file
.find(".idl") != string::npos
) || ((source_file
.find(".asm") != string::npos
|| tolower(source_file
.at(source_file
.size() - 1)) == 's')))
354 fprintf ( OUT
, "%s\t<FileConfiguration\r\n", indent_tab
.c_str() );
355 fprintf ( OUT
, "%s\t\tName=\"", indent_tab
.c_str() );
356 fprintf ( OUT
, config
.name
.c_str() );
357 fprintf ( OUT
, "|Win32\">\r\n" );
358 fprintf ( OUT
, "%s\t\t<Tool\r\n", indent_tab
.c_str() );
359 if (source_file
.find(".idl") != string::npos
)
361 string src
= source_file
.substr (0, source_file
.find(".idl"));
363 if ( src
.find (".\\") != string::npos
)
366 fprintf ( OUT
, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab
.c_str() );
368 if ( module
.type
== RpcClient
)
370 fprintf ( OUT
, "%s\t\t\tCommandLine=\"midl.exe /cstub %s_c.c /header %s_c.h /server none "$(InputPath)" /out "$(IntDir)"", indent_tab
.c_str(), src
.c_str (), src
.c_str () );
371 fprintf ( OUT
, "
");
372 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 () );
376 fprintf ( OUT
, "%s\t\t\tCommandLine=\"midl.exe /sstub %s_s.c /header %s_s.h /client none "$(InputPath)" /out "$(IntDir)"", indent_tab
.c_str(), src
.c_str (), src
.c_str () );
377 fprintf ( OUT
, "
");
378 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 () );
381 fprintf ( OUT
, "
");
382 fprintf ( OUT
, "lib.exe /OUT:"$(OutDir)\\%s.lib" "$(IntDir)\\%s.obj"
\"\r\n", module
.name
.c_str (), src
.c_str () );
383 fprintf ( OUT
, "%s\t\t\tOutputs=\"$(IntDir)\\$(InputName).obj\"/>\r\n", indent_tab
.c_str() );
385 else if ((source_file
.find(".asm") != string::npos
))
387 fprintf ( OUT
, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab
.c_str() );
388 fprintf ( OUT
, "%s\t\t\tCommandLine=\"nasmw $(InputPath) -f coff -o "$(OutDir)\\$(InputName).obj"\"\r\n", indent_tab
.c_str() );
389 fprintf ( OUT
, "%s\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n", indent_tab
.c_str() );
391 else if ((tolower(source_file
.at(source_file
.size() - 1)) == 's'))
393 fprintf ( OUT
, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab
.c_str() );
394 fprintf ( OUT
, "%s\t\t\tCommandLine=\"cl /E "$(InputPath)" %s /D__ASM__ | as -o "$(OutDir)\\$(InputName).obj"\"\r\n", indent_tab
.c_str(), include_string
.c_str() );
395 fprintf ( OUT
, "%s\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n", indent_tab
.c_str() );
397 fprintf ( OUT
, "%s\t</FileConfiguration>\r\n", indent_tab
.c_str() );
401 fprintf ( OUT
, "%s</File>\r\n", indent_tab
.c_str() );
404 for ( size_t ifolder
= last_folder
.size(); ifolder
> 0; ifolder
-- )
406 indent_tab
.resize( ifolder
+ 2 );
407 fprintf ( OUT
, "%s</Filter>\r\n", indent_tab
.c_str() );
410 fprintf ( OUT
, "\t\t</Filter>\r\n" );
413 fprintf ( OUT
, "\t\t<Filter\r\n" );
414 fprintf ( OUT
, "\t\t\tName=\"Header Files\"\r\n" );
415 fprintf ( OUT
, "\t\t\tFilter=\"h;hpp;hxx;hm;inl\">\r\n" );
416 for ( i
= 0; i
< header_files
.size(); i
++ )
418 const string
& header_file
= header_files
[i
];
419 fprintf ( OUT
, "\t\t\t<File\r\n" );
420 fprintf ( OUT
, "\t\t\t\tRelativePath=\"%s\">\r\n", header_file
.c_str() );
421 fprintf ( OUT
, "\t\t\t</File>\r\n" );
423 fprintf ( OUT
, "\t\t</Filter>\r\n" );
426 fprintf ( OUT
, "\t\t<Filter\r\n" );
427 fprintf ( OUT
, "\t\t\tName=\"Resource Files\"\r\n" );
428 fprintf ( OUT
, "\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\">\r\n" );
429 for ( i
= 0; i
< resource_files
.size(); i
++ )
431 const string
& resource_file
= resource_files
[i
];
432 fprintf ( OUT
, "\t\t\t<File\r\n" );
433 fprintf ( OUT
, "\t\t\t\tRelativePath=\"%s\">\r\n", resource_file
.c_str() );
434 fprintf ( OUT
, "\t\t\t</File>\r\n" );
436 fprintf ( OUT
, "\t\t</Filter>\r\n" );
438 fprintf ( OUT
, "\t</Files>\r\n" );
439 fprintf ( OUT
, "\t<Globals>\r\n" );
440 fprintf ( OUT
, "\t</Globals>\r\n" );
441 fprintf ( OUT
, "</VisualStudioProject>\r\n" );
444 void VCProjMaker::_generate_user_configuration ()
446 // Call base implementation
447 ProjMaker::_generate_user_configuration ();
450 void VCProjMaker::_generate_standard_configuration( const Module
& module
,
451 const MSVCConfiguration
& cfg
,
452 BinaryType binaryType
)
454 string path_basedir
= module
.GetPathToBaseDir ();
455 string intenv
= Environment::GetIntermediatePath ();
456 string outenv
= Environment::GetOutputPath ();
461 bool debug
= ( cfg
.optimization
== Debug
);
462 bool release
= ( cfg
.optimization
== Release
);
463 bool speed
= ( cfg
.optimization
== Speed
);
465 bool include_idl
= false;
466 string include_string
;
469 string intermediatedir
= "";
471 // don't do the work m_configurations.size() times
472 if (module
.importLibrary
!= NULL
)
474 intermediatedir
= module
.output
->relative_path
+ vcdir
;
475 importLib
= _strip_gcc_deffile(module
.importLibrary
->source
->name
, module
.importLibrary
->source
->relative_path
, intermediatedir
);
476 importLib
= Path::RelativeFromDirectory (
478 module
.output
->relative_path
);
481 string module_type
= GetExtension(*module
.output
);
483 // Set the configuration type for this config
484 ConfigurationType CfgType
;
485 if ( binaryType
== Exe
)
487 else if ( binaryType
== Lib
)
489 else if ( binaryType
== Dll
|| binaryType
== Sys
)
492 CfgType
= ConfigUnknown
;
495 if ( intenv
== "obj-i386" )
496 intdir
= path_basedir
+ "obj-i386"; /* append relative dir from project dir */
500 if ( outenv
== "output-i386" )
501 outdir
= path_basedir
+ "output-i386";
505 if ( configuration
.UseVSVersionInPath
)
507 vcdir
= DEF_SSEP
+ _get_vc_dir();
510 fprintf ( OUT
, "\t\t<Configuration\r\n" );
511 fprintf ( OUT
, "\t\t\tName=\"%s|Win32\"\r\n", cfg
.name
.c_str() );
513 if ( configuration
.UseConfigurationInPath
)
515 fprintf ( OUT
, "\t\t\tOutputDirectory=\"%s\\%s%s\\%s\"\r\n", outdir
.c_str (), module
.output
->relative_path
.c_str (), vcdir
.c_str (), cfg
.name
.c_str() );
516 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir
.c_str (), module
.output
->relative_path
.c_str (), vcdir
.c_str (), cfg
.name
.c_str() );
520 fprintf ( OUT
, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir
.c_str (), module
.output
->relative_path
.c_str (), vcdir
.c_str () );
521 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir
.c_str (), module
.output
->relative_path
.c_str (), vcdir
.c_str () );
524 fprintf ( OUT
, "\t\t\tConfigurationType=\"%d\"\r\n", CfgType
);
525 fprintf ( OUT
, "\t\t\tCharacterSet=\"2\"\r\n" );
526 fprintf ( OUT
, "\t\t\t>\r\n" );
528 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
529 fprintf ( OUT
, "\t\t\t\tName=\"VCCLCompilerTool\"\r\n" );
531 fprintf ( OUT
, "\t\t\t\tOptimization=\"%d\"\r\n", release
? 2 : 0 );
533 fprintf ( OUT
, "\t\t\t\tAdditionalIncludeDirectories=\"" );
534 bool multiple_includes
= false;
535 fprintf ( OUT
, "./;" );
536 for ( i
= 0; i
< includes
.size(); i
++ )
538 const std::string
& include
= includes
[i
];
539 if ( strcmp ( include
.c_str(), "." ) )
541 if ( multiple_includes
)
542 fprintf ( OUT
, ";" );
543 fprintf ( OUT
, "%s", include
.c_str() );
544 include_string
+= " /I " + include
;
545 multiple_includes
= true;
550 if ( multiple_includes
)
551 fprintf ( OUT
, ";" );
553 if ( configuration
.UseConfigurationInPath
)
555 fprintf ( OUT
, "%s\\include\\reactos\\idl%s\\%s\r\n", intdir
.c_str (), vcdir
.c_str (), cfg
.name
.c_str() );
559 fprintf ( OUT
, "%s\\include\\reactos\\idl\r\n", intdir
.c_str () );
562 if ( cfg
.headers
== ReactOSHeaders
)
564 for ( i
= 0; i
< includes_ros
.size(); i
++ )
566 const std::string
& include
= includes_ros
[i
];
567 if ( multiple_includes
)
568 fprintf ( OUT
, ";" );
569 fprintf ( OUT
, "%s", include
.c_str() );
570 //include_string += " /I " + include;
571 multiple_includes
= true;
576 // Add WDK or PSDK paths, if user provides them
577 if (getenv ( "BASEDIR" ) != NULL
&&
578 (module
.type
== Kernel
||
579 module
.type
== KernelModeDLL
||
580 module
.type
== KernelModeDriver
||
581 module
.type
== KeyboardLayout
))
583 string WdkBase
, SdkPath
, CrtPath
, DdkPath
;
584 WdkBase
= getenv ( "BASEDIR" );
585 SdkPath
= WdkBase
+ "\\inc\\api";
586 CrtPath
= WdkBase
+ "\\inc\\crt";
587 DdkPath
= WdkBase
+ "\\inc\\ddk";
589 if ( multiple_includes
)
590 fprintf ( OUT
, ";" );
592 fprintf ( OUT
, "%s;", SdkPath
.c_str() );
593 fprintf ( OUT
, "%s;", CrtPath
.c_str() );
594 fprintf ( OUT
, "%s", DdkPath
.c_str() );
595 multiple_includes
= true;
598 fprintf ( OUT
, "\"\r\n" );
600 StringSet defines
= common_defines
;
602 // Always add _CRT_SECURE_NO_WARNINGS to disable warnings about not
603 // using the safe functions introduced in MSVC8.
604 defines
.insert ( "_CRT_SECURE_NO_WARNINGS" );
608 defines
.insert ( "_DEBUG" );
611 if ( cfg
.headers
== MSVCHeaders
)
613 // this is a define in MinGW w32api, but not Microsoft's headers
614 defines
.insert ( "STDCALL=__stdcall" );
617 if ( binaryType
== Lib
|| binaryType
== Exe
)
619 defines
.insert ( "_LIB" );
623 defines
.insert ( "_WINDOWS" );
624 defines
.insert ( "_USRDLL" );
627 fprintf ( OUT
, "\t\t\t\tPreprocessorDefinitions=\"" );
628 for ( StringSet::iterator it1
=defines
.begin(); it1
!=defines
.end(); it1
++ )
631 fprintf ( OUT
, ";" );
633 string unescaped
= *it1
;
634 fprintf ( OUT
, "%s", _replace_str(unescaped
, "\"","").c_str() );
636 fprintf ( OUT
, "\"\r\n" );
637 fprintf ( OUT
, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h");
638 fprintf ( OUT
, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed
? "TRUE" : "FALSE" );
639 fprintf ( OUT
, "\t\t\t\tBasicRuntimeChecks=\"0\"\r\n" );
640 fprintf ( OUT
, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug
? 3 : 2 ); // 3=/MDd 2=/MD
641 fprintf ( OUT
, "\t\t\t\tBufferSecurityCheck=\"FALSE\"\r\n" );
642 fprintf ( OUT
, "\t\t\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" );
644 if ( module
.pch
!= NULL
)
646 fprintf ( OUT
, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" );
647 string pch_path
= Path::RelativeFromDirectory (
648 module
.pch
->file
->name
,
649 module
.output
->relative_path
);
650 string::size_type pos
= pch_path
.find_last_of ("/");
651 if ( pos
!= string::npos
)
652 pch_path
.erase(0, pos
+1);
653 fprintf ( OUT
, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path
.c_str() );
655 // Only include from the same module
656 pos
= pch_path
.find("../");
657 if (pos
== string::npos
&& std::find(header_files
.begin(), header_files
.end(), pch_path
) == header_files
.end())
658 header_files
.push_back(pch_path
);
662 fprintf ( OUT
, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" );
665 fprintf ( OUT
, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release
? "FALSE" : "FALSE");
668 fprintf ( OUT
, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" );
669 fprintf ( OUT
, "\t\t\t\tStringPooling=\"true\"\r\n" );
672 fprintf ( OUT
, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed
? "0" : "3" );
673 fprintf ( OUT
, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE");
674 if ( !module
.cplusplus
)
675 fprintf ( OUT
, "\t\t\t\tCompileAs=\"1\"\r\n" );
677 if ( module
.type
== Win32CUI
|| module
.type
== Win32GUI
)
679 fprintf ( OUT
, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 ); // 0=__cdecl
683 fprintf ( OUT
, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 ); // 2=__stdcall
686 fprintf ( OUT
, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed
? "0" : release
? "3": "4"); // 3=/Zi 4=ZI
688 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
689 fprintf ( OUT
, "\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n" );
691 if ( binaryType
== Lib
)
693 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
694 fprintf ( OUT
, "\t\t\t\tName=\"VCLibrarianTool\"\r\n" );
695 fprintf ( OUT
, "\t\t\t\tOutputFile=\"$(OutDir)/%s.lib\"/>\r\n", module
.name
.c_str() );
699 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
700 fprintf ( OUT
, "\t\t\t\tName=\"VCLinkerTool\"\r\n" );
701 if (module
.GetEntryPoint() == "0" && binaryType
!= Sys
)
702 fprintf ( OUT
, "AdditionalOptions=\"/noentry\"" );
704 if (configuration
.VSProjectVersion
== "9.00")
706 fprintf ( OUT
, "\t\t\t\tRandomizedBaseAddress=\"0\"\r\n" );
707 fprintf ( OUT
, "\t\t\t\tDataExecutionPrevention=\"0\"\r\n" );
710 if (module
.importLibrary
!= NULL
)
711 fprintf ( OUT
, "\t\t\t\tModuleDefinitionFile=\"%s\"\r\n", importLib
.c_str());
713 fprintf ( OUT
, "\t\t\t\tAdditionalDependencies=\"" );
714 bool use_msvcrt_lib
= false;
715 for ( i
= 0; i
< libraries
.size(); i
++ )
718 fprintf ( OUT
, " " );
719 string libpath
= libraries
[i
].c_str();
720 libpath
= libpath
.erase (0, libpath
.find_last_of ("\\") + 1 );
721 if ( libpath
== "msvcrt.lib" )
723 use_msvcrt_lib
= true;
725 fprintf ( OUT
, "%s", libpath
.c_str() );
727 fprintf ( OUT
, "\"\r\n" );
729 fprintf ( OUT
, "\t\t\t\tAdditionalLibraryDirectories=\"" );
731 // Add WDK libs paths, if needed
732 if (getenv ( "BASEDIR" ) != NULL
&&
733 (module
.type
== Kernel
||
734 module
.type
== KernelModeDLL
||
735 module
.type
== KernelModeDriver
||
736 module
.type
== KeyboardLayout
))
738 string WdkBase
, CrtPath
, DdkPath
;
739 WdkBase
= getenv ( "BASEDIR" );
740 CrtPath
= WdkBase
+ "\\lib\\crt\\i386";
741 DdkPath
= WdkBase
+ "\\lib\\wnet\\i386";
743 fprintf ( OUT
, "%s;", CrtPath
.c_str() );
744 fprintf ( OUT
, "%s", DdkPath
.c_str() );
746 if (libraries
.size () > 0)
747 fprintf ( OUT
, ";" );
750 // Add conventional libraries dirs
751 for (i
= 0; i
< libraries
.size (); i
++)
754 fprintf ( OUT
, ";" );
756 string libpath
= libraries
[i
].c_str();
757 libpath
.replace (libpath
.find("---"), 3, cfg
.name
);
758 libpath
= libpath
.substr (0, libpath
.find_last_of ("\\") );
759 fprintf ( OUT
, "%s", libpath
.c_str() );
762 fprintf ( OUT
, "\"\r\n" );
764 fprintf ( OUT
, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module
.name
.c_str(), module_type
.c_str() );
765 fprintf ( OUT
, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug
? 2 : 1 );
766 fprintf ( OUT
, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed
? "FALSE" : "TRUE" );
767 fprintf ( OUT
, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release
? 0 : 0); // whole program optimization
770 fprintf ( OUT
, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module
.name
.c_str() );
772 if ( binaryType
== Sys
)
774 if (module
.GetEntryPoint() == "0")
775 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /noentry /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
777 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
778 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
779 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
780 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
781 fprintf ( OUT
, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
782 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module
.GetEntryPoint() == "" ? "DriverEntry" : module
.GetEntryPoint().c_str ());
783 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
== "" ? "0x10000" : baseaddr
.c_str ());
785 else if ( binaryType
== Exe
)
787 if ( module
.type
== Kernel
)
789 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" );
790 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
791 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
792 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
793 fprintf ( OUT
, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
794 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" );
795 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
.c_str ());
797 else if ( module
.type
== NativeCUI
)
799 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" );
800 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 );
801 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
802 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
803 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" );
804 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
.c_str ());
806 else if ( module
.type
== Win32CUI
|| module
.type
== Win32GUI
|| module
.type
== Win32SCR
)
808 if ( use_msvcrt_lib
)
810 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
812 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 2 );
815 else if ( binaryType
== Dll
)
817 if (module
.GetEntryPoint() == "0")
818 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
821 // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12
823 if (module
.GetEntryPoint() == "DllMain@12")
824 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
826 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module
.GetEntryPoint().c_str ());
828 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
== "" ? "0x40000" : baseaddr
.c_str ());
829 if ( use_msvcrt_lib
)
831 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
834 fprintf ( OUT
, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 );
837 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
838 fprintf ( OUT
, "\t\t\t\tName=\"VCResourceCompilerTool\"\r\n" );
839 fprintf ( OUT
, "\t\t\t\tAdditionalIncludeDirectories=\"" );
840 multiple_includes
= false;
841 fprintf ( OUT
, "./;" );
842 for ( i
= 0; i
< includes
.size(); i
++ )
844 const std::string
& include
= includes
[i
];
845 if ( strcmp ( include
.c_str(), "." ) )
847 if ( multiple_includes
)
848 fprintf ( OUT
, ";" );
849 fprintf ( OUT
, "%s", include
.c_str() );
850 multiple_includes
= true;
853 if ( cfg
.headers
== ReactOSHeaders
)
855 for ( i
= 0; i
< includes_ros
.size(); i
++ )
857 const std::string
& include
= includes_ros
[i
];
858 if ( multiple_includes
)
859 fprintf ( OUT
, ";" );
860 fprintf ( OUT
, "%s", include
.c_str() );
861 multiple_includes
= true;
864 fprintf ( OUT
, "\"/>\r\n " );
866 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
867 fprintf ( OUT
, "\t\t\t\tName=\"VCMIDLTool\"/>\r\n" );
868 if (configuration
.VSProjectVersion
== "8.00")
870 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
871 fprintf ( OUT
, "\t\t\t\tName=\"VCManifestTool\"\r\n" );
872 fprintf ( OUT
, "\t\t\t\tEmbedManifest=\"false\"/>\r\n" );
874 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
875 fprintf ( OUT
, "\t\t\t\tName=\"VCPostBuildEventTool\"/>\r\n" );
876 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
877 fprintf ( OUT
, "\t\t\t\tName=\"VCPreBuildEventTool\"/>\r\n" );
878 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
879 fprintf ( OUT
, "\t\t\t\tName=\"VCPreLinkEventTool\"/>\r\n" );
880 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
881 fprintf ( OUT
, "\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\r\n" );
882 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
883 fprintf ( OUT
, "\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n" );
884 fprintf ( OUT
, "\t\t</Configuration>\r\n" );
889 VCProjMaker::_generate_makefile_configuration( const Module
& module
, const MSVCConfiguration
& cfg
)
891 string path_basedir
= module
.GetPathToBaseDir ();
892 string intenv
= Environment::GetIntermediatePath ();
893 string outenv
= Environment::GetOutputPath ();
900 if ( intenv
== "obj-i386" )
901 intdir
= path_basedir
+ "obj-i386"; /* append relative dir from project dir */
905 if ( outenv
== "output-i386" )
906 outdir
= path_basedir
+ "output-i386";
910 if ( configuration
.UseVSVersionInPath
)
912 vcdir
= DEF_SSEP
+ _get_vc_dir();
915 fprintf ( OUT
, "\t\t<Configuration\r\n" );
916 fprintf ( OUT
, "\t\t\tName=\"%s|Win32\"\r\n", cfg
.name
.c_str() );
918 if ( configuration
.UseConfigurationInPath
)
920 fprintf ( OUT
, "\t\t\tOutputDirectory=\"%s\\%s\\%s\"\r\n", outdir
.c_str (), module
.output
->relative_path
.c_str (), cfg
.name
.c_str() );
921 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"%s\\%s\\%s\"\r\n", intdir
.c_str (), module
.output
->relative_path
.c_str (), cfg
.name
.c_str() );
925 fprintf ( OUT
, "\t\t\tOutputDirectory=\"%s\\%s\"\r\n", outdir
.c_str (), module
.output
->relative_path
.c_str () );
926 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"%s\\%s\"\r\n", intdir
.c_str (), module
.output
->relative_path
.c_str () );
929 fprintf ( OUT
, "\t\t\tConfigurationType=\"0\"\r\n");
930 fprintf ( OUT
, "\t\t\t>\r\n" );
932 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
934 fprintf ( OUT
, "\t\t\t\tName=\"VCNMakeTool\"\r\n" );
935 fprintf ( OUT
, "\t\t\t\tBuildCommandLine=\"%srosbuild.bat build %s\"\r\n", path_basedir
.c_str (), module
.name
.c_str ());
936 fprintf ( OUT
, "\t\t\t\tReBuildCommandLine=\"%srosbuild.bat rebuild %s\"\r\n", path_basedir
.c_str (), module
.name
.c_str ());
937 fprintf ( OUT
, "\t\t\t\tCleanCommandLine=\"%srosbuild.bat clean %s\"\r\n", path_basedir
.c_str (), module
.name
.c_str ());
938 fprintf ( OUT
, "\t\t\t\tOutput=\"\"\r\n");
939 fprintf ( OUT
, "\t\t\t\tPreprocessorDefinitions=\"\"\r\n");
940 fprintf ( OUT
, "\t\t\t\tIncludeSearchPath=\"\"\r\n");
941 fprintf ( OUT
, "\t\t\t\tForcedIncludes=\"\"\r\n");
942 fprintf ( OUT
, "\t\t\t\tAssemblySearchPath=\"\"\r\n");
943 fprintf ( OUT
, "\t\t\t\tForcedUsingAssemblies=\"\"\r\n");
944 fprintf ( OUT
, "\t\t\t\tCompileAsManaged=\"\"\r\n");
946 fprintf ( OUT
, "\t\t\t/>\r\n" );
947 fprintf ( OUT
, "\t\t</Configuration>\r\n" );