cmDSPWriter.cxx 13 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$


  Copyright (c) 2000 National Library of Medicine
  All rights reserved.

  See COPYRIGHT.txt for copyright details.

=========================================================================*/
16
#include "cmDSPMakefile.h"
17
#include "cmStandardIncludes.h"
18
#include "cmSystemTools.h"
19
#include "cmRegularExpression.h"
20
#include "cmCacheManager.h"
Bill Hoffman's avatar
Bill Hoffman committed
21

22
23
24
25
cmDSPMakefile::~cmDSPMakefile()
{
}

26

27
28
29
30
cmDSPMakefile::cmDSPMakefile(cmMakefile*mf)
{
  m_Makefile = mf;
}
31

32
33
void cmDSPMakefile::OutputDSPFile()
{ 
Bill Hoffman's avatar
Bill Hoffman committed
34
35
36
37
38
39
40
41
42
43
44
45
  // If not an in source build, then create the output directory
  if(strcmp(m_Makefile->GetStartOutputDirectory(),
            m_Makefile->GetHomeDirectory()) != 0)
    {
    if(!cmSystemTools::MakeDirectory(m_Makefile->GetStartOutputDirectory()))
      {
      cmSystemTools::Error("Error creating directory ",
                           m_Makefile->GetStartOutputDirectory());
      }
    }

  // Setup /I and /LIBPATH options for the resulting DSP file
46
  std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
47
48
49
50
  std::vector<std::string>::iterator i;
  for(i = includes.begin(); i != includes.end(); ++i)
    {
    m_IncludeOptions +=  "/I \"";
51
    m_IncludeOptions += *i;
52
53
    m_IncludeOptions += "\" ";
    }
54
  std::vector<std::string>& libs = m_Makefile->GetLinkLibraries();
55
56
  for(i = libs.begin(); i != libs.end(); ++i)
    {
57
58
59
    m_LibraryOptions += " ";
    m_LibraryOptions += *i;
    m_LibraryOptions += ".lib ";
60
    }
61
  std::vector<std::string>& libswin32 = m_Makefile->GetLinkLibrariesWin32();
62
63
  for(i = libswin32.begin(); i != libswin32.end(); ++i)
    {
64
65
66
    m_LibraryOptions += " ";
    m_LibraryOptions += *i;
    m_LibraryOptions += ".lib ";
67
    }
68
  std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
69
70
  for(i = libdirs.begin(); i != libdirs.end(); ++i)
    {
71
72
73
    m_LibraryOptions += " /LIBPATH:\"";
    m_LibraryOptions += *i;
    m_LibraryOptions += "/$(OUTDIR)\" ";
74
    }
75
  m_LibraryOptions += "/STACK:10000000 ";
Bill Hoffman's avatar
Bill Hoffman committed
76
77
  
  // Create the DSP or set of DSP's for libraries and executables
Ken Martin's avatar
Ken Martin committed
78
  if(strlen(m_Makefile->GetLibraryName()) != 0)
79
    {
80
81
82
83
84
85
86
87
88
89
    const char* cacheValue
      = cmCacheManager::GetInstance()->GetCacheValue("BUILD_SHARED_LIBS");
    if(cacheValue && strcmp(cacheValue,"0"))
      {
      this->SetBuildType(DLL);
      }
    else
      {
      this->SetBuildType(STATIC_LIBRARY);
      }
90
91
    this->CreateSingleDSP();
    }
Ken Martin's avatar
Ken Martin committed
92
93
  // if there are executables build them
  if (m_Makefile->HasExecutables())
94
95
96
97
98
99
    {
    this->CreateExecutableDSPFiles();
    }
}
void cmDSPMakefile::CreateExecutableDSPFiles()
{
100
101
  std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
  for(int i = 0; i < Classes.size(); ++i)
102
    {
103
    cmClassFile& classfile = Classes[i];
Ken Martin's avatar
Ken Martin committed
104
    if (classfile.m_IsExecutable)
105
      {
Ken Martin's avatar
Ken Martin committed
106
107
108
109
110
111
112
      std::string fname = m_Makefile->GetStartOutputDirectory();
      fname += "/";
      fname += classfile.m_ClassName;
      fname += ".dsp";
      std::ofstream fout(fname.c_str());
      if(!fout)
        {
Bill Hoffman's avatar
Bill Hoffman committed
113
114
        cmSystemTools::Error("Error Writing ",
                             fname.c_str());
Ken Martin's avatar
Ken Martin committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
        }
      else
        {
        m_Makefile->SetLibraryName(classfile.m_ClassName.c_str());
        this->SetBuildType(EXECUTABLE);
        std::string pname = m_Makefile->GetLibraryName();
        m_CreatedProjectNames.push_back(pname);
        
        this->WriteDSPHeader(fout);
        this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
        this->WriteDSPBuildRule(fout, classfile.m_FullPath.c_str());
        this->WriteDSPEndGroup(fout);
        this->WriteDSPBuildRule(fout);
        this->WriteDSPFooter(fout);
        }
130
131
132
133
134
135
136
137
      }
    }
}


