~ubuntu-branches/ubuntu/intrepid/cmake/intrepid-backports

« back to all changes in this revision

Viewing changes to Source/cmDSPWriter.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Maitland Bottoms
  • Date: 2002-02-14 18:36:25 UTC
  • Revision ID: james.westby@ubuntu.com-20020214183625-8m44isdas2k4l0f7
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=========================================================================
 
2
 
 
3
  Program:   Insight Segmentation & Registration Toolkit
 
4
  Module:    $RCSfile: cmDSPWriter.cxx,v $
 
5
  Language:  C++
 
6
  Date:      $Date: 2002/01/15 00:08:38 $
 
7
  Version:   $Revision: 1.92 $
 
8
 
 
9
Copyright (c) 2001 Insight Consortium
 
10
All rights reserved.
 
11
 
 
12
Redistribution and use in source and binary forms, with or without
 
13
modification, are permitted provided that the following conditions are met:
 
14
 
 
15
 * Redistributions of source code must retain the above copyright notice,
 
16
   this list of conditions and the following disclaimer.
 
17
 
 
18
 * Redistributions in binary form must reproduce the above copyright notice,
 
19
   this list of conditions and the following disclaimer in the documentation
 
20
   and/or other materials provided with the distribution.
 
21
 
 
22
 * The name of the Insight Consortium, nor the names of any consortium members,
 
23
   nor of any contributors, may be used to endorse or promote products derived
 
24
   from this software without specific prior written permission.
 
25
 
 
26
  * Modified source versions must be plainly marked as such, and must not be
 
27
    misrepresented as being the original software.
 
28
 
 
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
 
30
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
31
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
32
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
 
33
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
34
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
35
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
36
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
37
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
38
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
39
 
 
40
=========================================================================*/
 
41
#include "cmDSPWriter.h"
 
42
#include "cmStandardIncludes.h"
 
43
#include "cmSystemTools.h"
 
44
#include "cmRegularExpression.h"
 
45
 
 
46
cmDSPWriter::~cmDSPWriter()
 
47
{
 
48
}
 
49
 
 
50
 
 
51
cmDSPWriter::cmDSPWriter(cmMakefile*mf)
 
52
{
 
53
  m_Makefile = mf;
 
54
}
 
55
 
 
56
void cmDSPWriter::OutputDSPFile()
 
57
 
58
  // If not an in source build, then create the output directory
 
59
  if(strcmp(m_Makefile->GetStartOutputDirectory(),
 
60
            m_Makefile->GetHomeDirectory()) != 0)
 
61
    {
 
62
    if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
 
63
      {
 
64
      cmSystemTools::Error("Error creating directory ",
 
65
                           m_Makefile->GetStartOutputDirectory());
 
66
      }
 
67
    }
 
68
 
 
69
  // Setup /I and /LIBPATH options for the resulting DSP file
 
70
  std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
 
71
  std::vector<std::string>::iterator i;
 
72
  for(i = includes.begin(); i != includes.end(); ++i)
 
73
    {
 
74
    m_IncludeOptions +=  " /I ";
 
75
    std::string tmp = cmSystemTools::EscapeSpaces(i->c_str());
 
76
    cmSystemTools::ConvertToWindowsSlashesAndCleanUp(tmp);
 
77
 
 
78
    // quote if not already quoted
 
79
    if (tmp[0] != '"')
 
80
      {
 
81
      m_IncludeOptions += "\"";
 
82
      m_IncludeOptions += tmp;
 
83
      m_IncludeOptions += "\"";
 
84
      }
 
85
    else
 
86
      {
 
87
      m_IncludeOptions += tmp;
 
88
      }
 
89
    }
 
90
  
 
91
  // Create the DSP or set of DSP's for libraries and executables
 
92
 
 
93
  // clear project names
 
94
  m_CreatedProjectNames.clear();
 
95
 
 
96
  // build any targets
 
97
  cmTargets &tgts = m_Makefile->GetTargets();
 
98
  for(cmTargets::iterator l = tgts.begin(); 
 
99
      l != tgts.end(); l++)
 
