cmDSPMakefile.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
57
58
59
60
  for(i = libs.begin(); i != libs.end(); ++i)
    {
    m_DebugLibraryOptions += " ";
    m_DebugLibraryOptions += *i;
    m_DebugLibraryOptions += ".lib ";
    }
61
  std::vector<std::string>& libswin32 = m_Makefile->GetLinkLibrariesWin32();
62
63
64
65
66
67
  for(i = libswin32.begin(); i != libswin32.end(); ++i)
    {
    m_DebugLibraryOptions += " ";
    m_DebugLibraryOptions += *i;
    m_DebugLibraryOptions += ".lib ";
    }
68
  std::vector<std::string>& libdirs = m_Makefile->GetLinkDirectories();
69
70
71
72
73
74
75
76
77
78
79
80
81
  for(i = libdirs.begin(); i != libdirs.end(); ++i)
    {
    m_DebugLibraryOptions += " /LIBPATH:\"";
    m_DebugLibraryOptions += *i;
    if(i->find("Debug") == std::string::npos)
      {
      if(i->find("Release") == std::string::npos)
	{
	m_DebugLibraryOptions += "/Debug\" ";
	}
      }
    }
  m_DebugLibraryOptions += "/STACK:10000000 ";
82
  // add any extra define flags 
83
84
  m_ReleaseLibraryOptions = m_DebugLibraryOptions;
  cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release");
85
86
87
88
89
90
91
  m_DebugDLLLibraryOptions = m_DebugLibraryOptions;
  cmSystemTools::ReplaceString(m_DebugDLLLibraryOptions, "Debug", "DebugDLL");
  m_ReleaseDLLLibraryOptions = m_DebugDLLLibraryOptions;
  cmSystemTools::ReplaceString(m_ReleaseDLLLibraryOptions, "Debug", "Release");
  m_ReleaseMinSizeLibraryOptions = m_ReleaseLibraryOptions;
  cmSystemTools::ReplaceString(m_ReleaseMinSizeLibraryOptions, 
                               "Release", "ReleaseMinSize");
Bill Hoffman's avatar
Bill Hoffman committed
92
93
  
  // Create the DSP or set of DSP's for libraries and executables
Ken Martin's avatar
Ken Martin committed
94
  if(strlen(m_Makefile->GetLibraryName()) != 0)
95
    {
96
97
98
99
100
101
102
103
104
105
    const char* cacheValue
      = cmCacheManager::GetInstance()->GetCacheValue("BUILD_SHARED_LIBS");
    if(cacheValue && strcmp(cacheValue,"0"))
      {
      this->SetBuildType(DLL);
      }
    else
      {
      this->SetBuildType(STATIC_LIBRARY);
      }
106
107
    this->CreateSingleDSP();
    }
Ken Martin's avatar
Ken Martin committed
108
109
  // if there are executables build them
  if (m_Makefile->HasExecutables())
110
111
112
113
114
115
    {
    this->CreateExecutableDSPFiles();
    }
}
void cmDSPMakefile::CreateExecutableDSPFiles()
{
116
117
  std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
  for(int i = 0; i < Classes.size(); ++i)
118
    {
119
    cmClassFile& classfile = Classes[i];
Ken Martin's avatar
Ken Martin committed
120
    if (classfile.m_IsExecutable)
121
      {
Ken Martin's avatar
Ken Martin committed
122
123
124
125
126
127
128
      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
129
130
        cmSystemTools::Error("Error Writing ",
                             fname.c_str());
Ken Martin's avatar
Ken Martin committed
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
        }
      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);
        }
146
147
148
149
150
151
152
153
      }
    }
}