void cmDSPMakefile::CreateSingleDSP()
{
  std::string fname;
Ken Martin's avatar
Ken Martin committed
138
  fname = m_Makefile->GetStartOutputDirectory();
139
  fname += "/";
140
  fname += m_Makefile->GetLibraryName();
141
142
  fname += ".dsp";
  m_CreatedProjectNames.clear();
143
  std::string pname = m_Makefile->GetLibraryName();
144
145
146
147
  m_CreatedProjectNames.push_back(pname);
  std::ofstream fout(fname.c_str());
  if(!fout)
    {
Bill Hoffman's avatar
Bill Hoffman committed
148
149
    cmSystemTools::Error("Error Writing ",
                         fname.c_str());
150
    }
151
152
153
154
155
156
157
  this->WriteDSPFile(fout);
}

void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
{
  std::string dspname = *(m_CreatedProjectNames.end()-1);
  dspname += ".dsp";
Ken Martin's avatar
Ken Martin committed
158
  std::string makefileIn = m_Makefile->GetStartDirectory();
159
  makefileIn += "/";
160
  makefileIn += "CMakeLists.txt";
161
  std::string dsprule = m_Makefile->GetHomeDirectory();
162
  dsprule += "/CMake/Source/CMakeSetupCMD ";
163
164
  dsprule += makefileIn;
  dsprule += " -DSP -H";
165
  dsprule += m_Makefile->GetHomeDirectory();
Ken Martin's avatar
Ken Martin committed
166
167
  dsprule += " -S";
  dsprule += m_Makefile->GetStartDirectory();
168
  dsprule += " -O";
Ken Martin's avatar
Ken Martin committed
169
  dsprule += m_Makefile->GetStartOutputDirectory();
170
  dsprule += " -B";
Ken Martin's avatar
Ken Martin committed
171
  dsprule += m_Makefile->GetHomeOutputDirectory();
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  std::set<std::string> depends;
  std::set<std::string> outputs;
  outputs.insert(outputs.begin(), dspname);
  fout << "# Begin Source File\n\n";
  fout << "SOURCE=" << makefileIn.c_str() << "\n\n";
  this->WriteCustomRule(fout, dsprule.c_str(), depends, outputs);
  fout << "# End Source File\n";
}


void cmDSPMakefile::AddDSPBuildRule(cmSourceGroup& sourceGroup)
{
  std::string dspname = *(m_CreatedProjectNames.end()-1);
  dspname += ".dsp";
  std::string makefileIn = m_Makefile->GetStartDirectory();
  makefileIn += "/";
  makefileIn += "CMakeLists.txt";
  std::string dsprule = m_Makefile->GetHomeDirectory();
  dsprule += "/CMake/Source/CMakeSetupCMD ";
  dsprule += makefileIn;
  dsprule += " -DSP -H";
  dsprule += m_Makefile->GetHomeDirectory();
  dsprule += " -S";
  dsprule += m_Makefile->GetStartDirectory();
  dsprule += " -O";
  dsprule += m_Makefile->GetStartOutputDirectory();
  dsprule += " -B";
  dsprule += m_Makefile->GetHomeOutputDirectory();

202
  std::vector<std::string> depends;
203
204
205
206
  std::vector<std::string> outputs;
  outputs.push_back(dspname);
  sourceGroup.AddCustomCommand(makefileIn.c_str(), dsprule.c_str(),
                               depends, outputs);
207
208
}

