summaryrefslogtreecommitdiffstats
path: root/Source/cmDSWMakefile.cxx
blob: fb5c71861fa2c4f882a9be51fca84d9c9975027b (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
205
206
207
208
209
210
#include "cmDSWMakefile.h"
#include "cmStandardIncludes.h"
#include "cmSystemTools.h"
#include "cmDSPMakefile.h"
#include "cmMSProjectGenerator.h"
#include <windows.h>

// microsoft nonsense
#undef GetCurrentDirectory
#undef SetCurrentDirectory

cmDSWMakefile::cmDSWMakefile(cmMakefile* m)
{
  m_Makefile = m;
}

// output the DSW file
void cmDSWMakefile::OutputDSWFile()
{ 
  if(m_Makefile->GetOutputDirectory() == "")
    {
    // default to build in place
    m_Makefile->SetOutputDirectory(m_Makefile->GetHomeDirectory());
    }
  // If the output directory is not the m_cmHomeDirectory
  // then create it.
  if(strcmp(m_Makefile->GetOutputDirectory(),
            m_Makefile->GetHomeDirectory()) != 0)
    {
    if(!cmSystemTools::MakeDirectory(m_Makefile->GetOutputDirectory()))
      {
      MessageBox(0, "Error creating directory ", 0, MB_OK);
      MessageBox(0, m_Makefile->GetOutputDirectory(), 0, MB_OK);
      }
    }
  std::string fname;
  fname = m_Makefile->GetOutputDirectory();
  fname += "/";
  fname += m_Makefile->GetProjectName();
  fname += ".dsw";
  std::ofstream fout(fname.c_str());
  if(!fout)
    {
    cmSystemTools::Error("Error can not open for write: " , fname.c_str());
    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<cmMSProjectGenerator*>& makefiles)
{
  std::string currentDir = m_Makefile->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
    cmMSProjectGenerator* pg = new cmMSProjectGenerator;
    pg->SetBuildDSP();
    cmMakefile* mf = new cmMakefile;
    mf->SetMakefileGenerator(pg);
    // add it to the vector
    makefiles.push_back(pg);
    // Set up the file with the current context
    mf->SetOutputHomeDirectory(m_Makefile->GetOutputDirectory());
    mf->SetHomeDirectory(m_Makefile->GetHomeDirectory());
    // set the current directory in the Source as a full
    // path
    std::string currentDir = m_Makefile->GetCurrentDirectory();
    currentDir += "/";
    currentDir += subdir;
    mf->SetCurrentDirectory(currentDir.c_str());
    // Parse the CMakeLists.txt file
    currentDir += "/CMakeLists.txt";
    mf->ReadMakefile(currentDir.c_str());
    // Set the output directory which may be different than the source
    std::string outdir = m_Makefile->GetOutputDirectory();
    outdir += "/";
    outdir += subdir;
    mf->SetOutputDirectory(outdir.c_str());
    // Create the DSP file
    mf->GenerateMakefile();
    // Look at any sub directories parsed (SUBDIRS) and 
    // recurse into them    
    const std::vector<std::string>& subdirs = mf->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
    {
    cmSystemTools::Error("Can not find CMakeLists.txt in ",
                         currentDir.c_str());
    }
}


// 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<cmMSProjectGenerator*> dspfiles;
  // loop over all the subdirectories for the DSW file,
  // and find all sub directory projects
  const std::vector<std::string>& dirs = m_Makefile->GetSubDirectories();
  for(std::vector<std::string>::const_iterator j = dirs.begin();
      j != dirs.end(); ++j)
    {
    this->FindAllCMakeListsFiles(j->c_str(), dspfiles);
    }
  // For each DSP file created insert them into the DSW file
  for(std::vector<cmMSProjectGenerator*>::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)->GetDSPMakefile()->
      GetMakefile()->GetCurrentDirectory();
    // Get the home directory with the trailing slash
    std::string homedir = m_Makefile->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)->GetDSPMakefile()->GetCreatedProjectNames();
    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)->GetDSPMakefile());
      }
    // delete the cmDSPMakefile object once done with it to avoid
    // leaks
    delete (*k)->GetDSPMakefile()->GetMakefile();
    }
  // Write the footer for the DSW file
  this->WriteDSWFooter(fout);
}


void cmDSWMakefile::WriteProject(std::ostream& fout, 
				 const char* dspname,
				 const char* dir,
                                 cmDSPMakefile* 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->GetMakefile()->HasExecutables())
    {
    // insert Begin Project Dependency  Project_Dep_Name project stuff here 
    std::vector<std::string>::iterator i, end;
    i = project->GetMakefile()->GetLinkLibraries().begin();
    end = project->GetMakefile()->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";
}