void cmDSPMakefile::CreateSingleDSP()
{
  std::string fname;
Ken Martin's avatar
Ken Martin committed
154
  fname = m_Makefile->GetStartOutputDirectory();
155
  fname += "/";
156
  fname += m_Makefile->GetLibraryName();
157
158
  fname += ".dsp";
  m_CreatedProjectNames.clear();
159
  std::string pname = m_Makefile->GetLibraryName();
160
161
162
163
  m_CreatedProjectNames.push_back(pname);
  std::ofstream fout(fname.c_str());
  if(!fout)
    {
Bill Hoffman's avatar
Bill Hoffman committed
164
165
    cmSystemTools::Error("Error Writing ",
                         fname.c_str());
166
    }
167
168
169
170
171
172
173
  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
174
  std::string makefileIn = m_Makefile->GetStartDirectory();
175
  makefileIn += "/";
176
  makefileIn += "CMakeLists.txt";
177
  std::string dsprule = m_Makefile->GetHomeDirectory();
178
  dsprule += "/CMake/Source/CMakeSetupCMD ";
179
180
  dsprule += makefileIn;
  dsprule += " -DSP -H";
181
  dsprule += m_Makefile->GetHomeDirectory();
Ken Martin's avatar
Ken Martin committed
182
183
  dsprule += " -S";
  dsprule += m_Makefile->GetStartDirectory();
184
  dsprule += " -O";
Ken Martin's avatar
Ken Martin committed
185
  dsprule += m_Makefile->GetStartOutputDirectory();
186
  dsprule += " -B";
Ken Martin's avatar
Ken Martin committed
187
  dsprule += m_Makefile->GetHomeOutputDirectory();
188
189

  std::vector<std::string> depends;
190
191
  this->WriteCustomRule(fout, makefileIn.c_str(), 
			dspname.c_str(),
192
193
			dsprule.c_str(),
			depends);
194
195
196
197
198
199
}

void cmDSPMakefile::WriteDSPFile(std::ostream& fout)
{
  this->WriteDSPHeader(fout);
  this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
200
201
202
203
  this->WriteDSPBuildRules(fout,"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
  this->WriteDSPEndGroup(fout);
  this->WriteDSPBeginGroup(fout, "Header Files", "h;hpp;hxx;hm;inl");
  this->WriteDSPBuildRules(fout,"h;hpp;hxx;hm;inl");
204
  this->WriteDSPEndGroup(fout);
205
206
207
  this->WriteDSPBeginGroup(fout, "XML Files", "xml");
  this->WriteDSPBuildRules(fout,"xml");
  this->WriteDSPEndGroup(fout);
208
209
210
211
212
213
  this->WriteDSPBuildRule(fout);
  this->WriteDSPFooter(fout);
}


void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
214
215
                                    const char* source,
                                    const char* result,
216
217
                                    const char* command,
                                    std::vector<std::string>& depends)
218
219
220
{
  fout << "# Begin Source File\n\n";
  fout << "SOURCE=" << source << "\n\n";
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

  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";
    fout << '\"' << result << "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\" ";
    for (int i = 0; i < depends.size(); i++)
      {
      fout << "\"" << depends[i].c_str() << "\" ";
      }
    fout << "\n  " << command << "\n\n";
    fout << "# End Custom Build\n\n";
    }
  
  fout << "!ENDIF\n\n";
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
  fout << "# End Source File\n";
}


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)
{
267
  m_BuildType = b;
268
269
270
  switch(b)
    {
    case STATIC_LIBRARY:
271
      m_DSPHeaderTemplate = m_Makefile->GetHomeDirectory();
272
      m_DSPHeaderTemplate += "/CMake/Source/staticLibHeader.dsptemplate";
273
      m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
274
      m_DSPFooterTemplate += "/CMake/Source/staticLibFooter.dsptemplate";
275
276
      break;
    case DLL:
277
      m_DSPHeaderTemplate =  m_Makefile->GetHomeDirectory();
278
      m_DSPHeaderTemplate += "/CMake/Source/DLLHeader.dsptemplate";
279
      m_DSPFooterTemplate =  m_Makefile->GetHomeDirectory();
280
      m_DSPFooterTemplate += "/CMake/Source/DLLFooter.dsptemplate";
281
282
      break;
    case EXECUTABLE:
283
      m_DSPHeaderTemplate = m_Makefile->GetHomeDirectory();
284
      m_DSPHeaderTemplate += "/CMake/Source/EXEHeader.dsptemplate";
285
      m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
286
      m_DSPFooterTemplate += "/CMake/Source/EXEFooter.dsptemplate";
287
288
289
      break;
    }

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
  // 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()));
      }
    }
}
311
312
313
314
315
316
  