209

210
211
void cmDSPMakefile::WriteDSPFile(std::ostream& fout)
{
212
  // Write the DSP file's header.
213
  this->WriteDSPHeader(fout);
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  
  // We may be modifying the source groups temporarily, so make a copy.
  std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
  
  // Find the group in which the CMakeLists.txt source belongs, and add
  // the rule to generate this DSP file.
  for(std::vector<cmSourceGroup>::reverse_iterator sg = sourceGroups.rbegin();
      sg != sourceGroups.rend(); ++sg)
    {
    if(sg->Matches("CMakeLists.txt"))
      {
      this->AddDSPBuildRule(*sg);
      break;
      }    
    }
  
  // Loop through every source group.
  for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
      sg != sourceGroups.end(); ++sg)
    {
    const std::vector<std::string>& sources = sg->GetSources();
    const cmSourceGroup::CustomCommands& customCommands = sg->GetCustomCommands();
    // If the group is empty, don't write it at all.
    if(sources.empty() && customCommands.empty())
      { continue; }
    
    // If the group has a name, write the header.
    std::string name = sg->GetName();
    if(name != "")
      {
      this->WriteDSPBeginGroup(fout, name.c_str(), "");
      }
    
    // Loop through each source in the source group.
    for(std::vector<std::string>::const_iterator s = sources.begin();
        s != sources.end(); ++s)
      {
      this->WriteDSPBuildRule(fout, s->c_str());
      }    
    
    // Loop through each custom command in the source group.
    for(cmSourceGroup::CustomCommands::const_iterator cc =
          customCommands.begin(); cc != customCommands.end(); ++ cc)
      {
      std::string source = cc->first;
      const cmSourceGroup::Commands& commands = cc->second;

      fout << "# Begin Source File\n\n";
      fout << "SOURCE=" << source << "\n\n";
      
      // Loop through every command generating code from the current source.
      for(cmSourceGroup::Commands::const_iterator c = commands.begin();
          c != commands.end(); ++c)
        {
        std::string command = c->first;
        const cmSourceGroup::CommandFiles& commandFiles = c->second;
        this->WriteCustomRule(fout, command.c_str(), commandFiles.m_Depends,
                              commandFiles.m_Outputs);
        }      
      
      fout << "# End Source File\n";
      }
    
    // If the group has a name, write the footer.
    if(name != "")
      {
      this->WriteDSPEndGroup(fout);
      }
    }  

  // Write the DSP file's footer.
285
286
287
288
289
  this->WriteDSPFooter(fout);
}


void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
290
                                    const char* command,
291
292
                                    const std::set<std::string>& depends,
                                    const std::set<std::string>& outputs)
293
{
294
295
296
297
298
299
300
301
302
303
304
305
  std::vector<std::string>::iterator i;
  for(i = m_Configurations.begin(); i != m_Configurations.end(); ++i)
    {
    if (i == m_Configurations.begin())
      {
      fout << "!IF  \"$(CFG)\" == " << i->c_str() << std::endl;
      }
    else 
      {
      fout << "!ELSEIF  \"$(CFG)\" == " << i->c_str() << std::endl;
      }
    fout << "# Begin Custom Build\n\n";
306
307
308
309
    
    // Write a rule for every output generated by this command.
    for(std::set<std::string>::const_iterator output = outputs.begin();
        output != outputs.end(); ++output)
310
      {
311
312
313
314
315
316
317
318
      fout << "\"" << output->c_str()
           << "\" :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"";
      // Write out all the dependencies for this rule.
      for(std::set<std::string>::const_iterator d = depends.begin();
          d != depends.end(); ++d)
        {
        fout << " \"" << d->c_str() << "\"";
        }
319
      fout << "\n  " << command << "\n\n";
320
      }
321
    
322
323
324
325
    fout << "# End Custom Build\n\n";
    }
  
  fout << "!ENDIF\n\n";
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
}