100
    {
 
101
    switch(l->second.GetType())
 
102
      {
 
103
      case cmTarget::STATIC_LIBRARY:
 
104
        this->SetBuildType(STATIC_LIBRARY, l->first.c_str());
 
105
        break;
 
106
      case cmTarget::SHARED_LIBRARY:
 
107
        this->SetBuildType(DLL, l->first.c_str());
 
108
        break;
 
109
      case cmTarget::EXECUTABLE:
 
110
        this->SetBuildType(EXECUTABLE,l->first.c_str());
 
111
        break;
 
112
      case cmTarget::WIN32_EXECUTABLE:
 
113
        this->SetBuildType(WIN32_EXECUTABLE,l->first.c_str());
 
114
        break;
 
115
      case cmTarget::UTILITY:
 
116
        this->SetBuildType(UTILITY, l->first.c_str());
 
117
        break;
 
118
      case cmTarget::INSTALL_FILES:
 
119
        break;
 
120
      case cmTarget::INSTALL_PROGRAMS:
 
121
        break;
 
122
      default:
 
123
        cmSystemTools::Error("Bad target type", l->first.c_str());
 
124
        break;
 
125
      }
 
126
    // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
 
127
    // so don't build a projectfile for it
 
128
    if ((l->second.GetType() != cmTarget::INSTALL_FILES)
 
129
        && (l->second.GetType() != cmTarget::INSTALL_PROGRAMS)
 
130
        && (strncmp(l->first.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) != 0))
 
131
      {
 
132
      this->CreateSingleDSP(l->first.c_str(),l->second);
 
133
      }
 
134
    }
 
135
}
 
136
 
 
137
void cmDSPWriter::CreateSingleDSP(const char *lname, cmTarget &target)
 
138
{
 
139
  // add to the list of projects
 
140
  std::string pname = lname;
 
141
  m_CreatedProjectNames.push_back(pname);
 
142
  // create the dsp.cmake file
 
143
  std::string fname;
 
144
  fname = m_Makefile->GetStartOutputDirectory();
 
145
  fname += "/";
 
146
  fname += lname;
 
147
  fname += ".dsp";
 
148
  // save the name of the real dsp file
 
149
  std::string realDSP = fname;
 
150
  fname += ".cmake";
 
151
  std::ofstream fout(fname.c_str());
 
152
  if(!fout)
 
153
    {
 
154
    cmSystemTools::Error("Error Writing ", fname.c_str());
 
155
    }
 
156
  this->WriteDSPFile(fout,lname,target);
 
157
  fout.close();
 
158
  // if the dsp file has changed, then write it.
 
159
  cmSystemTools::CopyFileIfDifferent(fname.c_str(), realDSP.c_str());
 
160
}
 
161
 
 
162
 
 
163
void cmDSPWriter::AddDSPBuildRule(cmSourceGroup& sourceGroup)
 
164
{
 
165
  std::string dspname = *(m_CreatedProjectNames.end()-1);
 
166
  if(dspname == "ALL_BUILD")
 
167
  {
 
168
    return;
 
169
  }
 
170
  dspname += ".dsp.cmake";
 
171
  std::string makefileIn = m_Makefile->GetStartDirectory();
 
172
  makefileIn += "/";
 
173
  makefileIn += "CMakeLists.txt";
 
174
  makefileIn = cmSystemTools::HandleNetworkPaths(makefileIn.c_str());
 
175
  makefileIn = cmSystemTools::EscapeSpaces(makefileIn.c_str());
 
176
  std::string dsprule = "${CMAKE_COMMAND}";
 
177
  m_Makefile->ExpandVariablesInString(dsprule);
 
178
  dsprule = cmSystemTools::HandleNetworkPaths(dsprule.c_str());
 
179
  std::string args = makefileIn;
 
180
  args += " -H\"";
 
181
  args += cmSystemTools::HandleNetworkPaths(m_Makefile->GetHomeDirectory());
 
182
  args += "\" -S\"";
 
183
  args += cmSystemTools::HandleNetworkPaths(m_Makefile->GetStartDirectory());
 
184
  args += "\" -O\"";
 
185
  args += cmSystemTools::HandleNetworkPaths(m_Makefile->GetStartOutputDirectory());
 
186
  args += "\" -B\"";
 
187
  args += cmSystemTools::HandleNetworkPaths(m_Makefile->GetHomeOutputDirectory());
 
188
  args += "\"";
 
189
  m_Makefile->ExpandVariablesInString(args);
 
190
 
 
191
  std::string configFile = 
 
192
    m_Makefile->GetDefinition("CMAKE_ROOT");
 
193
  configFile += "/Templates/CMakeWindowsSystemConfig.cmake";
 
194
  std::vector<std::string> listFiles = m_Makefile->GetListFiles();
 
195
  bool found = false;
 
196
  for(std::vector<std::string>::iterator i = listFiles.begin();
 
197
      i != listFiles.end(); ++i)
 
198
    {
 
199
    if(*i == configFile)
 
200
      {
 
201
      found  = true;
 
202
      }
 
203
    }
 
204
  if(!found)
 
205
    {
 
206
    listFiles.push_back(configFile);
 
207
    }
 
208
  
 
209
  std::vector<std::string> outputs;
 
210
  outputs.push_back(dspname);
 
211
  cmCustomCommand cc(makefileIn.c_str(), dsprule.c_str(),
 
212
                     args.c_str(),
 
213
                     listFiles, 
 
214
                     outputs);
 
215
  sourceGroup.AddCustomCommand(cc);
 
216
}
 
