2 * Copyright (C) 2005 Trevor McCort
3 * Copyright (C) 2005 Casper S. Hornstrup
4 * Copyright (C) 2005 Steven Edwards
5 * Copyright (C) 2005 Royce Mitchell
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.
22 #pragma warning ( disable : 4786 )
31 #include "../mingw/mingw.h"
37 static class MSVCFactory
: public Backend::Factory
41 MSVCFactory() : Factory("MSVC") {}
42 Backend
*operator() (Project
&project
,
43 Configuration
& configuration
)
45 return new MSVCBackend(project
, configuration
);
51 MSVCBackend::MSVCBackend(Project
&project
,
52 Configuration
& configuration
) : Backend(project
, configuration
)
57 void MSVCBackend::Process()
59 if ( configuration
.CleanAsYouGo
) {
60 _clean_project_files();
63 if ( configuration
.InstallFiles
) {
64 _install_files( _get_vc_dir(), configuration
.VSConfigurationType
);
67 string
filename_sln ( ProjectNode
.name
);
68 //string filename_rules = "gccasm.rules";
70 if ( configuration
.VSProjectVersion
== "6.00" )
71 filename_sln
+= ".dsw";
73 filename_sln
+= ".sln";
75 //m_rulesFile = fopen ( filename_rules.c_str(), "wb" );
78 // _generate_rules_file ( m_rulesFile );
80 //fclose ( m_rulesFile );
83 printf ( "Creating MSVC workspace: %s\n", filename_sln
.c_str() );
86 m_slnFile
= fopen ( filename_sln
.c_str(), "wb" );
90 printf ( "Could not create file '%s'.\n", filename_sln
.c_str() );
94 if ( configuration
.VSProjectVersion
== "6.00" )
95 _generate_wine_dsw ( m_slnFile
);
97 _generate_sln ( m_slnFile
);
100 printf ( "Done.\n" );
103 void MSVCBackend::ProcessModules()
105 for(size_t i
= 0; i
< ProjectNode
.modules
.size(); i
++)
107 Module
&module
= *ProjectNode
.modules
[i
];
109 module
.guid
= _gen_guid();
111 if (configuration
.VSProjectVersion
== "6.00")
112 this->_generate_dsp ( module
);
114 this->_generate_vcproj ( module
);
117 /*for(size_t k = 0; k < module.non_if_data.files.size(); k++)
119 File &file = *module.non_if_data.files[k];
121 ProcessFile(file.name);
126 static bool FileExists(string
&filename
)
128 ifstream
file(filename
.c_str());
137 void MSVCBackend::ProcessFile(string
&filepath
)
139 // Remove the .\ at the start of the filenames
140 if ( filepath
[0] == '.' && strchr ( "/\\", filepath
[1] ) )
141 filepath
.erase(0, 2);
143 if(!FileExists(filepath
))
147 for(size_t i
= 0; i
< filepath
.length(); i
++)
149 if(filepath
[i
] == '\\')
153 // Remove the filename from the path
156 size_t pos
= filepath
.rfind(string("/"), filepath
.length() - 1);
158 if(pos
!= string::npos
)
161 folder
.erase(pos
, folder
.length() - pos
);
165 fileUnit
.filename
= filepath
;
166 fileUnit
.folder
= folder
;
168 m_fileUnits
.push_back(fileUnit
);
176 bool MSVCBackend::CheckFolderAdded(string
&folder
)
178 for(size_t i
= 0; i
< m_folders
.size(); i
++)
180 if(m_folders
[i
] == folder
)
187 void MSVCBackend::AddFolders(string
&folder
)
189 // Check if this folder was already added. true if it was, false otherwise.
190 if(CheckFolderAdded(folder
))
193 m_folders
.push_back(folder
);
195 size_t pos
= folder
.rfind(string("/"), folder
.length() - 1);
197 if(pos
== string::npos
)
200 folder
.erase(pos
, folder
.length() - pos
);
204 void MSVCBackend::OutputFolders()
207 m_devFile
<< "Folders=";
209 for(size_t i
= 0; i
< m_folders
.size(); i
++)
214 m_devFile
<< m_folders
[i
];
220 MSVCBackend::OptFileName ( const Module
& module
) const
223 ReplaceExtension ( module
.GetPath(), "_" + _get_vc_dir() + "_auto.opt" )
228 MSVCBackend::SuoFileName ( const Module
& module
) const
231 ReplaceExtension ( module
.GetPath(), "_" + _get_vc_dir() + "_auto.suo" )
236 MSVCBackend::DswFileName ( const Module
& module
) const
239 ReplaceExtension ( module
.GetPath(), "_auto.dsw" )
244 MSVCBackend::SlnFileName ( const Module
& module
) const
247 ReplaceExtension ( module
.GetPath(), "_" + _get_vc_dir() + "_auto.sln" )
252 MSVCBackend::NcbFileName ( const Module
& module
) const
255 ReplaceExtension ( module
.GetPath(), "_" + _get_vc_dir() + "_auto.ncb" )
260 MSVCBackend::DspFileName ( const Module
& module
) const
263 ReplaceExtension ( module
.GetPath(), "_auto.dsp" )
268 MSVCBackend::VcprojFileName ( const Module
& module
) const
271 ReplaceExtension ( module
.GetPath(), "_" + _get_vc_dir() + "_auto.vcproj" )
275 std::string
MSVCBackend::_get_vc_dir ( void ) const
277 if ( configuration
.VSProjectVersion
== "6.00" )
279 else if ( configuration
.VSProjectVersion
== "7.00" )
281 else if ( configuration
.VSProjectVersion
== "7.10" )
283 else /* must be VS2005 */
290 MSVCBackend::_get_object_files ( const Module
& module
, vector
<string
>& out
) const
292 string basepath
= module
.GetBasePath ();
293 string vcdir
= _get_vc_dir ();
295 string intenv
= Environment::GetIntermediatePath () + "\\" + basepath
+ "\\" + vcdir
+ "\\";
296 string outenv
= Environment::GetOutputPath () + "\\" + basepath
+ "\\" + vcdir
+ "\\";
297 string dbg
= vcdir
.substr ( 0, 3 );
300 cfgs
.push_back ( intenv
+ "Debug" );
301 cfgs
.push_back ( intenv
+ "Release" );
302 cfgs
.push_back ( intenv
+ "Speed" );
303 cfgs
.push_back ( outenv
+ "Debug" );
304 cfgs
.push_back ( outenv
+ "Release" );
305 cfgs
.push_back ( outenv
+ "Speed" );
308 vector
<const IfableData
*> ifs_list
;
309 ifs_list
.push_back ( &module
.project
.non_if_data
);
310 ifs_list
.push_back ( &module
.non_if_data
);
311 while ( ifs_list
.size () )
313 const IfableData
& data
= *ifs_list
.back();
315 const vector
<File
*>& files
= data
.files
;
316 for ( i
= 0; i
< files
.size (); i
++ )
318 string file
= files
[i
]->name
;
319 string::size_type pos
= file
.find_last_of ("\\");
320 if ( pos
!= string::npos
)
321 file
.erase ( 0, pos
+1 );
322 if ( !stricmp ( Right(file
,3).c_str(), ".rc" ) )
323 file
= ReplaceExtension ( file
, ".res" );
325 file
= ReplaceExtension ( file
, ".obj" );
326 for ( size_t j
= 0; j
< cfgs
.size () / 2; j
++ )
327 out
.push_back ( cfgs
[j
] + "\\" + file
);
331 //common files in intermediate dir
332 for ( i
= 0; i
< cfgs
.size () / 2; i
++)
334 out
.push_back ( cfgs
[i
] + "\\" + "BuildLog.htm" );
335 out
.push_back ( cfgs
[i
] + "\\" + dbg
+ "0.pdb" );
336 out
.push_back ( cfgs
[i
] + "\\" + dbg
+ "0.idb" );
337 out
.push_back ( cfgs
[i
] + "\\" + module
.name
+ ".pch" );
339 //files in the output dir
340 for ( i
= cfgs
.size () / 2; i
< cfgs
.size (); i
++ )
342 out
.push_back ( cfgs
[i
] + "\\" + module
.GetTargetName () );
343 out
.push_back ( cfgs
[i
] + "\\" + module
.name
+ ".pdb" );
344 out
.push_back ( cfgs
[i
] + "\\" + module
.name
+ ".lib" );
345 out
.push_back ( cfgs
[i
] + "\\" + module
.name
+ ".exp" );
346 out
.push_back ( cfgs
[i
] + "\\" + module
.name
+ ".ilk" );
347 out
.push_back ( cfgs
[i
] + "\\" + "(InputName).obj" ); //MSVC2003 build bug
352 MSVCBackend::_clean_project_files ( void )
354 for ( size_t i
= 0; i
< ProjectNode
.modules
.size(); i
++ )
356 Module
& module
= *ProjectNode
.modules
[i
];
358 printf("Cleaning project %s %s %s\n", module
.name
.c_str (), module
.GetBasePath ().c_str (), NcbFileName ( module
).c_str () );
360 string basepath
= module
.GetBasePath ();
361 remove ( NcbFileName ( module
).c_str () );
362 remove ( DspFileName ( module
).c_str () );
363 remove ( DswFileName ( module
).c_str () );
364 remove ( OptFileName ( module
).c_str () );
365 remove ( SlnFileName ( module
).c_str () );
366 remove ( SuoFileName ( module
).c_str () );
367 remove ( VcprojFileName ( module
).c_str () );
369 _get_object_files ( module
, out
);
370 for ( size_t j
= 0; j
< out
.size (); j
++)
371 remove ( out
[j
].c_str () );
373 string filename_sln
= ProjectNode
.name
+ ".sln";
374 string filename_dsw
= ProjectNode
.name
+ ".dsw";
376 remove ( filename_sln
.c_str () );
377 remove ( filename_dsw
.c_str () );
381 MSVCBackend::_copy_file ( const std::string
& inputname
, const std::string
& targetname
) const
383 FILE * input
= fopen ( inputname
.c_str (), "rb" );
387 FILE * output
= fopen ( targetname
.c_str (), "wb+" );
396 while ( (num_read
= fread( buffer
, sizeof(char), 256, input
) ) || !feof( input
) )
397 fwrite( buffer
, sizeof(char), num_read
, output
);
405 MSVCBackend::_install_files (const std::string
& vcdir
, const::string
& config
)
407 for ( size_t i
= 0; i
< ProjectNode
.modules
.size(); i
++ )
409 Module
& module
= *ProjectNode
.modules
[i
];
410 if ( module
.installBase
== "" || module
.installName
== "" )
413 string inputname
= Environment::GetOutputPath () + "\\" + module
.GetBasePath () + "\\" + vcdir
+ "\\" + config
+ "\\" + module
.GetTargetName ();
414 string installdir
= Environment::GetInstallPath () + "\\" + module
.installBase
+ "\\" + module
.installName
;
415 if ( _copy_file( inputname
, installdir
) )
416 printf ("Installed File :'%s'\n",installdir
.c_str () );