void cmDSPMakefile::WriteDSPBeginGroup(std::ostream& fout, 
					const char* group,
					const char* filter)
{
  fout << "# Begin Group \"" << group << "\"\n"
    "# PROP Default_Filter \"" << filter << "\"\n";
}


void cmDSPMakefile::WriteDSPEndGroup(std::ostream& fout)
{
  fout << "# End Group\n";
}




void cmDSPMakefile::SetBuildType(BuildType b)
{
348
  m_BuildType = b;
349
350
351
  switch(b)
    {
    case STATIC_LIBRARY:
352
      m_DSPHeaderTemplate = m_Makefile->GetHomeDirectory();
353
      m_DSPHeaderTemplate += "/CMake/Source/staticLibHeader.dsptemplate";
354
      m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
355
      m_DSPFooterTemplate += "/CMake/Source/staticLibFooter.dsptemplate";
356
357
      break;
    case DLL:
358
      m_DSPHeaderTemplate =  m_Makefile->GetHomeDirectory();
359
      m_DSPHeaderTemplate += "/CMake/Source/DLLHeader.dsptemplate";
360
      m_DSPFooterTemplate =  m_Makefile->GetHomeDirectory();
361
      m_DSPFooterTemplate += "/CMake/Source/DLLFooter.dsptemplate";
362
363
      break;
    case EXECUTABLE:
364
      m_DSPHeaderTemplate = m_Makefile->GetHomeDirectory();
365
      m_DSPHeaderTemplate += "/CMake/Source/EXEHeader.dsptemplate";
366
      m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
367
      m_DSPFooterTemplate += "/CMake/Source/EXEFooter.dsptemplate";
368
369
370
      break;
    }

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
  // once the build type is set, determine what configurations are
  // possible
  std::ifstream fin(m_DSPHeaderTemplate.c_str());
  cmRegularExpression reg("# Name ");
  if(!fin)
    {
    cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
    }
  char buffer[2048];
  while(fin)
    {
    fin.getline(buffer, 2048);
    std::string line = buffer;
    cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", 
                                 m_Makefile->GetLibraryName());
    if (reg.find(line))
      {
      m_Configurations.push_back(line.substr(reg.end()));
      }
    }
}
392
393
394
395
396
397
  
void cmDSPMakefile::WriteDSPHeader(std::ostream& fout)
{
  std::ifstream fin(m_DSPHeaderTemplate.c_str());
  if(!fin)
    {
Bill Hoffman's avatar
Bill Hoffman committed
398
    cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
399
400
    }
  char buffer[2048];
401

402
403
404
405
  while(fin)
    {
      fin.getline(buffer, 2048);
      std::string line = buffer;
406
407
      cmSystemTools::ReplaceString(line, "CM_LIBRARIES",
                                    m_LibraryOptions.c_str());
408
409
410
      cmSystemTools::ReplaceString(line, "BUILD_INCLUDES",
                                    m_IncludeOptions.c_str());
      cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", 
411
                                    m_Makefile->GetLibraryName());
412
      cmSystemTools::ReplaceString(line, 
413
414
                                    "EXTRA_DEFINES", 
				   m_Makefile->GetDefineFlags());
415
416
417
418
419
420
421
422
423
424
      fout << line.c_str() << std::endl;
    }
}


void cmDSPMakefile::WriteDSPFooter(std::ostream& fout)
{  
  std::ifstream fin(m_DSPFooterTemplate.c_str());
  if(!fin)
    {
Bill Hoffman's avatar
Bill Hoffman committed
425
426
    cmSystemTools::Error("Error Reading ",
                         m_DSPFooterTemplate.c_str());
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
    }
  char buffer[2048];
  while(fin)
    {
      fin.getline(buffer, 2048);
      fout << buffer << std::endl;
    }
}


void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout, const char* path)
{
  fout << "# Begin Source File\n\n";
  fout << "SOURCE=" 
       << path << "\n";
  fout << "# End Source File\n";
}