217
 
 
218
 
 
219
void cmDSPWriter::WriteDSPFile(std::ostream& fout, 
 
220
                                 const char *libName,
 
221
                                 cmTarget &target)
 
222
{
 
223
  // We may be modifying the source groups temporarily, so make a copy.
 
224
  std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
 
225
  
 
226
  // get the classes from the source lists then add them to the groups
 
227
  std::vector<cmSourceFile> classes = target.GetSourceFiles();
 
228
  for(std::vector<cmSourceFile>::iterator i = classes.begin(); 
 
229
      i != classes.end(); i++)
 
230
    {
 
231
    if(!i->IsAHeaderFileOnly())
 
232
      {
 
233
      // Add the file to the list of sources.
 
234
      std::string source = i->GetFullPath();
 
235
      cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
 
236
                                                               sourceGroups);
 
237
      sourceGroup.AddSource(source.c_str());
 
238
      }
 
239
    }
 
240
  
 
241
  // add any custom rules to the source groups
 
242
  for (std::vector<cmCustomCommand>::const_iterator cr = 
 
243
         target.GetCustomCommands().begin(); 
 
244
       cr != target.GetCustomCommands().end(); ++cr)
 
245
    {
 
246
    cmSourceGroup& sourceGroup = 
 
247
      m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
 
248
                                  sourceGroups);
 
249
    cmCustomCommand cc(*cr);
 
250
    cc.ExpandVariables(*m_Makefile);
 
251
    sourceGroup.AddCustomCommand(cc);
 
252
    }
 
253
  
 
254
  // Write the DSP file's header.
 
255
  this->WriteDSPHeader(fout, libName, target, sourceGroups);
 
256
  
 
257
  // Find the group in which the CMakeLists.txt source belongs, and add
 
258
  // the rule to generate this DSP file.
 
259
  for(std::vector<cmSourceGroup>::reverse_iterator sg = sourceGroups.rbegin();
 
260
      sg != sourceGroups.rend(); ++sg)
 
261
    {
 
262
    if(sg->Matches("CMakeLists.txt"))
 
263
      {
 
264
      this->AddDSPBuildRule(*sg);
 
265
      break;
 
266
      }    
 
267
    }
 
268
  
 
269
  // Loop through every source group.
 
270
  for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
 
271
      sg != sourceGroups.end(); ++sg)
 
272
    {
 
273
    const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
 
274
    // If the group is empty, don't write it at all.
 
275
    if(buildRules.empty())
 
276
      { continue; }
 
277
    
 
278
    // If the group has a name, write the header.
 
279
    std::string name = sg->GetName();
 
280
    if(name != "")
 
281
      {
 
282
      this->WriteDSPBeginGroup(fout, name.c_str(), "");
 
283
      }
 
284
    
 
285
    // Loop through each build rule in the source group.
 
286
    for(cmSourceGroup::BuildRules::const_iterator cc =
 
287
          buildRules.begin(); cc != buildRules.end(); ++ cc)
 
288
      {
 
289
      std::string source = cc->first;
 
290
      const cmSourceGroup::Commands& commands = cc->second;
 
291
 
 
292
      if (source != libName || target.GetType() == cmTarget::UTILITY)
 
293
        {
 
294
        fout << "# Begin Source File\n\n";
 
295
        
 
296
        // Tell MS-Dev what the source is.  If the compiler knows how to
 
297
        // build it, then it will.
 
298
        fout << "SOURCE=" << cmSystemTools::EscapeSpaces(source.c_str()) << "\n\n";
 
299
        if (!commands.empty())
 
300
          {
 
301
          cmSourceGroup::CommandFiles totalCommand;
 
302
          std::string totalCommandStr;
 
303
          totalCommandStr = this->CombineCommands(commands, totalCommand,
 
304
                                                  source.c_str());
 
305
          this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(), 
 
306
                                totalCommand.m_Depends, 
 
307
                                totalCommand.m_Outputs);
 
308
          }
 
309
        fout << "# End Source File\n";
 
310
        }
 
311
      }
 
