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::_get_file_path( FileLocation
* file
, std::string relative_path
)
86 if (file
->directory
== SourceDirectory
)
88 // We want the full path here for directory support later on
89 return Path::RelativeFromDirectory (file
->relative_path
, relative_path
);
91 else if(file
->directory
== IntermediateDirectory
)
93 return std::string("$(RootIntDir)\\") + file
->relative_path
;
95 else if(file
->directory
== OutputDirectory
)
97 return std::string("$(RootOutDir)\\") + file
->relative_path
;
100 return std::string("");
106 VCProjMaker::_generate_proj_file ( const Module
& module
)
110 // make sure the containers are empty
111 header_files
.clear();
114 common_defines
.clear();
116 printf ( "Creating MSVC project: '%s'\n", vcproj_file
.c_str() );
118 string path_basedir
= module
.GetPathToBaseDir ();
120 bool include_idl
= false;
122 vector
<string
> source_files
, resource_files
, generated_files
;
124 const IfableData
& data
= module
.non_if_data
;
125 const vector
<File
*>& files
= data
.files
;
126 for ( i
= 0; i
< files
.size(); i
++ )
128 string path
= _get_file_path(&files
[i
]->file
, module
.output
->relative_path
);
129 string file
= path
+ std::string("\\") + files
[i
]->file
.name
;
131 if (files
[i
]->file
.directory
!= SourceDirectory
)
132 generated_files
.push_back ( file
);
133 else if ( !stricmp ( Right(file
,3).c_str(), ".rc" ) )
134 resource_files
.push_back ( file
);
135 else if ( !stricmp ( Right(file
,2).c_str(), ".h" ) )
136 header_files
.push_back ( file
);
138 source_files
.push_back ( file
);
140 const vector
<Include
*>& incs
= data
.includes
;
141 for ( i
= 0; i
< incs
.size(); i
++ )
143 string path
= _get_file_path(incs
[i
]->directory
, module
.output
->relative_path
);
145 if ( module
.type
!= RpcServer
&& module
.type
!= RpcClient
)
147 if ( path
.find ("/include/reactos/idl") != string::npos
)
153 includes
.push_back ( path
);
155 const vector
<Library
*>& libs
= data
.libraries
;
156 for ( i
= 0; i
< libs
.size(); i
++ )
158 string libpath
= "$(RootOutDir)\\" + libs
[i
]->importedModule
->output
->relative_path
+ "\\" + _get_vc_dir() + "\\$(ConfigurationName)\\" + libs
[i
]->name
+ ".lib";
159 libraries
.push_back ( libpath
);
161 const vector
<Define
*>& defs
= data
.defines
;
162 for ( i
= 0; i
< defs
.size(); i
++ )
164 if ( defs
[i
]->backend
!= "" && defs
[i
]->backend
!= "msvc" )
167 if ( defs
[i
]->value
[0] )
168 common_defines
.insert( defs
[i
]->name
+ "=" + defs
[i
]->value
);
170 common_defines
.insert( defs
[i
]->name
);
172 for ( std::map
<std::string
, Property
*>::const_iterator p
= data
.properties
.begin(); p
!= data
.properties
.end(); ++ p
)
174 Property
& prop
= *p
->second
;
175 if ( strstr ( module
.baseaddress
.c_str(), prop
.name
.c_str() ) )
176 baseaddr
= prop
.value
;
179 if(module
.importLibrary
)
181 std::string ImportLibraryPath
= _get_file_path(module
.importLibrary
->source
, module
.output
->relative_path
);
183 switch (module
.IsSpecDefinitionFile())
186 generated_files
.push_back("$(IntDir)\\" + ReplaceExtension(module
.importLibrary
->source
->name
,".spec"));
188 generated_files
.push_back("$(IntDir)\\" + ReplaceExtension(module
.importLibrary
->source
->name
,".stubs.c"));
189 generated_files
.push_back("$(IntDir)\\" + ReplaceExtension(module
.importLibrary
->source
->name
,".def"));
191 source_files
.push_back(ImportLibraryPath
+ std::string("\\") + module
.importLibrary
->source
->name
);
195 fprintf ( OUT
, "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\r\n" );
196 fprintf ( OUT
, "<VisualStudioProject\r\n" );
197 fprintf ( OUT
, "\tProjectType=\"Visual C++\"\r\n" );
199 if (configuration
.VSProjectVersion
.empty())
200 configuration
.VSProjectVersion
= MS_VS_DEF_VERSION
;
202 fprintf ( OUT
, "\tVersion=\"%s\"\r\n", configuration
.VSProjectVersion
.c_str() );
203 fprintf ( OUT
, "\tName=\"%s\"\r\n", module
.name
.c_str() );
204 fprintf ( OUT
, "\tProjectGUID=\"%s\"\r\n", module
.guid
.c_str() );
205 fprintf ( OUT
, "\tKeyword=\"Win32Proj\">\r\n" );
207 fprintf ( OUT
, "\t<Platforms>\r\n" );
208 fprintf ( OUT
, "\t\t<Platform\r\n" );
209 fprintf ( OUT
, "\t\t\tName=\"Win32\"/>\r\n" );
210 fprintf ( OUT
, "\t</Platforms>\r\n" );
212 fprintf ( OUT
, "\t<ToolFiles>\r\n" );
213 fprintf ( OUT
, "\t\t<ToolFile\r\n" );
214 fprintf ( OUT
, "\t\t\tRelativePath=\"%s%s\"\r\n", path_basedir
.c_str(), "tools\\rbuild\\backend\\msvc\\s_as_mscpp.rules" );
215 fprintf ( OUT
, "\t\t/>\r\n" );
216 fprintf ( OUT
, "\t\t<ToolFile\r\n" );
217 fprintf ( OUT
, "\t\t\tRelativePath=\"%s%s\"\r\n", path_basedir
.c_str(), "tools\\rbuild\\backend\\msvc\\spec.rules" );
218 fprintf ( OUT
, "\t\t/>\r\n" );
219 fprintf ( OUT
, "\t</ToolFiles>\r\n" );
221 // Set the binary type
222 string module_type
= GetExtension(*module
.output
);
223 BinaryType binaryType
;
224 if ((module
.type
== ObjectLibrary
) || (module
.type
== RpcClient
) ||(module
.type
== RpcServer
) || (module_type
== ".lib") || (module_type
== ".a"))
226 else if ((module_type
== ".dll") || (module_type
== ".cpl"))
228 else if ((module_type
== ".exe") || (module_type
== ".scr"))
230 else if (module_type
== ".sys")
233 binaryType
= BinUnknown
;
235 // Write out all the configurations
236 fprintf ( OUT
, "\t<Configurations>\r\n" );
237 for ( size_t icfg
= 0; icfg
< m_configurations
.size(); icfg
++ )
239 const MSVCConfiguration
& cfg
= *m_configurations
[icfg
];
241 if ( cfg
.optimization
== RosBuild
)
243 _generate_makefile_configuration( module
, cfg
);
247 _generate_standard_configuration( module
, cfg
, binaryType
);
250 fprintf ( OUT
, "\t</Configurations>\r\n" );
252 // Write out the project files
253 fprintf ( OUT
, "\t<Files>\r\n" );
256 fprintf ( OUT
, "\t\t<Filter\r\n" );
257 fprintf ( OUT
, "\t\t\tName=\"Generated Files\">\r\n" );
258 for( i
= 0; i
< generated_files
.size(); i
++)
260 string source_file
= DosSeparator(generated_files
[i
]);
262 fprintf ( OUT
, "\t\t\t<File\r\n");
263 fprintf ( OUT
, "\t\t\t\tRelativePath=\"%s\">\r\n", source_file
.c_str() );
264 fprintf ( OUT
, "\t\t\t</File>\r\n");
266 fprintf ( OUT
, "\t\t</Filter>\r\n" );
269 fprintf ( OUT
, "\t\t<Filter\r\n" );
270 fprintf ( OUT
, "\t\t\tName=\"Source Files\"\r\n" );
271 fprintf ( OUT
, "\t\t\tFilter=\"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;S\">\r\n" );
273 std::sort(source_files
.begin(), source_files
.end(), SortFilesAscending());
274 vector
<string
> last_folder
;
275 vector
<string
> split_path
;
276 string
indent_tab("\t\t\t");
278 for ( size_t isrcfile
= 0; isrcfile
< source_files
.size(); isrcfile
++ )
280 string source_file
= DosSeparator(source_files
[isrcfile
]);
282 Path::Split(split_path
, source_file
, false);
283 size_t same_folder_index
= 0;
284 for ( size_t ifolder
= 0; ifolder
< last_folder
.size(); ifolder
++ )
286 if ( ifolder
< split_path
.size() && last_folder
[ifolder
] == split_path
[ifolder
] )
292 if ( same_folder_index
< split_path
.size() || last_folder
.size() > split_path
.size() )
295 if ( split_path
.size() > last_folder
.size() )
297 for ( size_t ifolder
= last_folder
.size(); ifolder
< split_path
.size(); ifolder
++ )
298 indent_tab
.push_back('\t');
299 tabStart
= split_path
.size() - last_folder
.size() + 1;
301 else if ( split_path
.size() < last_folder
.size() )
303 indent_tab
.resize( split_path
.size() + 3 );
304 tabStart
= split_path
.size() - last_folder
.size() + 1;
307 for ( size_t ifolder
= last_folder
.size(), itab
= tabStart
; ifolder
> same_folder_index
; ifolder
--, itab
++ )
309 fprintf ( OUT
, "%s</Filter>\r\n", indent_tab
.substr(0, indent_tab
.size() - itab
).c_str() );
312 for ( size_t ifolder
= same_folder_index
, itab
= split_path
.size() - same_folder_index
; ifolder
< split_path
.size(); ifolder
++, itab
-- )
314 const string tab
= indent_tab
.substr(0, indent_tab
.size() - itab
);
315 fprintf ( OUT
, "%s<Filter\r\n", tab
.c_str() );
316 fprintf ( OUT
, "%s\tName=\"%s\">\r\n", tab
.c_str(), split_path
[ifolder
].c_str() );
319 last_folder
= split_path
;
322 fprintf ( OUT
, "%s<File\r\n", indent_tab
.c_str() );
323 fprintf ( OUT
, "%s\tRelativePath=\"%s\">\r\n", indent_tab
.c_str(), source_file
.c_str() );
325 for ( size_t iconfig
= 0; iconfig
< m_configurations
.size(); iconfig
++ )
327 const MSVCConfiguration
& config
= *m_configurations
[iconfig
];
329 //if (configuration.VSProjectVersion < "8.00") {
330 if ((source_file
.find(".idl") != string::npos
) || ((source_file
.find(".asm") != string::npos
)))
332 fprintf ( OUT
, "%s\t<FileConfiguration\r\n", indent_tab
.c_str() );
333 fprintf ( OUT
, "%s\t\tName=\"%s|Win32\"\r\n", indent_tab
.c_str(),config
.name
.c_str() );
334 fprintf ( OUT
, "%s\t\tExcludedFromBuild=\"true\"\r\n",indent_tab
.c_str());
335 fprintf ( OUT
, ">\r\n" );
337 fprintf ( OUT
, "%s\t\t<Tool\r\n", indent_tab
.c_str() );
338 if (source_file
.find(".idl") != string::npos
)
340 string src
= source_file
.substr (0, source_file
.find(".idl"));
342 if ( src
.find (".\\") != string::npos
)
345 fprintf ( OUT
, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab
.c_str() );
347 if ( module
.type
== RpcClient
)
349 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 () );
350 fprintf ( OUT
, "
");
351 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 () );
355 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 () );
356 fprintf ( OUT
, "
");
357 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 () );
360 fprintf ( OUT
, "
");
361 fprintf ( OUT
, "lib.exe /OUT:"$(OutDir)\\%s.lib" "$(IntDir)\\%s.obj"
\"\r\n", module
.name
.c_str (), src
.c_str () );
362 fprintf ( OUT
, "%s\t\t\tOutputs=\"$(IntDir)\\$(InputName).obj\"/>\r\n", indent_tab
.c_str() );
364 else if ((source_file
.find(".asm") != string::npos
))
366 fprintf ( OUT
, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab
.c_str() );
367 fprintf ( OUT
, "%s\t\t\tCommandLine=\"nasmw $(InputPath) -f coff -o "$(OutDir)\\$(InputName).obj"\"\r\n", indent_tab
.c_str() );
368 fprintf ( OUT
, "%s\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n", indent_tab
.c_str() );
371 fprintf ( OUT
, "%s\t</FileConfiguration>\r\n", indent_tab
.c_str() );
375 fprintf ( OUT
, "%s</File>\r\n", indent_tab
.c_str() );
378 for ( size_t ifolder
= last_folder
.size(); ifolder
> 0; ifolder
-- )
380 indent_tab
.resize( ifolder
+ 2 );
381 fprintf ( OUT
, "%s</Filter>\r\n", indent_tab
.c_str() );
384 fprintf ( OUT
, "\t\t</Filter>\r\n" );
387 fprintf ( OUT
, "\t\t<Filter\r\n" );
388 fprintf ( OUT
, "\t\t\tName=\"Header Files\"\r\n" );
389 fprintf ( OUT
, "\t\t\tFilter=\"h;hpp;hxx;hm;inl\">\r\n" );
390 for ( i
= 0; i
< header_files
.size(); i
++ )
392 const string
& header_file
= header_files
[i
];
393 fprintf ( OUT
, "\t\t\t<File\r\n" );
394 fprintf ( OUT
, "\t\t\t\tRelativePath=\"%s\">\r\n", header_file
.c_str() );
395 fprintf ( OUT
, "\t\t\t</File>\r\n" );
397 fprintf ( OUT
, "\t\t</Filter>\r\n" );
400 fprintf ( OUT
, "\t\t<Filter\r\n" );
401 fprintf ( OUT
, "\t\t\tName=\"Resource Files\"\r\n" );
402 fprintf ( OUT
, "\t\t\tFilter=\"ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe\">\r\n" );
403 for ( i
= 0; i
< resource_files
.size(); i
++ )
405 const string
& resource_file
= resource_files
[i
];
406 fprintf ( OUT
, "\t\t\t<File\r\n" );
407 fprintf ( OUT
, "\t\t\t\tRelativePath=\"%s\">\r\n", resource_file
.c_str() );
408 fprintf ( OUT
, "\t\t\t</File>\r\n" );
410 fprintf ( OUT
, "\t\t</Filter>\r\n" );
412 fprintf ( OUT
, "\t</Files>\r\n" );
413 fprintf ( OUT
, "\t<Globals>\r\n" );
414 fprintf ( OUT
, "\t</Globals>\r\n" );
415 fprintf ( OUT
, "</VisualStudioProject>\r\n" );
418 void VCProjMaker::_generate_user_configuration ()
420 // Call base implementation
421 ProjMaker::_generate_user_configuration ();
424 void VCProjMaker::_generate_standard_configuration( const Module
& module
,
425 const MSVCConfiguration
& cfg
,
426 BinaryType binaryType
)
428 string path_basedir
= module
.GetPathToBaseDir ();
431 bool include_idl
= false;
434 string intermediatedir
= "";
437 if ( configuration
.UseVSVersionInPath
)
439 vcdir
= DEF_SSEP
+ _get_vc_dir();
442 if(module
.IsSpecDefinitionFile())
444 importLib
= "$(IntDir)\\$(ProjectName).def";
446 else if (module
.importLibrary
!= NULL
)
448 intermediatedir
= module
.output
->relative_path
+ vcdir
;
449 importLib
= _strip_gcc_deffile(module
.importLibrary
->source
->name
, module
.importLibrary
->source
->relative_path
, intermediatedir
);
450 importLib
= Path::RelativeFromDirectory (
452 module
.output
->relative_path
);
455 string module_type
= GetExtension(*module
.output
);
457 // Set the configuration type for this config
458 ConfigurationType CfgType
;
459 if ( binaryType
== Exe
)
461 else if ( binaryType
== Lib
)
463 else if ( binaryType
== Dll
|| binaryType
== Sys
)
466 CfgType
= ConfigUnknown
;
468 fprintf ( OUT
, "\t\t<Configuration\r\n" );
469 fprintf ( OUT
, "\t\t\tName=\"%s|Win32\"\r\n", cfg
.name
.c_str() );
471 if ( configuration
.UseConfigurationInPath
)
473 fprintf ( OUT
, "\t\t\tOutputDirectory=\"$(RootOutDir)\\%s%s\\$(ConfigurationName)\"\r\n", module
.output
->relative_path
.c_str (), vcdir
.c_str () );
474 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"$(RootIntDir)\\%s%s\\$(ConfigurationName)\"\r\n", module
.output
->relative_path
.c_str (), vcdir
.c_str () );
478 fprintf ( OUT
, "\t\t\tOutputDirectory=\"$(RootOutDir)\\%s%s\"\r\n", module
.output
->relative_path
.c_str (), vcdir
.c_str () );
479 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"$(RootIntDir)\\%s%s\"\r\n", module
.output
->relative_path
.c_str (), vcdir
.c_str () );
482 fprintf ( OUT
, "\t\t\tConfigurationType=\"%d\"\r\n", CfgType
);
484 fprintf ( OUT
, "\t\t\tInheritedPropertySheets=\"%s%s.vsprops\"\r\n", path_basedir
.c_str (), cfg
.name
.c_str ());
485 fprintf ( OUT
, "\t\t\tCharacterSet=\"2\"\r\n" );
486 fprintf ( OUT
, "\t\t\t>\r\n" );
488 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
489 fprintf ( OUT
, "\t\t\t\tName=\"s_as_mscpp\"\r\n" );
490 fprintf ( OUT
, "\t\t\t\tsIncPaths=\"" );
491 fprintf ( OUT
, "./;" );
492 for ( i
= 0; i
< includes
.size(); i
++ )
494 const std::string
& include
= includes
[i
];
495 if ( strcmp ( include
.c_str(), "." ) )
497 fprintf ( OUT
, "%s", include
.c_str() );
498 fprintf ( OUT
, ";" );
501 fprintf ( OUT
, "$(globalIncludes);\"\r\n");
502 fprintf ( OUT
, "\t\t\t\tsPPDefs=\"__ASM__\"\r\n" );
503 fprintf ( OUT
, "\t\t\t/>\r\n" );
505 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
506 fprintf ( OUT
, "\t\t\t\tName=\"Pspec\"\r\n" );
507 fprintf ( OUT
, "\t\t\t\tincludes=\"" );
508 fprintf ( OUT
, "./;" );
509 for ( i
= 0; i
< includes
.size(); i
++ )
511 const std::string
& include
= includes
[i
];
512 if ( strcmp ( include
.c_str(), "." ) )
514 fprintf ( OUT
, "%s", include
.c_str() );
515 fprintf ( OUT
, ";" );
518 fprintf ( OUT
, "$(globalIncludes);\"\r\n");
519 fprintf ( OUT
, "\t\t\t\tsPPDefs=\"__ASM__\"\r\n" );
520 fprintf ( OUT
, "\t\t\t/>\r\n" );
523 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
524 fprintf ( OUT
, "\t\t\t\tName=\"VCCLCompilerTool\"\r\n" );
526 fprintf ( OUT
, "\t\t\t\tAdditionalIncludeDirectories=\"" );
527 bool multiple_includes
= false;
528 fprintf ( OUT
, "./;" );
529 for ( i
= 0; i
< includes
.size(); i
++ )
531 const std::string
& include
= includes
[i
];
532 if ( strcmp ( include
.c_str(), "." ) )
534 if ( multiple_includes
)
535 fprintf ( OUT
, ";" );
536 fprintf ( OUT
, "%s", include
.c_str() );
537 multiple_includes
= true;
542 if ( multiple_includes
)
543 fprintf ( OUT
, ";" );
545 if ( configuration
.UseConfigurationInPath
)
547 fprintf ( OUT
, "$(int)\\include\\reactos\\idl%s\\$(ConfigurationName)\r\n", vcdir
.c_str ());
551 fprintf ( OUT
, "$(int)\\include\\reactos\\idl\r\n" );
555 fprintf ( OUT
, "\"\r\n" );
557 StringSet defines
= common_defines
;
559 if ( binaryType
== Lib
|| binaryType
== Exe
)
561 defines
.insert ( "_LIB" );
565 defines
.insert ( "_WINDOWS" );
566 defines
.insert ( "_USRDLL" );
569 fprintf ( OUT
, "\t\t\t\tPreprocessorDefinitions=\"" );
570 for ( StringSet::iterator it1
=defines
.begin(); it1
!=defines
.end(); it1
++ )
572 string unescaped
= *it1
;
573 fprintf ( OUT
, "%s ; ", _replace_str(unescaped
, "\"","").c_str() );
575 fprintf ( OUT
, "\"\r\n" );
577 //disable precompiled headers for now
579 if ( module
.pch
!= NULL
)
581 fprintf ( OUT
, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" );
582 string pch_path
= Path::RelativeFromDirectory (
583 module
.pch
->file
->name
,
584 module
.output
->relative_path
);
585 string::size_type pos
= pch_path
.find_last_of ("/");
586 if ( pos
!= string::npos
)
587 pch_path
.erase(0, pos
+1);
588 fprintf ( OUT
, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path
.c_str() );
590 // Only include from the same module
591 pos
= pch_path
.find("../");
592 if (pos
== string::npos
&& std::find(header_files
.begin(), header_files
.end(), pch_path
) == header_files
.end())
593 header_files
.push_back(pch_path
);
597 if ( module
.cplusplus
)
598 fprintf ( OUT
, "\t\t\t\tCompileAs=\"2\"\r\n" );
600 fprintf ( OUT
, "\t\t\t/>\r\n");
602 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
603 fprintf ( OUT
, "\t\t\t\tName=\"VCCustomBuildTool\"/>\r\n" );
605 if ( binaryType
!= Lib
)
607 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
608 fprintf ( OUT
, "\t\t\t\tName=\"VCLinkerTool\"\r\n" );
609 if (module
.GetEntryPoint() == "0" && binaryType
!= Sys
)
610 fprintf ( OUT
, "AdditionalOptions=\"/noentry\"" );
612 if (configuration
.VSProjectVersion
== "9.00")
614 fprintf ( OUT
, "\t\t\t\tRandomizedBaseAddress=\"0\"\r\n" );
615 fprintf ( OUT
, "\t\t\t\tDataExecutionPrevention=\"0\"\r\n" );
618 if (module
.importLibrary
!= NULL
)
619 fprintf ( OUT
, "\t\t\t\tModuleDefinitionFile=\"%s\"\r\n", importLib
.c_str());
621 fprintf ( OUT
, "\t\t\t\tAdditionalDependencies=\"" );
622 bool use_msvcrt_lib
= false;
623 for ( i
= 0; i
< libraries
.size(); i
++ )
626 fprintf ( OUT
, " " );
627 string libpath
= libraries
[i
].c_str();
628 libpath
= libpath
.erase (0, libpath
.find_last_of ("\\") + 1 );
629 if ( libpath
== "msvcrt.lib" )
631 use_msvcrt_lib
= true;
633 fprintf ( OUT
, "%s", libpath
.c_str() );
635 fprintf ( OUT
, "\"\r\n" );
637 fprintf ( OUT
, "\t\t\t\tAdditionalLibraryDirectories=\"" );
639 // Add conventional libraries dirs
640 for (i
= 0; i
< libraries
.size (); i
++)
643 fprintf ( OUT
, ";" );
645 string libpath
= libraries
[i
].c_str();
646 libpath
= libpath
.substr (0, libpath
.find_last_of ("\\") );
647 fprintf ( OUT
, "%s", libpath
.c_str() );
650 fprintf ( OUT
, "\"\r\n" );
652 fprintf ( OUT
, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module
.name
.c_str(), module_type
.c_str() );
653 if ( binaryType
== Sys
)
655 if (module
.GetEntryPoint() == "0")
656 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /noentry /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
658 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" );
659 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
660 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
661 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
662 fprintf ( OUT
, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
663 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module
.GetEntryPoint() == "" ? "DriverEntry" : module
.GetEntryPoint().c_str ());
664 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
== "" ? "0x10000" : baseaddr
.c_str ());
666 else if ( binaryType
== Exe
)
668 if ( module
.type
== Kernel
)
670 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" );
671 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
672 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
673 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 );
674 fprintf ( OUT
, "\t\t\t\tDriver=\"%d\"\r\n", 1 );
675 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" );
676 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
.c_str ());
678 else if ( module
.type
== NativeCUI
)
680 fprintf ( OUT
, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" );
681 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 );
682 fprintf ( OUT
, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" );
683 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
684 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" );
685 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
.c_str ());
687 else if ( module
.type
== Win32CUI
|| module
.type
== Win32GUI
|| module
.type
== Win32SCR
)
689 if ( use_msvcrt_lib
)
691 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
693 fprintf ( OUT
, "\t\t\t\tSubSystem=\"%d\"\r\n", 2 );
696 else if ( binaryType
== Dll
)
698 if (module
.GetEntryPoint() == "0")
699 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
702 // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12
704 if (module
.GetEntryPoint() == "DllMain@12")
705 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"\"\r\n" );
707 fprintf ( OUT
, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module
.GetEntryPoint().c_str ());
709 fprintf ( OUT
, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr
== "" ? "0x40000" : baseaddr
.c_str ());
710 if ( use_msvcrt_lib
)
712 fprintf ( OUT
, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" );
715 fprintf ( OUT
, "\t\t\t/>\r\n" );
718 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
719 fprintf ( OUT
, "\t\t\t\tName=\"VCResourceCompilerTool\"\r\n" );
720 fprintf ( OUT
, "\t\t\t\tAdditionalIncludeDirectories=\"" );
721 multiple_includes
= false;
722 fprintf ( OUT
, "./;" );
723 for ( i
= 0; i
< includes
.size(); i
++ )
725 const std::string
& include
= includes
[i
];
726 if ( strcmp ( include
.c_str(), "." ) )
728 if ( multiple_includes
)
729 fprintf ( OUT
, ";" );
730 fprintf ( OUT
, "%s", include
.c_str() );
731 multiple_includes
= true;
735 fprintf ( OUT
, "\"/>\r\n " );
737 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
738 fprintf ( OUT
, "\t\t\t\tName=\"VCMIDLTool\"/>\r\n" );
739 if (configuration
.VSProjectVersion
== "8.00")
741 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
742 fprintf ( OUT
, "\t\t\t\tName=\"VCManifestTool\"\r\n" );
743 fprintf ( OUT
, "\t\t\t\tEmbedManifest=\"false\"/>\r\n" );
745 fprintf ( OUT
, "\t\t</Configuration>\r\n" );
750 VCProjMaker::_generate_makefile_configuration( const Module
& module
, const MSVCConfiguration
& cfg
)
752 string path_basedir
= module
.GetPathToBaseDir ();
753 string intenv
= Environment::GetIntermediatePath ();
754 string outenv
= Environment::GetOutputPath ();
759 if ( intenv
== "obj-i386" )
760 intdir
= path_basedir
+ "obj-i386"; /* append relative dir from project dir */
764 if ( outenv
== "output-i386" )
765 outdir
= path_basedir
+ "output-i386";
769 fprintf ( OUT
, "\t\t<Configuration\r\n" );
770 fprintf ( OUT
, "\t\t\tName=\"%s|Win32\"\r\n", cfg
.name
.c_str() );
772 if ( configuration
.UseConfigurationInPath
)
774 fprintf ( OUT
, "\t\t\tOutputDirectory=\"%s\\%s\\%s\"\r\n", outdir
.c_str (), module
.output
->relative_path
.c_str (), cfg
.name
.c_str() );
775 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"%s\\%s\\%s\"\r\n", intdir
.c_str (), module
.output
->relative_path
.c_str (), cfg
.name
.c_str() );
779 fprintf ( OUT
, "\t\t\tOutputDirectory=\"%s\\%s\"\r\n", outdir
.c_str (), module
.output
->relative_path
.c_str () );
780 fprintf ( OUT
, "\t\t\tIntermediateDirectory=\"%s\\%s\"\r\n", intdir
.c_str (), module
.output
->relative_path
.c_str () );
783 fprintf ( OUT
, "\t\t\tConfigurationType=\"0\"\r\n");
784 fprintf ( OUT
, "\t\t\t>\r\n" );
786 fprintf ( OUT
, "\t\t\t<Tool\r\n" );
788 fprintf ( OUT
, "\t\t\t\tName=\"VCNMakeTool\"\r\n" );
789 fprintf ( OUT
, "\t\t\t\tBuildCommandLine=\"%srosbuild.bat build %s\"\r\n", path_basedir
.c_str (), module
.name
.c_str ());
790 fprintf ( OUT
, "\t\t\t\tReBuildCommandLine=\"%srosbuild.bat rebuild %s\"\r\n", path_basedir
.c_str (), module
.name
.c_str ());
791 fprintf ( OUT
, "\t\t\t\tCleanCommandLine=\"%srosbuild.bat clean %s\"\r\n", path_basedir
.c_str (), module
.name
.c_str ());
792 fprintf ( OUT
, "\t\t\t\tOutput=\"\"\r\n");
793 fprintf ( OUT
, "\t\t\t\tPreprocessorDefinitions=\"\"\r\n");
794 fprintf ( OUT
, "\t\t\t\tIncludeSearchPath=\"\"\r\n");
795 fprintf ( OUT
, "\t\t\t\tForcedIncludes=\"\"\r\n");
796 fprintf ( OUT
, "\t\t\t\tAssemblySearchPath=\"\"\r\n");
797 fprintf ( OUT
, "\t\t\t\tForcedUsingAssemblies=\"\"\r\n");
798 fprintf ( OUT
, "\t\t\t\tCompileAsManaged=\"\"\r\n");
800 fprintf ( OUT
, "\t\t\t/>\r\n" );
801 fprintf ( OUT
, "\t\t</Configuration>\r\n" );