void cmDSPMakefile::WriteDSPHeader(std::ostream& fout)
{
  std::ifstream fin(m_DSPHeaderTemplate.c_str());
  if(!fin)
    {
Bill Hoffman's avatar
Bill Hoffman committed
317
    cmSystemTools::Error("Error Reading ", m_DSPHeaderTemplate.c_str());
318
319
    }
  char buffer[2048];
320

321
322
323
324
325
326
  while(fin)
    {
      fin.getline(buffer, 2048);
      std::string line = buffer;
      cmSystemTools::ReplaceString(line, "CM_RELEASE_LIBRARIES",
                                    m_ReleaseLibraryOptions.c_str());
327
328
      cmSystemTools::ReplaceString(line, "CM_RELEASEMINSIZE_LIBRARIES",
                                   m_ReleaseMinSizeLibraryOptions.c_str());
329
330
      cmSystemTools::ReplaceString(line, "CM_DEBUG_LIBRARIES",
                                    m_DebugLibraryOptions.c_str());
331
332
333
334
      cmSystemTools::ReplaceString(line, "CM_RELEASEDLL_LIBRARIES",
                                    m_ReleaseDLLLibraryOptions.c_str());
      cmSystemTools::ReplaceString(line, "CM_DEBUGDLL_LIBRARIES",
                                    m_DebugDLLLibraryOptions.c_str());
335
336
337
      cmSystemTools::ReplaceString(line, "BUILD_INCLUDES",
                                    m_IncludeOptions.c_str());
      cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", 
338
                                    m_Makefile->GetLibraryName());
339
      cmSystemTools::ReplaceString(line, 
340
341
                                    "EXTRA_DEFINES", 
				   m_Makefile->GetDefineFlags());
342
343
344
345
346
347
348
349
350
351
      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
352
353
    cmSystemTools::Error("Error Reading ",
                         m_DSPFooterTemplate.c_str());
354
355
356
357
358
359
360
361
362
363
    }
  char buffer[2048];
  while(fin)
    {
      fin.getline(buffer, 2048);
      fout << buffer << std::endl;
    }
}

					
364
void cmDSPMakefile::WriteDSPBuildRules(std::ostream& fout, const char *ext)
365
{
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
  // make a list if matching extentions
  std::vector<std::string> exts;
  std::string inExts = ext;
  
  std::string::size_type pos = inExts.find(';');
  std::string::size_type lastPos = 0;
  while (pos != std::string::npos)
    {
    std::string anExt = inExts.substr(lastPos, pos - lastPos);
    exts.push_back(anExt);
    lastPos = pos + 1;
    pos = inExts.find(';',lastPos);
    }
  exts.push_back(inExts.substr(lastPos,inExts.size() - lastPos));
  
  // loop over any classes
382
383
  std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
  for(int i = 0; i < Classes.size(); ++i)
384
    {
385
    if(!Classes[i].m_IsExecutable && !Classes[i].m_HeaderFileOnly)
386
      {
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
      // is this class of the appropriate type ?
      if (std::find(exts.begin(),exts.end(),Classes[i].m_ClassExtension)
          != exts.end())
        {
        this->WriteDSPBuildRule(fout, Classes[i].m_FullPath.c_str());
        }
      }
    }
  // loop over any custom commands
  std::vector<cmMakefile::customCommand>& ccoms = 
    this->GetMakefile()->GetCustomCommands();
  int numCust = ccoms.size();
  for (int j = 0; j < numCust; j++)
    {
    cmMakefile::customCommand &cc = ccoms[j];
    // is the source of the command the correct type
    pos = cc.m_Source.rfind('.');
    if(pos != std::string::npos)
      {
      if (std::find(exts.begin(),exts.end(),
                    cc.m_Source.substr(pos+1,cc.m_Source.size() - pos - 1))
          != exts.end())
        {
        this->WriteCustomRule(fout, cc.m_Source.c_str(), 
                              cc.m_Result.c_str(), 
                              cc.m_Command.c_str(),
                              cc.m_Depends);
        }
415
416
417
418
419
420
421
422
423
424
425
      }
    }
}

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