312
    
 
313
    // If the group has a name, write the footer.
 
314
    if(name != "")
 
315
      {
 
316
      this->WriteDSPEndGroup(fout);
 
317
      }
 
318
    }  
 
319
 
 
320
  // Write the DSP file's footer.
 
321
  this->WriteDSPFooter(fout);
 
322
}
 
323
 
 
324
 
 
325
void cmDSPWriter::WriteCustomRule(std::ostream& fout,
 
326
                                    const char* source,
 
327
                                    const char* command,
 
328
                                    const std::set<std::string>& depends,
 
329
                                    const std::set<std::string>& outputs)
 
330
{
 
331
  std::vector<std::string>::iterator i;
 
332
  for(i = m_Configurations.begin(); i != m_Configurations.end(); ++i)
 
333
    {
 
334
    if (i == m_Configurations.begin())
 
335
      {
 
336
      fout << "!IF  \"$(CFG)\" == " << i->c_str() << std::endl;
 
337
      }
 
338
    else 
 
339
      {
 
340
      fout << "!ELSEIF  \"$(CFG)\" == " << i->c_str() << std::endl;
 
341
      }
 
342
    
 
343
    // Write out the dependencies for the rule.
 
344
    fout << "USERDEP__HACK=";
 
345
    std::string temp;
 
346
    for(std::set<std::string>::const_iterator d = depends.begin();
 
347
        d != depends.end(); ++d)
 
348
      {
 
349
      temp = *d;
 
350
      fout << "\\\n\t" << cmSystemTools::EscapeSpaces(cmSystemTools::ConvertToWindowsSlashes(temp));
 
351
      }
 
352
    fout << "\n";
 
353
 
 
354
    fout << "# PROP Ignore_Default_Tool 1\n";
 
355
    fout << "# Begin Custom Build\n\n";
 
356
    if(outputs.size() == 0)
 
357
      {
 
358
      fout << source << "_force :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
 
359
      fout << command << "\n\n";
 
360
      }
 
361
    
 
362
    // Write a rule for every output generated by this command.
 
363
    for(std::set<std::string>::const_iterator output = outputs.begin();
 
364
        output != outputs.end(); ++output)
 
365
      {
 
366
      fout << "\"" << output->c_str()
 
367
           << "\" :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
 
368
      fout << command << "\n\n";
 
369
      }
 
370
    
 
371
    fout << "# End Custom Build\n\n";
 
372
    }
 
373
  
 
374
  fout << "!ENDIF\n\n";
 
375
}
 
376
 
 
377
 
 
378
void cmDSPWriter::WriteDSPBeginGroup(std::ostream& fout, 
 
379
                                        const char* group,
 
380
                                        const char* filter)
 
381
{
 
382
  fout << "# Begin Group \"" << group << "\"\n"
 
383
    "# PROP Default_Filter \"" << filter << "\"\n";
 
384
}
 
385
 
 
386
 
 
387
void cmDSPWriter::WriteDSPEndGroup(std::ostream& fout)
 
388
{
 
389
  fout << "# End Group\n";
 
390
}
 
391
 
 
392
 
 
393
 
 
394
 
 
395
void cmDSPWriter::SetBuildType(BuildType b, const char *libName)
 
