summaryrefslogtreecommitdiffstats
path: root/Source/cmDSWWriter.cxx
blob: 3ee71f9a8016e83e63c382f5a3dd186a757f25a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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
202
203
204
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include "cmDSWMakefile.h"
#include "cmSystemTools.h"
#include "cmDSPMakefile.h"
#include <iostream>
#include <fstream>
#include <windows.h>

// microsoft nonsense
#undef GetCurrentDirectory
#undef SetCurrentDirectory

// output the DSW file
void cmDSWMakefile::OutputDSWFile()
{ 
  if(m_OutputDirectory == "")
    {
    // default to build in place
    m_OutputDirectory = m_cmHomeDirectory;
    }
  // If the output directory is not the m_cmHomeDirectory
  // then create it.
  if(m_OutputDirectory != m_cmHomeDirectory)
    {
    if(!cmSystemTools::MakeDirectory(m_OutputDirectory.c_str()))
      {
      MessageBox(0, "Error creating directory ", 0, MB_OK);
      MessageBox(0, m_OutputDirectory.c_str(), 0, MB_OK);
      }
    }
  std::string fname;
  fname = m_OutputDirectory;
  fname += "/";
  fname += this->m_ProjectName;
  fname += ".dsw";
  std::cerr << "writting dsw file " << fname.c_str() << std::endl;
  std::ofstream fout(fname.c_str());
  if(!fout)
    {
    std::cerr  << "Error can not open " 
	       << fname.c_str() << " for write" << std::endl;
    return;
    }
  this->WriteDSWFile(fout);
}

// ------------------------------------------------
// Recursive function to find all the CMakeLists.txt files
// in a project.  As each file is read in, any directories in
// the SUBDIR variable are also passed back to this function.
// The result is a vector of cmDSPMakefile objects, one for
// each directory with a CMakeLists.txt file
//
void cmDSWMakefile::FindAllCMakeListsFiles(const char* subdir,
					   std::vector<cmDSPMakefile*>& makefiles)
{
  std::string currentDir = this->GetCurrentDirectory();
  currentDir += "/";
  currentDir += subdir;
  currentDir += "/";
  currentDir += "CMakeLists.txt";
  // CMakeLists.txt exits in the subdirectory
  // then create a cmDSPMakefile for it
  if(cmSystemTools::FileExists(currentDir.c_str()))
    {
    // Create a new cmDSPMakefile to read the currentDir CMakeLists.txt file
    cmDSPMakefile* dsp = new cmDSPMakefile;
    // add it to the vector
    makefiles.push_back(dsp);
    // Set up the file with the current context
    dsp->SetOutputHomeDirectory(this->GetOutputDirectory());
    dsp->SetHomeDirectory(this->GetHomeDirectory());
    // set the current directory in the Source as a full
    // path
    std::string currentDir = this->GetCurrentDirectory();
    currentDir += "/";
    currentDir += subdir;
    dsp->SetCurrentDirectory(currentDir.c_str());
    // Parse the CMakeLists.txt file
    currentDir += "/CMakeLists.txt";
    dsp->ReadMakefile(currentDir.c_str());
    // Set the output directory which may be different than the source
    std::string outdir = m_OutputDirectory;
    outdir += "/";
    outdir += subdir;
    dsp->SetOutputDirectory(outdir.c_str());
    // Create the DSP file
    dsp->OutputDSPFile();
    // Look at any sub directories parsed (SUBDIRS) and 
    // recurse into them    
    const std::vector<std::string>& subdirs = dsp->GetSubDirectories();
    for(std::vector<std::string>::const_iterator i = subdirs.begin();
	i != subdirs.end(); ++i)
      {
      // append the subdirectory to the current directoy subdir
      std::string nextDir = subdir;
      nextDir += "/";
      nextDir += i->c_str();
      // recurse into nextDir
      this->FindAllCMakeListsFiles(nextDir.c_str(),
				   makefiles);
      }
    }
  else
    {
    std::cerr << "Can not find CMakeLists.txt in " << currentDir.c_str() 
	      << std::endl;
    }
}


// Write a DSW file to the stream
void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
{
  // Write out the header for a DSW file
  this->WriteDSWHeader(fout);
  // Create an array of dsp files for the project
  std::vector<cmDSPMakefile*> dspfiles;
  // loop over all the subdirectories for the DSW file,
  // and find all sub directory projects
  for(std::vector<std::string>::iterator j = m_SubDirectories.begin();
      j != m_SubDirectories.end(); ++j)
    {
    this->FindAllCMakeListsFiles(j->c_str(), dspfiles);
    }
  // For each DSP file created insert them into the DSW file
  for(std::vector<cmDSPMakefile*>::iterator k = dspfiles.begin();
      k != dspfiles.end(); ++k)
    {
    // Get the directory for the dsp file, it comes
    // from the source, so it has the source path which needs
    // to be removed as this may be built in a different directory
    // than the source
    std::string dir = (*k)->GetCurrentDirectory();
    // Get the home directory with the trailing slash
    std::string homedir = this->GetHomeDirectory();
    homedir += "/";
    // make the directory relative by removing the home directory part
    cmSystemTools::ReplaceString(dir, homedir.c_str(), "");
    // Get the list of create dsp files from the cmDSPMakefile, more
    // than one dsp could have been created per input CMakeLists.txt file
    std::vector<std::string> dspnames = (*k)->GetCreatedProjectNames();
    std::cerr << "Create dsp for " 
	      << dspnames.size()
	      << " number of dsp files in " << dir << std::endl;
    for(std::vector<std::string>::iterator si = dspnames.begin();
	si != dspnames.end(); ++si)
      {
      // Write the project into the DSW file
      this->WriteProject(fout, si->c_str(), dir.c_str(), *k);
      }
    // delete the cmDSPMakefile object once done with it to avoid
    // leaks
    delete *k;
    }
  // Write the footer for the DSW file
  this->WriteDSWFooter(fout);
}


void cmDSWMakefile::WriteProject(std::ostream& fout, 
				 const char* dspname,
				 const char* dir,
                                 cmMakefile* project)
{
  fout << "###############################################################################\n\n";
  fout << "Project: \"" << dspname << "\"=" 
       << dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n";
  fout << "Package=<5>\n{{{\n}}}\n\n";
  fout << "Package=<4>\n";
  fout << "{{{\n";
  if(project->HasExecutables())
    {
    // insert Begin Project Dependency  Project_Dep_Name project stuff here 
    std::vector<std::string>::iterator i, end;
    i = project->GetBuildFlags().GetLinkLibraries().begin();
    end = project->GetBuildFlags().GetLinkLibraries().end();
    for(;i!= end; ++i)
      {
      fout << "Begin Project Dependency\n";
      fout << "Project_Dep_Name " << *i << "\n";
      fout << "End Project Dependency\n";
      }
    }
  fout << "}}}\n\n";
}

void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
{
  fout << "###############################################################################\n\n";
  fout << "Global:\n\n";
  fout << "Package=<5>\n{{{\n}}}\n\n";
  fout << "Package=<3>\n{{{\n}}}\n\n";
  fout << "###############################################################################\n\n";
}

  
void cmDSWMakefile::WriteDSWHeader(std::ostream& fout)
{
  fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n";
  fout << "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n";
}