cmDSPMakefile.cxx 12.6 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
  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)
	{
77
	m_DebugLibraryOptions += "/$(OUTDIR)\" ";
78
79
80
81
	}
      }
    }
  m_DebugLibraryOptions += "/STACK:10000000 ";
82
  // add any extra define flags 
83
  m_ReleaseLibraryOptions = m_DebugLibraryOptions;
84
85
86
  m_DebugDLLLibraryOptions = m_DebugLibraryOptions;
  m_ReleaseDLLLibraryOptions = m_DebugDLLLibraryOptions;
  m_ReleaseMinSizeLibraryOptions = m_ReleaseLibraryOptions;
Bill Hoffman's avatar
Bill Hoffman committed
87
88
  
  // Create the DSP or set of DSP's for libraries and executables
Ken Martin's avatar
Ken Martin committed
89
  if(strlen(m_Makefile->GetLibraryName()) != 0)
90
    {
91
92
93
94
95
96
97
98
99
100
    const char* cacheValue
      = cmCacheManager::GetInstance()->GetCacheValue("BUILD_SHARED_LIBS");
    if(cacheValue && strcmp(cacheValue,"0"))
      {
      this->SetBuildType(DLL);
      }
    else
      {
      this->SetBuildType(STATIC_LIBRARY);
      }
101
102
    this->CreateSingleDSP();
    }
Ken Martin's avatar
Ken Martin committed
103
104
  // if there are executables build them
  if (m_Makefile->HasExecutables())
105
106
107
108
109
110
    {
    this->CreateExecutableDSPFiles();
    }
}
void cmDSPMakefile::CreateExecutableDSPFiles()
{
111
112
  std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
  for(int i = 0; i < Classes.size(); ++i)
113
    {
114
    cmClassFile& classfile = Classes[i];
Ken Martin's avatar
Ken Martin committed
115
    if (classfile.m_IsExecutable)
116
      {
Ken Martin's avatar
Ken Martin committed
117
118
119
120
121
122
123
      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
124
125
        cmSystemTools::Error("Error Writing ",
                             fname.c_str());
Ken Martin's avatar
Ken Martin committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
        }
      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);
        }
141
142
143
144
145
146
147
148
      }
    }
}


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

  std::vector<std::string> depends;
185
186
  this->WriteCustomRule(fout, makefileIn.c_str(), 
			dspname.c_str(),
187
188
			dsprule.c_str(),
			depends);
189
190
191
192
193
194
}

void cmDSPMakefile::WriteDSPFile(std::ostream& fout)
{
  this->WriteDSPHeader(fout);
  this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
195
196
197
198
  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");
199
  this->WriteDSPEndGroup(fout);
200
201
202
  this->WriteDSPBeginGroup(fout, "XML Files", "xml");
  this->WriteDSPBuildRules(fout,"xml");
  this->WriteDSPEndGroup(fout);
203
204
205
206
207
208
  this->WriteDSPBuildRule(fout);
  this->WriteDSPFooter(fout);
}


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

  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";
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
  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)
{
262
  m_BuildType = b;
263
264
265
  switch(b)
    {
    case STATIC_LIBRARY:
266
      m_DSPHeaderTemplate = m_Makefile->GetHomeDirectory();
267
      m_DSPHeaderTemplate += "/CMake/Source/staticLibHeader.dsptemplate";
268
      m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
269
      m_DSPFooterTemplate += "/CMake/Source/staticLibFooter.dsptemplate";
270
271
      break;
    case DLL:
272
      m_DSPHeaderTemplate =  m_Makefile->GetHomeDirectory();
273
      m_DSPHeaderTemplate += "/CMake/Source/DLLHeader.dsptemplate";
274
      m_DSPFooterTemplate =  m_Makefile->GetHomeDirectory();
275
      m_DSPFooterTemplate += "/CMake/Source/DLLFooter.dsptemplate";
276
277
      break;
    case EXECUTABLE:
278
      m_DSPHeaderTemplate = m_Makefile->GetHomeDirectory();
279
      m_DSPHeaderTemplate += "/CMake/Source/EXEHeader.dsptemplate";
280
      m_DSPFooterTemplate = m_Makefile->GetHomeDirectory();
281
      m_DSPFooterTemplate += "/CMake/Source/EXEFooter.dsptemplate";
282
283
284
      break;
    }

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

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

					
359
void cmDSPMakefile::WriteDSPBuildRules(std::ostream& fout, const char *ext)
360
{
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  // 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
377
378
  std::vector<cmClassFile>& Classes = m_Makefile->GetClasses();
  for(int i = 0; i < Classes.size(); ++i)
379
    {
380
    if(!Classes[i].m_IsExecutable && !Classes[i].m_HeaderFileOnly)
381
      {
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
      // 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);
        }
410
411
412
413
414
415
416
417
418
419
420
      }
    }
}

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