396
{
 
397
  std::string root= m_Makefile->GetDefinition("CMAKE_ROOT");
 
398
  const char *def= m_Makefile->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY");
 
399
 
 
400
  if( def)
 
401
    {
 
402
    root = def;
 
403
    }
 
404
  else
 
405
    {
 
406
    root += "/Templates";
 
407
    }
 
408
  
 
409
  switch(b)
 
410
    {
 
411
    case STATIC_LIBRARY:
 
412
      m_DSPHeaderTemplate = root;
 
413
      m_DSPHeaderTemplate += "/staticLibHeader.dsptemplate";
 
414
      m_DSPFooterTemplate = root;
 
415
      m_DSPFooterTemplate += "/staticLibFooter.dsptemplate";
 
416
      break;
 
417
    case DLL:
 
418
      m_DSPHeaderTemplate =  root;
 
419
      m_DSPHeaderTemplate += "/DLLHeader.dsptemplate";
 
420
      m_DSPFooterTemplate =  root;
 
421
      m_DSPFooterTemplate += "/DLLFooter.dsptemplate";
 
422
      break;
 
423
    case EXECUTABLE:
 
424
      m_DSPHeaderTemplate = root;
 
425
      m_DSPHeaderTemplate += "/EXEHeader.dsptemplate";
 
426
      m_DSPFooterTemplate = root;
 
427
      m_DSPFooterTemplate += "/EXEFooter.dsptemplate";
 
428
      break;
 
429
    case WIN32_EXECUTABLE:
 
430
      m_DSPHeaderTemplate = root;
 
431
      m_DSPHeaderTemplate += "/EXEWinHeader.dsptemplate";
 
432
      m_DSPFooterTemplate = root;
 
433
      m_DSPFooterTemplate += "/EXEFooter.dsptemplate";
 
434
      break;
 
435
    case UTILITY:
 
436
      m_DSPHeaderTemplate = root;
 
437
      m_DSPHeaderTemplate += "/UtilityHeader.dsptemplate";
 
438
      m_DSPFooterTemplate = root;
 
439
      m_DSPFooterTemplate += "/UtilityFooter.dsptemplate";
 
440
      break;
 
441
    }
 
442
 
 
443
  // once the build type is set, determine what configurations are
 
444
  // possible
 
445
  std::ifstream fin(m_DSPHeaderTemplate.c_str());
 
446
 
 
447
  cmRegularExpression reg("# Name ");
 
448
  if(!fin)
 
449
    {
 
450
    cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
 
451
    }
 
452
 
 
453
  // reset m_Configurations
 
454
  m_Configurations.erase(m_Configurations.begin(), m_Configurations.end());
 
455
  // now add all the configurations possible
 
456
  char buffer[2048];
 
457
  while(fin)
 
458
    {
 
459
    fin.getline(buffer, 2048);
 
460
    std::string line = buffer;
 
461
    cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME",libName);
 
462
    if (reg.find(line))
 
463
      {
 
464
      m_Configurations.push_back(line.substr(reg.end()));
 
465
      }
 
466
    }
 
467
}
 
468
 
 
469
std::string
 
470
cmDSPWriter::CombineCommands(const cmSourceGroup::Commands &commands,
 
471
                             cmSourceGroup::CommandFiles &totalCommand,
 
472
                             const char *source)
 
473
  
 
474
{
 
475
  // Loop through every custom command generating code from the
 
476
  // current source.
 
477
  // build up the depends and outputs and commands 
 
478
  std::string totalCommandStr = "";
 
479
  std::string temp;
 
480
  for(cmSourceGroup::Commands::const_iterator c = commands.begin();
 
481
      c != commands.end(); ++c)
 
482
    {
 
483
    totalCommandStr += "\n\t";
 
484
    temp= c->second.m_Command; 
 
485
    cmSystemTools::ConvertToWindowsSlashes(temp);
 
486
    temp = cmSystemTools::EscapeSpaces(temp.c_str());
 
487
    totalCommandStr += temp;
 
488
    totalCommandStr += " ";
 
489
    totalCommandStr += c->second.m_Arguments;
 
490
    totalCommand.Merge(c->second);
 
491
    }      
 
492
  // Create a dummy file with the name of the source if it does
 
493
  // not exist
 
494
  if(totalCommand.m_Outputs.empty())
 
495
    { 
 
496
    std::string dummyFile = m_Makefile->GetStartOutputDirectory();
 
497
    dummyFile += "/";
 
498
    dummyFile += source;
 
499
    if(!cmSystemTools::FileExists(dummyFile.c_str()))
 
500
      {
 
501
      std::ofstream fout(dummyFile.c_str());
 
502
      fout << "Dummy file created by cmake as unused source for utility command.\n";
 
503
      }
 
504
    }
 
505
  return totalCommandStr;
 
506
}
 
507
 
 
508
 
 
509
// look for custom rules on a target and collect them together
 
510
std::string 
 
511
cmDSPWriter::CreateTargetRules(const cmTarget &target, 
 
512
                               const char *libName)
 
513
{
 
514
  std::string customRuleCode = "";
 
515
 
 
516
  if (target.GetType() >= cmTarget::UTILITY)
 
517
    {
 
518
    return customRuleCode;
 
519
    }
 
520
  
 
521
  // Find the group in which the lix exe custom rules belong
 
522
  bool init = false;
 
523
  for (std::vector<cmCustomCommand>::const_iterator cr = 
 
524
         target.GetCustomCommands().begin(); 
 
525
       cr != target.GetCustomCommands().end(); ++cr)
 
526
    {
 
527
    cmCustomCommand cc(*cr);
 
528
    cc.ExpandVariables(*m_Makefile);
 
529
    if (cc.GetSourceName() == libName)
 
530
      {
 
531
      if (!init)
 
532
        {
 
533
        // header stuff
 
534
        customRuleCode = "# Begin Special Build Tool\nPostBuild_Cmds=";
 
535
        init = true;
 
536
        }
 
537
      else
 
538
        {
 
539
        customRuleCode += "\t";
 
540
        }
 
541
      customRuleCode += cc.GetCommand() + " " + cc.GetArguments();
 
542
      }
 
543
    }
 
544
 
 
545
  if (init)
 
546
    {
 
547
    customRuleCode += "\n# End Special Build Tool\n";
 
548
    }
 
549
  return customRuleCode;
 
550
}
 
551
 
 
552
void cmDSPWriter::WriteDSPHeader(std::ostream& fout, const char *libName,
 
553
                                   const cmTarget &target, 
 
554
                                 std::vector<cmSourceGroup> &)
 
555
{
 
556
  // determine the link directories
 
557
  std::string libOptions;
 
558
  std::string libDebugOptions;
 
559
  std::string libOptimizedOptions;
 
560
 
 
561
  std::string libMultiLineOptions;
 
562
  std::string libMultiLineDebugOptions;
 
563
  std::string libMultiLineOptimizedOptions;
 
564
 
 
565
  // suppoirt override in output directory
 
566
  std::string libPath = "";
 
567
  if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
 
568
    {
 
569
    libPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
 
570
    }
 
571
  std::string exePath = "";
 
572
  if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
 
573
    {
 
574
    exePath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
 
575
    }
 
576
 
 
577
  if(libPath.size())
 
578
    {
 
579
    // make sure there is a trailing slash
 
580
    if(libPath[libPath.size()-1] != '/')
 
581
      {
 
582
      libPath += "/";
 
583
      }
 
584
    libOptions += " /LIBPATH:\"";
 
585
    libOptions += cmSystemTools::HandleNetworkPaths(libPath.c_str());
 
586
    libOptions += "$(INTDIR)\" ";
 
587
    libOptions += " /LIBPATH:\"";
 
588
    libOptions += cmSystemTools::HandleNetworkPaths(libPath.c_str());
 
589
    libOptions += "\" ";
 
590
    libMultiLineOptions += "# ADD LINK32 /LIBPATH:\"";
 
591
    libMultiLineOptions += cmSystemTools::HandleNetworkPaths(libPath.c_str()); 
 
592
    libMultiLineOptions += "$(INTDIR)\" ";
 
593
    libMultiLineOptions += " /LIBPATH:\"";
 
594
    libMultiLineOptions += cmSystemTools::HandleNetworkPaths(libPath.c_str()); 
 
595
    libMultiLineOptions += "\" \n";
 
596
    }
 
597
  if(exePath.size())
 
598
    {
 
599
    // make sure there is a trailing slash
 
600
    if(exePath[exePath.size()-1] != '/')
 
601
      {
 
602
      exePath += "/";
 
603
      }
 
604
    libOptions += " /LIBPATH:\"";
 
605
    libOptions += cmSystemTools::HandleNetworkPaths(exePath.c_str());
 
606
    libOptions += "$(INTDIR)\" ";
 
607
    libOptions += " /LIBPATH:\"";
 
608
    libOptions += cmSystemTools::HandleNetworkPaths(exePath.c_str());
 
609
    libOptions += "\" ";
 
610
    libMultiLineOptions += "# ADD LINK32 /LIBPATH:\"";
 
611
    libMultiLineOptions += cmSystemTools::HandleNetworkPaths(exePath.c_str()); 
 
612
    libMultiLineOptions += "$(INTDIR)\" ";
 
613
    libMultiLineOptions += " /LIBPATH:\"";
 
614
    libMultiLineOptions += cmSystemTools::HandleNetworkPaths(exePath.c_str());
 
615
    libMultiLineOptions += "\" \n";
 
616
    }
 
617
  std::vector<std::string>::iterator i;
 
618
  std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
 
619
  for(i = libdirs.begin(); i != libdirs.end(); ++i)
 
620
    {
 
621
    libOptions += " /LIBPATH:\"";
 
622
    libOptions += cmSystemTools::HandleNetworkPaths(i->c_str());
 
623
    libOptions += "/$(INTDIR)\" ";
 
624
    libOptions += " /LIBPATH:\"";
 
625
    libOptions += cmSystemTools::HandleNetworkPaths(i->c_str());
 
626
    libOptions += "\" ";
 
627
 
 
628
    libMultiLineOptions += "# ADD LINK32 /LIBPATH:\"";
 
629
    libMultiLineOptions += cmSystemTools::HandleNetworkPaths(i->c_str()); 
 
630
    libMultiLineOptions += "/$(INTDIR)\" ";
 
631
    libMultiLineOptions += " /LIBPATH:\"";
 
632
    libMultiLineOptions += cmSystemTools::HandleNetworkPaths(i->c_str());
 
633
    libMultiLineOptions += "\" \n";
 
634
    }
 
635
  // find link libraries
 
636
  const cmTarget::LinkLibraries& libs = target.GetLinkLibraries();
 
637
  cmTarget::LinkLibraries::const_iterator j;
 
638
  for(j = libs.begin(); j != libs.end(); ++j)
 
639
    {
 
640
    // add libraries to executables and dlls (but never include
 
641
    // a library in a library, bad recursion)
 
642
    if ((target.GetType() != cmTarget::SHARED_LIBRARY
 
643
         && target.GetType() != cmTarget::STATIC_LIBRARY) || 
 
644
        (target.GetType() == cmTarget::SHARED_LIBRARY && libName != j->first))
 
645
      {
 
646
      std::string lib = j->first;
 
647
      if(j->first.find(".lib") == std::string::npos)
 
648
        {
 
649
        lib += ".lib";
 
650
        }
 
651
      lib = cmSystemTools::EscapeSpaces(lib.c_str());
 
652
 
 
653
      if (j->second == cmTarget::GENERAL)
 
654
        {
 
655
        libOptions += " ";
 
656
        libOptions += lib;
 
657
        
 
658
        libMultiLineOptions += "# ADD LINK32 ";
 
659
        libMultiLineOptions +=  lib;
 
660
        libMultiLineOptions += "\n";
 
661
        }
 
662
      if (j->second == cmTarget::DEBUG)
 
663
        {
 
664
        libDebugOptions += " ";
 
665
        libDebugOptions += lib;
 
666
 
 
667
        libMultiLineDebugOptions += "# ADD LINK32 ";
 
668
        libMultiLineDebugOptions += lib;
 
669
        libMultiLineDebugOptions += "\n";
 
670
        }
 
671
      if (j->second == cmTarget::OPTIMIZED)
 
672
        {
 
673
        libOptimizedOptions += " ";
 
674
        libOptimizedOptions += lib;
 
675
 
 
676
        libMultiLineOptimizedOptions += "# ADD LINK32 ";
 
677
        libMultiLineOptimizedOptions += lib;
 
678
        libMultiLineOptimizedOptions += "\n";
 
679
        }      
 
680
      }
 
681
    }
 
682
  std::string extraLinkOptions = 
 
683
    m_Makefile->GetDefinition("CMAKE_EXTRA_LINK_FLAGS");
 
684
  if(extraLinkOptions.size())
 
685
    {
 
686
    libOptions += " ";
 
687
    libOptions += extraLinkOptions;
 
688
    libOptions += " ";
 
689
    libMultiLineOptions += "# ADD LINK32 ";
 
690
    libMultiLineOptions +=  extraLinkOptions;
 
691
    libMultiLineOptions += " \n";
 
692
    }
 
693
  
 
694
  // are there any custom rules on the target itself
 
695
  // only if the target is a lib or exe
 
696
  std::string customRuleCode = this->CreateTargetRules(target, libName);
 
697
 
 
698
  std::ifstream fin(m_DSPHeaderTemplate.c_str());
 
699
  if(!fin)
 
700
    {
 
701
    cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
 
702
    }
 
703
  char buffer[2048];
 
704
 
 
705
  while(fin)
 
706
    {
 
707
      fin.getline(buffer, 2048);
 
708
      std::string line = buffer;
 
709
      const char* mfcFlag = m_Makefile->GetDefinition("CMAKE_MFC_FLAG");
 
710
      if(!mfcFlag)
 
711
        {
 
712
        mfcFlag = "0";
 
713
        }
 
714
      cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE",
 
715
                                   customRuleCode.c_str());
 
716
      cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
 
717
                                   mfcFlag);
 
718
      cmSystemTools::ReplaceString(line, "CM_LIBRARIES",
 
719
                                   libOptions.c_str());
 
720
      cmSystemTools::ReplaceString(line, "CM_DEBUG_LIBRARIES",
 
721
                                   libDebugOptions.c_str());
 
722
      cmSystemTools::ReplaceString(line, "CM_OPTIMIZED_LIBRARIES",
 
723
                                   libOptimizedOptions.c_str());
 
724
 
 
725
      cmSystemTools::ReplaceString(line, "CM_MULTILINE_LIBRARIES",
 
726
                                   libMultiLineOptions.c_str());
 
727
      cmSystemTools::ReplaceString(line, "CM_MULTILINE_DEBUG_LIBRARIES",
 
728
                                   libMultiLineDebugOptions.c_str());
 
729
      cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIMIZED_LIBRARIES",
 
730
                                   libMultiLineOptimizedOptions.c_str());
 
731
 
 
732
      cmSystemTools::ReplaceString(line, "BUILD_INCLUDES",
 
733
                                   m_IncludeOptions.c_str());
 
734
      cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME",libName);
 
735
      cmSystemTools::ReplaceString(line, "LIBRARY_OUTPUT_PATH",
 
736
                                   cmSystemTools::HandleNetworkPaths(libPath.c_str()).c_str());
 
737
      cmSystemTools::ReplaceString(line, "EXECUTABLE_OUTPUT_PATH",
 
738
                                   cmSystemTools::HandleNetworkPaths(exePath.c_str()).c_str());
 
739
      cmSystemTools::ReplaceString(line, 
 
740
                                   "EXTRA_DEFINES", 
 
741
                                   m_Makefile->GetDefineFlags());
 
742
      cmSystemTools::ReplaceString(line,
 
743
                                   "CMAKE_CXX_FLAGS_RELEASE",
 
744
                                   m_Makefile->
 
745
                                   GetDefinition("CMAKE_CXX_FLAGS_RELEASE"));
 
746
      cmSystemTools::ReplaceString(line,
 
747
                                   "CMAKE_CXX_FLAGS_MINSIZEREL",
 
748
                                   m_Makefile->
 
749
                                   GetDefinition("CMAKE_CXX_FLAGS_MINSIZEREL")
 
750
        );
 
751
      cmSystemTools::ReplaceString(line,
 
752
                                   "CMAKE_CXX_FLAGS_DEBUG",
 
753
                                   m_Makefile->
 
754
                                   GetDefinition("CMAKE_CXX_FLAGS_DEBUG"));
 
755
      cmSystemTools::ReplaceString(line,
 
756
                                   "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
 
757
                                   m_Makefile->
 
758
                                   GetDefinition("CMAKE_CXX_FLAGS_RELWITHDEBINFO"));
 
759
      cmSystemTools::ReplaceString(line,
 
760
                                   "CMAKE_CXX_FLAGS",
 
761
                                   m_Makefile->
 
762
                                   GetDefinition("CMAKE_CXX_FLAGS"));
 
763
      
 
764
      fout << line.c_str() << std::endl;
 
765
    }
 
766
}
 
767
 
 
768
 
 
769
void cmDSPWriter::WriteDSPFooter(std::ostream& fout)
 
770
{  
 
771
  std::ifstream fin(m_DSPFooterTemplate.c_str());
 
772
  if(!fin)
 
773
    {
 
774
    cmSystemTools::Error("Error Reading ",
 
775
                         m_DSPFooterTemplate.c_str());
 
776
    }
 
777
  char buffer[2048];
 
778
  while(fin)
 
779
    {
 
780
      fin.getline(buffer, 2048);
 
781
      fout << buffer << std::endl;
 
782
    }
 
783
}