Ticket #9137: TOOLS - Add create_project tool.patch
File TOOLS - Add create_project tool.patch, 134.0 KB (added by , 14 years ago) |
---|
-
new file tools/create_project/codeblocks.cpp
# HG changeset patch # User Julien <littleboy@users.sf.net> # Parent e24b1c8ca9425663ae80cc825fe59bf7f37acc44 TOOLS: Add create_project tool diff -r e24b1c8ca942 tools/create_project/codeblocks.cpp
- + 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #include "codeblocks.h" 27 28 #include <fstream> 29 30 namespace CreateProjectTool { 31 32 CodeBlocksProvider::CodeBlocksProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version) 33 : ProjectProvider(global_warnings, project_warnings, version) { 34 } 35 36 void CodeBlocksProvider::createWorkspace(const BuildSetup &setup) { 37 std::ofstream workspace((setup.outputDir + '/' + "scummvm.workspace").c_str()); 38 if (!workspace) 39 error("Could not open \"" + setup.outputDir + '/' + "scummvm.workspace\" for writing"); 40 41 workspace << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n" 42 "<CodeBlocks_workspace_file>\n"; 43 44 workspace << "\t<Workspace title=\"ScummVM\">\n"; 45 46 writeReferences(workspace); 47 48 // Note we assume that the UUID map only includes UUIDs for enabled engines! 49 for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { 50 if (i->first == "scummvm") 51 continue; 52 53 workspace << "\t\t<Project filename=\"" << i->first << ".cbp\" />\n"; 54 } 55 56 workspace << "\t</Workspace>\n" 57 "</CodeBlocks_workspace_file>"; 58 } 59 60 void CodeBlocksProvider::createProjectFile(const std::string &name, const std::string &, const BuildSetup &setup, const std::string &moduleDir, 61 const StringList &includeList, const StringList &excludeList) { 62 63 const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension(); 64 std::ofstream project(projectFile.c_str()); 65 if (!project) 66 error("Could not open \"" + projectFile + "\" for writing"); 67 68 project << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n" 69 "<CodeBlocks_project_file>\n" 70 "\t<FileVersion major=\"1\" minor=\"6\" />\n" 71 "\t<Project>\n" 72 "\t\t<Option title=\"" << name << "\" />\n" 73 "\t\t<Option pch_mode=\"2\" />\n" 74 "\t\t<Option compiler=\"gcc\" />\n" 75 "\t\t<Build>\n"; 76 77 if (name == "scummvm") { 78 std::string libraries; 79 80 for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) 81 libraries += *i + ".a;"; 82 83 project << "\t\t\t<Target title=\"default\">\n" 84 "\t\t\t\t<Option output=\"scummvm\\scummvm\" prefix_auto=\"1\" extension_auto=\"1\" />\n" 85 "\t\t\t\t<Option object_output=\"scummvm\" />\n" 86 "\t\t\t\t<Option external_deps=\"" << libraries /* + list of engines scummvm\engines\name\name.a */ << "\" />\n" 87 "\t\t\t\t<Option type=\"1\" />\n" 88 "\t\t\t\t<Option compiler=\"gcc\" />\n" 89 "\t\t\t\t<Option parameters=\"-d 8 --debugflags=parser\" />\n" 90 "\t\t\t\t<Option projectIncludeDirsRelation=\"2\" />\n"; 91 92 ////////////////////////////////////////////////////////////////////////// 93 // Compiler 94 project << "\t\t\t\t<Compiler>\n"; 95 96 writeWarnings(name, project); 97 writeDefines(setup.defines, project); 98 99 project << "\t\t\t\t\t<Add directory=\"..\\..\" />\n" 100 "\t\t\t\t\t<Add directory=\"..\\..\\engines\" />\n" 101 "\t\t\t\t\t<Add directory=\"..\\..\\common\" />\n" 102 "\t\t\t\t\t<Add directory=\"$(SCUMMVM_LIBS)\\include\" />\n" 103 "\t\t\t\t</Compiler>\n"; 104 105 ////////////////////////////////////////////////////////////////////////// 106 // Linker 107 project << "\t\t\t\t<Linker>\n"; 108 109 for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) 110 project << "\t\t\t\t\t<Add library=\"" << *i << ".a\" />\n"; 111 112 for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { 113 if (i->first == "scummvm") 114 continue; 115 116 project << "\t\t\t\t\t<Add library=\"scummvm\\engines\\" << i->first << "\\lib" << i->first << ".a\" />\n"; 117 } 118 119 project << "\t\t\t\t\t<Add directory=\"$(SCUMMVM_LIBS)\\lib\" />\n" 120 "\t\t\t\t</Linker>\n"; 121 122 ////////////////////////////////////////////////////////////////////////// 123 // Resource compiler 124 project << "\t\t\t\t<ResourceCompiler>\n" 125 "\t\t\t\t\t<Add directory=\"..\\..\\dists\" />\n" 126 "\t\t\t\t\t<Add directory=\"..\\..\\..\\scummvm\" />\n" 127 "\t\t\t\t</ResourceCompiler>\n" 128 "\t\t\t</Target>\n" 129 "\t\t</Build>\n"; 130 131 132 133 } else { 134 project << "\t\t\t<Target title=\"default\">\n" 135 "\t\t\t\t<Option output=\"scummvm\\engines\\" << name << "\\lib" << name << "\" prefix_auto=\"1\" extension_auto=\"1\" />\n" 136 "\t\t\t\t<Option working_dir=\"\" />\n" 137 "\t\t\t\t<Option object_output=\"scummvm\" />\n" 138 "\t\t\t\t<Option type=\"2\" />\n" 139 "\t\t\t\t<Option compiler=\"gcc\" />\n" 140 "\t\t\t\t<Option createDefFile=\"1\" />\n" 141 "\t\t\t\t<Compiler>\n"; 142 143 writeWarnings(name, project); 144 writeDefines(setup.defines, project); 145 146 project << "\t\t\t\t\t<Add option=\"-g\" />\n" 147 "\t\t\t\t\t<Add directory=\"..\\..\\engines\" />\n" 148 "\t\t\t\t\t<Add directory=\"..\\..\\..\\scummvm\" />\n" 149 "\t\t\t\t</Compiler>\n" 150 "\t\t\t</Target>\n" 151 "\t\t</Build>\n"; 152 } 153 154 std::string modulePath; 155 if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) { 156 modulePath = moduleDir.substr(setup.srcDir.size()); 157 if (!modulePath.empty() && modulePath.at(0) == '/') 158 modulePath.erase(0, 1); 159 } 160 161 if (modulePath.size()) 162 addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix + '/' + modulePath); 163 else 164 addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix); 165 166 167 project << "\t\t<Extensions>\n" 168 "\t\t\t<code_completion />\n" 169 "\t\t\t<debugger />\n" 170 "\t\t</Extensions>\n" 171 "\t</Project>\n" 172 "</CodeBlocks_project_file>"; 173 174 } 175 176 void CodeBlocksProvider::writeWarnings(const std::string &name, std::ofstream &output) const { 177 178 // Global warnings 179 for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) 180 output << "\t\t\t\t\t<Add option=\"" << *i << "\" />\n"; 181 182 // Check for project-specific warnings: 183 std::map<std::string, StringList>::iterator warningsIterator = _projectWarnings.find(name); 184 if (warningsIterator != _projectWarnings.end()) 185 for (StringList::const_iterator i = warningsIterator->second.begin(); i != warningsIterator->second.end(); ++i) 186 output << "\t\t\t\t\t<Add option=\"" << *i << "\" />\n"; 187 188 } 189 190 void CodeBlocksProvider::writeDefines(const StringList &defines, std::ofstream &output) const { 191 for (StringList::const_iterator i = defines.begin(); i != defines.end(); ++i) 192 output << "\t\t\t\t\t<Add option=\"-D" << *i << "\" />\n"; 193 } 194 195 void CodeBlocksProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, 196 const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) { 197 198 for (FileNode::NodeList::const_iterator i = dir.children.begin(); i != dir.children.end(); ++i) { 199 const FileNode *node = *i; 200 201 if (!node->children.empty()) { 202 writeFileListToProject(*node, projectFile, indentation + 1, duplicate, objPrefix + node->name + '_', filePrefix + node->name + '/'); 203 } else { 204 std::string name, ext; 205 splitFilename(node->name, name, ext); 206 207 if (ext == "rc") { 208 projectFile << "\t\t<Unit filename=\"" << convertPathToWin(filePrefix + node->name) << "\">\n" 209 "\t\t\t<Option compilerVar=\"WINDRES\" />\n" 210 "\t\t</Unit>\n"; 211 212 } else { 213 projectFile << "\t\t<Unit filename=\"" << convertPathToWin(filePrefix + node->name) << "\" />\n"; 214 } 215 } 216 } 217 } 218 219 void CodeBlocksProvider::writeReferences(std::ofstream &output) { 220 output << "\t\t<Project filename=\"scummvm.cbp\" active=\"1\">\n"; 221 222 for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { 223 if (i->first == "scummvm") 224 continue; 225 226 output << "\t\t\t<Depends filename=\"" << i->first << ".cbp\" />\n"; 227 } 228 229 output << "\t\t</Project>\n"; 230 } 231 232 const char *CodeBlocksProvider::getProjectExtension() { 233 return ".cbp"; 234 } 235 236 237 } // End of CreateProjectTool namespace -
new file tools/create_project/codeblocks.h
diff -r e24b1c8ca942 tools/create_project/codeblocks.h
- + 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #ifndef TOOLS_CREATE_PROJECT_CODEBLOCKS_H 27 #define TOOLS_CREATE_PROJECT_CODEBLOCKS_H 28 29 #include "create_project.h" 30 31 namespace CreateProjectTool { 32 33 class CodeBlocksProvider : public ProjectProvider { 34 public: 35 CodeBlocksProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version = 0); 36 37 protected: 38 39 void createWorkspace(const BuildSetup &setup); 40 41 void createOtherBuildFiles(const BuildSetup &) {} 42 43 void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, 44 const StringList &includeList, const StringList &excludeList); 45 46 void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, 47 const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); 48 49 void writeReferences(std::ofstream &output); 50 51 const char *getProjectExtension(); 52 53 private: 54 void writeWarnings(const std::string &name, std::ofstream &output) const; 55 void writeDefines(const StringList &defines, std::ofstream &output) const; 56 }; 57 58 } // End of CreateProjectTool namespace 59 60 #endif // TOOLS_CREATE_PROJECT_CODEBLOCKS_H -
new file tools/create_project/create_project.cpp
diff -r e24b1c8ca942 tools/create_project/create_project.cpp
- + 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #include "create_project.h" 27 #include "codeblocks.h" 28 #include "msvc.h" 29 30 #include <fstream> 31 #include <iostream> 32 33 #include <stack> 34 #include <algorithm> 35 #include <iomanip> 36 37 #include <cstring> 38 #include <cstdlib> 39 #include <ctime> 40 41 #if defined(_WIN32) || defined(WIN32) 42 #include <windows.h> 43 #else 44 #include <sstream> 45 #include <sys/param.h> 46 #include <sys/stat.h> 47 #include <dirent.h> 48 #endif 49 50 namespace { 51 /** 52 * Converts the given path to only use slashes as 53 * delimiters. 54 * This means that for example the path: 55 * foo/bar\test.txt 56 * will be converted to: 57 * foo/bar/test.txt 58 * 59 * @param path Path string. 60 * @return Converted path. 61 */ 62 std::string unifyPath(const std::string &path); 63 64 /** 65 * Returns the last path component. 66 * 67 * @param path Path string. 68 * @return Last path component. 69 */ 70 std::string getLastPathComponent(const std::string &path); 71 72 /** 73 * Display the help text for the program. 74 * 75 * @param exe Name of the executable. 76 */ 77 void displayHelp(const char *exe); 78 79 /** 80 * Structure for describing an FSNode. This is a very minimalistic 81 * description, which includes everything we need. 82 * It only contains the name of the node and whether it is a directory 83 * or not. 84 */ 85 struct FSNode { 86 FSNode() : name(), isDirectory(false) {} 87 FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {} 88 89 std::string name; ///< Name of the file system node 90 bool isDirectory; ///< Whether it is a directory or not 91 }; 92 93 typedef std::list<FSNode> FileList; 94 } // End of anonymous namespace 95 96 enum ProjectType { 97 kProjectNone, 98 kProjectCodeBlocks, 99 kProjectMSVC 100 }; 101 102 int main(int argc, char *argv[]) { 103 #if !(defined(_WIN32) || defined(WIN32)) 104 // Initialize random number generator for UUID creation 105 std::srand(std::time(0)); 106 #endif 107 108 if (argc < 2) { 109 displayHelp(argv[0]); 110 return -1; 111 } 112 113 const std::string srcDir = argv[1]; 114 115 BuildSetup setup; 116 setup.srcDir = unifyPath(srcDir); 117 118 if (setup.srcDir.at(setup.srcDir.size() - 1) == '/') 119 setup.srcDir.erase(setup.srcDir.size() - 1); 120 121 setup.filePrefix = setup.srcDir; 122 setup.outputDir = '.'; 123 124 setup.engines = parseConfigure(setup.srcDir); 125 126 if (setup.engines.empty()) { 127 std::cout << "WARNING: No engines found in configure file or configure file missing in \"" << setup.srcDir << "\"\n"; 128 return 0; 129 } 130 131 setup.features = getAllFeatures(); 132 133 ProjectType projectType = kProjectNone; 134 int msvcVersion = 9; 135 136 // Parse command line arguments 137 using std::cout; 138 for (int i = 2; i < argc; ++i) { 139 if (!std::strcmp(argv[i], "--list-engines")) { 140 cout << " The following enables are available in the ScummVM source distribution\n" 141 " located at \"" << srcDir << "\":\n"; 142 143 cout << " state | name | description\n\n"; 144 cout.setf(std::ios_base::left, std::ios_base::adjustfield); 145 for (EngineDescList::const_iterator j = setup.engines.begin(); j != setup.engines.end(); ++j) 146 cout << ' ' << (j->enable ? " enabled" : "disabled") << " | " << std::setw((std::streamsize)15) << j->name << std::setw((std::streamsize)0) << " | " << j->desc << "\n"; 147 cout.setf(std::ios_base::right, std::ios_base::adjustfield); 148 149 return 0; 150 151 } else if (!std::strcmp(argv[i], "--codeblocks")) { 152 if (projectType != kProjectNone) { 153 std::cerr << "ERROR: You cannot pass more than one project type!\n"; 154 return -1; 155 } 156 157 projectType = kProjectCodeBlocks; 158 159 } else if (!std::strcmp(argv[i], "--msvc")) { 160 if (projectType != kProjectNone) { 161 std::cerr << "ERROR: You cannot pass more than one project type!\n"; 162 return -1; 163 } 164 165 projectType = kProjectMSVC; 166 167 } else if (!std::strcmp(argv[i], "--msvc-version")) { 168 if (i + 1 >= argc) { 169 std::cerr << "ERROR: Missing \"version\" parameter for \"--msvc-version\"!\n"; 170 return -1; 171 } 172 173 msvcVersion = atoi(argv[++i]); 174 175 if (msvcVersion != 8 && msvcVersion != 9 && msvcVersion != 10) { 176 std::cerr << "ERROR: Unsupported version: \"" << msvcVersion << "\" passed to \"--msvc-version\"!\n"; 177 return -1; 178 } 179 } else if (!strncmp(argv[i], "--enable-", 9)) { 180 const char *name = &argv[i][9]; 181 if (!*name) { 182 std::cerr << "ERROR: Invalid command \"" << argv[i] << "\"\n"; 183 return -1; 184 } 185 186 if (!std::strcmp(name, "all-engines")) { 187 for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j) 188 j->enable = true; 189 } else if (!setEngineBuildState(name, setup.engines, true)) { 190 // If none found, we'll try the features list 191 if (!setFeatureBuildState(name, setup.features, true)) { 192 std::cerr << "ERROR: \"" << name << "\" is neither an engine nor a feature!\n"; 193 return -1; 194 } 195 } 196 } else if (!strncmp(argv[i], "--disable-", 10)) { 197 const char *name = &argv[i][10]; 198 if (!*name) { 199 std::cerr << "ERROR: Invalid command \"" << argv[i] << "\"\n"; 200 return -1; 201 } 202 203 if (!std::strcmp(name, "all-engines")) { 204 for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j) 205 j->enable = false; 206 } else if (!setEngineBuildState(name, setup.engines, false)) { 207 // If none found, we'll try the features list 208 if (!setFeatureBuildState(name, setup.features, false)) { 209 std::cerr << "ERROR: \"" << name << "\" is neither an engine nor a feature!\n"; 210 return -1; 211 } 212 } 213 } else if (!std::strcmp(argv[i], "--file-prefix")) { 214 if (i + 1 >= argc) { 215 std::cerr << "ERROR: Missing \"prefix\" parameter for \"--file-prefix\"!\n"; 216 return -1; 217 } 218 219 setup.filePrefix = unifyPath(argv[++i]); 220 if (setup.filePrefix.at(setup.filePrefix.size() - 1) == '/') 221 setup.filePrefix.erase(setup.filePrefix.size() - 1); 222 } else if (!std::strcmp(argv[i], "--output-dir")) { 223 if (i + 1 >= argc) { 224 std::cerr << "ERROR: Missing \"path\" parameter for \"--output-dirx\"!\n"; 225 return -1; 226 } 227 228 setup.outputDir = unifyPath(argv[++i]); 229 if (setup.outputDir.at(setup.outputDir.size() - 1) == '/') 230 setup.outputDir.erase(setup.outputDir.size() - 1); 231 } else { 232 std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n"; 233 return -1; 234 } 235 } 236 237 // Print status 238 cout << "Enabled engines:\n\n"; 239 for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) { 240 if (i->enable) 241 cout << " " << i->desc << '\n'; 242 } 243 244 cout << "\nDisabled engines:\n\n"; 245 for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) { 246 if (!i->enable) 247 cout << " " << i->desc << '\n'; 248 } 249 250 cout << "\nEnabled features:\n\n"; 251 for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) { 252 if (i->enable) 253 cout << " " << i->description << '\n'; 254 } 255 256 cout << "\nDisabled features:\n\n"; 257 for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) { 258 if (!i->enable) 259 cout << " " << i->description << '\n'; 260 } 261 262 // Creation... 263 setup.defines = getEngineDefines(setup.engines); 264 StringList featureDefines = getFeatureDefines(setup.features); 265 setup.defines.splice(setup.defines.begin(), featureDefines); 266 267 setup.libraries = getFeatureLibraries(setup.features); 268 269 setup.libraries.push_back("winmm"); 270 setup.libraries.push_back("sdl"); 271 272 // Initialize global & project-specific warnings 273 #define SET_GLOBAL_WARNINGS(...) \ 274 { \ 275 std::string global[PP_NARG(__VA_ARGS__)] = { __VA_ARGS__ }; \ 276 globalWarnings.assign(global, global + (sizeof(global) / sizeof(global[0]))); \ 277 } 278 279 #define SET_WARNINGS(name, ...) \ 280 { \ 281 std::string project[PP_NARG(__VA_ARGS__)] = { __VA_ARGS__ }; \ 282 projectWarnings[name].assign(project, project + (sizeof(project) / sizeof(project[0]))); \ 283 } 284 285 // List of global warnings and map of project-specific warnings 286 StringList globalWarnings; 287 std::map<std::string, StringList> projectWarnings; 288 289 CreateProjectTool::ProjectProvider *provider = NULL; 290 291 switch (projectType) { 292 default: 293 case kProjectNone: 294 std::cerr << "ERROR: No project type has been specified!\n"; 295 return -1; 296 297 case kProjectCodeBlocks: 298 //////////////////////////////////////////////////////////////////////////// 299 // Code::Blocks is using GCC behind the scenes, so we need to pass a list 300 // of options to enable or disable warnings 301 //////////////////////////////////////////////////////////////////////////// 302 // 303 // -Wall 304 // enable all warnings 305 // 306 // -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder 307 // disable annoying and not-so-useful warnings 308 // 309 // -Wpointer-arith -Wcast-qual -Wcast-align 310 // -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings 311 // enable even more warnings... 312 // 313 // -fno-rtti -fno-exceptions -fcheck-new 314 // disable RTTI and exceptions, and enable checking of pointers returned 315 // by "new" 316 // 317 //////////////////////////////////////////////////////////////////////////// 318 319 SET_GLOBAL_WARNINGS("-Wall", "-Wno-long-long", "-Wno-multichar", "-Wno-unknown-pragmas", "-Wno-reorder", 320 "-Wpointer-arith", "-Wcast-qual", "-Wcast-align", "-Wshadow", "-Wimplicit", 321 "-Wnon-virtual-dtor", "-Wwrite-strings", "-fno-rtti", "-fno-exceptions", "-fcheck-new"); 322 323 provider = new CreateProjectTool::CodeBlocksProvider(globalWarnings, projectWarnings); 324 325 break; 326 327 case kProjectMSVC: 328 //////////////////////////////////////////////////////////////////////////// 329 // For Visual Studio, all warnings are on by default in the project files, 330 // so we pass a list of warnings to disable globally or per-project 331 // 332 // Tracker reference: 333 // https://sourceforge.net/tracker/?func=detail&aid=2909981&group_id=37116&atid=418822 334 //////////////////////////////////////////////////////////////////////////// 335 // 336 // 4068 (unknown pragma) 337 // only used in scumm engine to mark code sections 338 // 339 // 4100 (unreferenced formal parameter) 340 // 341 // 4103 (alignment changed after including header, may be due to missing #pragma pack(pop)) 342 // used by pack-start / pack-end 343 // 344 // 4127 (conditional expression is constant) 345 // used in a lot of engines 346 // 347 // 4244 ('conversion' conversion from 'type1' to 'type2', possible loss of data) 348 // throws tons and tons of warnings, most of them false positives 349 // 350 // 4250 ('class1' : inherits 'class2::member' via dominance) 351 // two or more members have the same name. Should be harmless 352 // 353 // 4310 (cast truncates constant value) 354 // used in some engines 355 // 356 // 4351 (new behavior: elements of array 'array' will be default initialized) 357 // a change in behavior in Visual Studio 2005. We want the new behavior, so it can be disabled 358 // 359 // 4512 ('class' : assignment operator could not be generated) 360 // some classes use const items and the default assignment operator cannot be generated 361 // 362 // 4702 (unreachable code) 363 // mostly thrown after error() calls (marked as NORETURN) 364 // 365 // 4706 (assignment within conditional expression) 366 // used in a lot of engines 367 // 368 // 4800 ('type' : forcing value to bool 'true' or 'false' (performance warning)) 369 // 370 // 4996 ('function': was declared deprecated) 371 // disabling it removes all the non-standard unsafe functions warnings (strcpy_s, etc.) 372 // 373 //////////////////////////////////////////////////////////////////////////// 374 // 375 // 4189 (local variable is initialized but not referenced) 376 // false positive in lure engine 377 // 378 // 4355 ('this' : used in base member initializer list) 379 // only disabled for specific engines where it is used in a safe way 380 // 381 // 4510 ('class' : default constructor could not be generated) 382 // 383 // 4511 ('class' : copy constructor could not be generated) 384 // 385 // 4610 (object 'class' can never be instantiated - user-defined constructor required) 386 // "correct" but harmless (as is 4510) 387 // 388 //////////////////////////////////////////////////////////////////////////// 389 390 SET_GLOBAL_WARNINGS("4068", "4100", "4103", "4127", "4244", "4250", "4310", "4351", "4512", "4702", "4706", "4800", "4996"); 391 SET_WARNINGS("agi", "4510", "4610"); 392 SET_WARNINGS("agos", "4511"); 393 SET_WARNINGS("lure", "4189", "4355"); 394 SET_WARNINGS("kyra", "4355"); 395 SET_WARNINGS("m4", "4355"); 396 397 if (msvcVersion == 8 || msvcVersion == 9) 398 provider = new CreateProjectTool::VisualStudioProvider(globalWarnings, projectWarnings, msvcVersion); 399 else 400 provider = new CreateProjectTool::MSBuildProvider(globalWarnings, projectWarnings, msvcVersion); 401 402 break; 403 } 404 405 provider->createProject(setup); 406 407 delete provider; 408 } 409 410 namespace { 411 std::string unifyPath(const std::string &path) { 412 std::string result = path; 413 std::replace(result.begin(), result.end(), '\\', '/'); 414 return result; 415 } 416 417 std::string getLastPathComponent(const std::string &path) { 418 std::string::size_type pos = path.find_last_of('/'); 419 if (pos == std::string::npos) 420 return path; 421 else 422 return path.substr(pos + 1); 423 } 424 425 void displayHelp(const char *exe) { 426 using std::cout; 427 428 cout << "Usage:\n" 429 << exe << " path\\to\\source [optional options]\n" 430 << "\n" 431 << " Creates project files for the ScummVM source located at \"path\\to\\source\".\n" 432 " The project files will be created in the directory where tool is run from and\n" 433 " will include \"path\\to\\source\" for relative file paths, thus be sure that you\n" 434 " pass a relative file path like \"..\\..\\trunk\".\n" 435 "\n" 436 " Additionally there are the following switches for changing various settings:\n" 437 "\n" 438 "Project specific settings:\n" 439 " --codeblock build Code::Blocks project files\n" 440 " --msvc build Visual Studio project files\n" 441 " --file-prefix prefix allow overwriting of relative file prefix in the\n" 442 " MSVC project files. By default the prefix is the\n" 443 " \"path\\to\\source\" argument\n" 444 " --output-dir path overwrite path, where the project files are placed\n" 445 " By default this is \".\", i.e. the current working\n" 446 " directory\n" 447 "\n" 448 "MSVC specific settings:\n" 449 " --msvc-version version set the targeted MSVC version. Possible values:\n" 450 " 8 stands for \"Visual Studio 2005\"\n" 451 " 9 stands for \"Visual Studio 2008\"\n" 452 " 10 stands for \"Visual Studio 2010\"\n" 453 " The default is \"9\", thus \"Visual Studio 2008\"\n" 454 "\n" 455 "ScummVM engine settings:\n" 456 " --list-engines list all available engines and their default state\n" 457 " --enable-engine enable building of the engine with the name \"engine\"\n" 458 " --disable-engine disable building of the engine with the name \"engine\"\n" 459 " --enable-all-engines enable building of all engines\n" 460 " --disable-all-engines disable building of all engines\n" 461 "\n" 462 "ScummVM optional feature settings:\n" 463 " --enable-name enable inclusion of the feature \"name\"\n" 464 " --disable-name disable inclusion of the feature \"name\"\n" 465 "\n" 466 " There are the following features available:\n" 467 "\n"; 468 469 cout << " state | name | description\n\n"; 470 const FeatureList features = getAllFeatures(); 471 cout.setf(std::ios_base::left, std::ios_base::adjustfield); 472 for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i) 473 cout << ' ' << (i->enable ? " enabled" : "disabled") << " | " << std::setw((std::streamsize)15) << i->name << std::setw((std::streamsize)0) << " | " << i->description << '\n'; 474 cout.setf(std::ios_base::right, std::ios_base::adjustfield); 475 } 476 477 typedef StringList TokenList; 478 479 /** 480 * Takes a given input line and creates a list of tokens out of it. 481 * 482 * A token in this context is separated by whitespaces. A special case 483 * are quotation marks though. A string inside quotation marks is treated 484 * as single token, even when it contains whitespaces. 485 * 486 * Thus for example the input: 487 * foo bar "1 2 3 4" ScummVM 488 * will create a list with the following entries: 489 * "foo", "bar", "1 2 3 4", "ScummVM" 490 * As you can see the quotation marks will get *removed* too. 491 * 492 * @param input The text to be tokenized. 493 * @return A list of tokens. 494 */ 495 TokenList tokenize(const std::string &input); 496 497 /** 498 * Try to parse a given line and create an engine definition 499 * out of the result. 500 * 501 * This may take *any* input line, when the line is not used 502 * to define an engine the result of the function will be "false". 503 * 504 * Note that the contents of "engine" are undefined, when this 505 * function returns "false". 506 * 507 * @param line Text input line. 508 * @param engine Reference to an object, where the engine information 509 * is to be stored in. 510 * @return "true", when parsing succeeded, "false" otherwise. 511 */ 512 bool parseEngine(const std::string &line, EngineDesc &engine); 513 } // End of anonymous namespace 514 515 EngineDescList parseConfigure(const std::string &srcDir) { 516 std::string configureFile = srcDir + "/configure"; 517 518 std::ifstream configure(configureFile.c_str()); 519 if (!configure) 520 return EngineDescList(); 521 522 std::string line; 523 EngineDescList engines; 524 525 for (;;) { 526 std::getline(configure, line); 527 if (configure.eof()) 528 break; 529 530 if (configure.fail()) 531 error("Failed while reading from " + configureFile); 532 533 EngineDesc desc; 534 if (parseEngine(line, desc)) 535 engines.push_back(desc); 536 } 537 538 return engines; 539 } 540 541 bool isSubEngine(const std::string &name, const EngineDescList &engines) { 542 for (EngineDescList::const_iterator i = engines.begin(); i != engines.end(); ++i) { 543 if (std::find(i->subEngines.begin(), i->subEngines.end(), name) != i->subEngines.end()) 544 return true; 545 } 546 547 return false; 548 } 549 550 bool setEngineBuildState(const std::string &name, EngineDescList &engines, bool enable) { 551 if (enable && isSubEngine(name, engines)) { 552 // When we enable a sub engine, we need to assure that the parent is also enabled, 553 // thus we enable both sub engine and parent over here. 554 EngineDescList::iterator engine = std::find(engines.begin(), engines.end(), name); 555 if (engine != engines.end()) { 556 engine->enable = enable; 557 558 for (engine = engines.begin(); engine != engines.end(); ++engine) { 559 if (std::find(engine->subEngines.begin(), engine->subEngines.end(), name) != engine->subEngines.end()) { 560 engine->enable = true; 561 break; 562 } 563 } 564 565 return true; 566 } 567 } else { 568 EngineDescList::iterator engine = std::find(engines.begin(), engines.end(), name); 569 if (engine != engines.end()) { 570 engine->enable = enable; 571 572 // When we disable an einge, we also need to disable all the sub engines. 573 if (!enable && !engine->subEngines.empty()) { 574 for (StringList::const_iterator j = engine->subEngines.begin(); j != engine->subEngines.end(); ++j) { 575 EngineDescList::iterator subEngine = std::find(engines.begin(), engines.end(), *j); 576 if (subEngine != engines.end()) 577 subEngine->enable = false; 578 } 579 } 580 581 return true; 582 } 583 } 584 585 return false; 586 } 587 588 StringList getEngineDefines(const EngineDescList &engines) { 589 StringList result; 590 591 for (EngineDescList::const_iterator i = engines.begin(); i != engines.end(); ++i) { 592 if (i->enable) { 593 std::string define = "ENABLE_" + i->name; 594 std::transform(define.begin(), define.end(), define.begin(), toupper); 595 result.push_back(define); 596 } 597 } 598 599 return result; 600 } 601 602 namespace { 603 bool parseEngine(const std::string &line, EngineDesc &engine) { 604 // Format: 605 // add_engine engine_name "Readable Description" enable_default ["SubEngineList"] 606 TokenList tokens = tokenize(line); 607 608 if (tokens.size() < 4) 609 return false; 610 611 TokenList::const_iterator token = tokens.begin(); 612 613 if (*token != "add_engine") 614 return false; 615 ++token; 616 617 engine.name = *token; ++token; 618 engine.desc = *token; ++token; 619 engine.enable = (*token == "yes"); ++token; 620 if (token != tokens.end()) 621 engine.subEngines = tokenize(*token); 622 623 return true; 624 } 625 626 TokenList tokenize(const std::string &input) { 627 TokenList result; 628 629 std::string::size_type sIdx = input.find_first_not_of(" \t"); 630 std::string::size_type nIdx = std::string::npos; 631 632 if (sIdx == std::string::npos) 633 return result; 634 635 do { 636 if (input.at(sIdx) == '\"') { 637 ++sIdx; 638 nIdx = input.find_first_of('\"', sIdx); 639 } else { 640 nIdx = input.find_first_of(' ', sIdx); 641 } 642 643 if (nIdx != std::string::npos) { 644 result.push_back(input.substr(sIdx, nIdx - sIdx)); 645 sIdx = input.find_first_not_of(" \t", nIdx + 1); 646 } else { 647 result.push_back(input.substr(sIdx)); 648 break; 649 } 650 } while (sIdx != std::string::npos); 651 652 return result; 653 } 654 } // End of anonymous namespace 655 656 namespace { 657 const Feature s_features[] = { 658 // Libraries 659 { "libz", "USE_ZLIB", "zlib", true, "zlib (compression) support" }, 660 { "mad", "USE_MAD", "libmad", true, "libmad (MP3) support" }, 661 { "vorbis", "USE_VORBIS", "libvorbisfile_static libvorbis_static libogg_static", true, "Ogg Vorbis support" }, 662 { "flac", "USE_FLAC", "libFLAC_static", true, "FLAC support" }, 663 { "png", "USE_PNG", "libpng", true, "libpng support" }, 664 { "theora", "USE_THEORADEC", "libtheora_static", true, "Theora decoding support" }, 665 { "mpeg2", "USE_MPEG2", "libmpeg2", false, "mpeg2 codec for cutscenes" }, 666 667 // ScummVM feature flags 668 { "scalers", "USE_SCALERS", "", true, "Scalers" }, 669 { "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" }, 670 { "16bit", "USE_RGB_COLOR", "", true, "16bit color support" }, 671 { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, 672 { "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling. 673 { "translation", "USE_TRANSLATION", "", true, "Translation support" }, 674 { "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there 675 // is just no current way of properly detecting this... 676 }; 677 } // End of anonymous namespace 678 679 FeatureList getAllFeatures() { 680 const size_t featureCount = sizeof(s_features) / sizeof(s_features[0]); 681 682 FeatureList features; 683 for (size_t i = 0; i < featureCount; ++i) 684 features.push_back(s_features[i]); 685 686 return features; 687 } 688 689 StringList getFeatureDefines(const FeatureList &features) { 690 StringList defines; 691 692 for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i) { 693 if (i->enable && i->define && i->define[0]) 694 defines.push_back(i->define); 695 } 696 697 return defines; 698 } 699 700 StringList getFeatureLibraries(const FeatureList &features) { 701 StringList libraries; 702 703 for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i) { 704 if (i->enable && i->libraries && i->libraries[0]) { 705 StringList fLibraries = tokenize(i->libraries); 706 libraries.splice(libraries.end(), fLibraries); 707 } 708 } 709 710 return libraries; 711 } 712 713 bool setFeatureBuildState(const std::string &name, FeatureList &features, bool enable) { 714 FeatureList::iterator i = std::find(features.begin(), features.end(), name); 715 if (i != features.end()) { 716 i->enable = enable; 717 return true; 718 } else { 719 return false; 720 } 721 } 722 723 namespace CreateProjectTool { 724 725 ////////////////////////////////////////////////////////////////////////// 726 // Utilities 727 ////////////////////////////////////////////////////////////////////////// 728 729 std::string convertPathToWin(const std::string &path) { 730 std::string result = path; 731 std::replace(result.begin(), result.end(), '/', '\\'); 732 return result; 733 } 734 735 std::string getIndent(const int indentation) { 736 std::string result; 737 for (int i = 0; i < indentation; ++i) 738 result += '\t'; 739 return result; 740 } 741 742 void splitFilename(const std::string &fileName, std::string &name, std::string &ext) { 743 const std::string::size_type dot = fileName.find_last_of('.'); 744 name = (dot == std::string::npos) ? fileName : fileName.substr(0, dot); 745 ext = (dot == std::string::npos) ? std::string() : fileName.substr(dot + 1); 746 } 747 748 bool producesObjectFile(const std::string &fileName) { 749 std::string n, ext; 750 splitFilename(fileName, n, ext); 751 752 if (ext == "cpp" || ext == "c" || ext == "asm") 753 return true; 754 else 755 return false; 756 } 757 758 /** 759 * Checks whether the give file in the specified directory is present in the given 760 * file list. 761 * 762 * This function does as special match against the file list. It will not take file 763 * extensions into consideration, when the extension of a file in the specified 764 * directory is one of "h", "cpp", "c" or "asm". 765 * 766 * @param dir Parent directory of the file. 767 * @param fileName File name to match. 768 * @param fileList List of files to match against. 769 * @return "true" when the file is in the list, "false" otherwise. 770 */ 771 bool isInList(const std::string &dir, const std::string &fileName, const StringList &fileList) { 772 std::string compareName, extensionName; 773 splitFilename(fileName, compareName, extensionName); 774 775 if (!extensionName.empty()) 776 compareName += '.'; 777 778 for (StringList::const_iterator i = fileList.begin(); i != fileList.end(); ++i) { 779 if (i->compare(0, dir.size(), dir)) 780 continue; 781 782 // When no comparison name is given, we try to match whether a subset of 783 // the given directory should be included. To do that we must assure that 784 // the first character after the substring, having the same size as dir, must 785 // be a path delimiter. 786 if (compareName.empty()) { 787 if (i->size() >= dir.size() + 1 && i->at(dir.size()) == '/') 788 return true; 789 else 790 continue; 791 } 792 793 const std::string lastPathComponent = getLastPathComponent(*i); 794 if (!producesObjectFile(fileName) && extensionName != "h") { 795 if (fileName == lastPathComponent) 796 return true; 797 } else { 798 if (!lastPathComponent.compare(0, compareName.size(), compareName)) 799 return true; 800 } 801 } 802 803 return false; 804 } 805 806 /** 807 * A strict weak compare predicate for sorting a list of 808 * "FileNode *" entries. 809 * 810 * It will sort directory nodes before file nodes. 811 * 812 * @param l Left-hand operand. 813 * @param r Right-hand operand. 814 * @return "true" if and only if l should be sorted before r. 815 */ 816 bool compareNodes(const FileNode *l, const FileNode *r) { 817 if (!l) { 818 return false; 819 } else if (!r) { 820 return true; 821 } else { 822 if (l->children.empty() && !r->children.empty()) { 823 return false; 824 } else if (!l->children.empty() && r->children.empty()) { 825 return true; 826 } else { 827 return l->name < r->name; 828 } 829 } 830 } 831 832 /** 833 * Returns a list of all files and directories in the specified 834 * path. 835 * 836 * @param dir Directory which should be listed. 837 * @return List of all children. 838 */ 839 FileList listDirectory(const std::string &dir) { 840 FileList result; 841 #if defined(_WIN32) || defined(WIN32) 842 WIN32_FIND_DATA fileInformation; 843 HANDLE fileHandle = FindFirstFile((dir + "/*").c_str(), &fileInformation); 844 845 if (fileHandle == INVALID_HANDLE_VALUE) 846 return result; 847 848 do { 849 if (fileInformation.cFileName[0] == '.') 850 continue; 851 852 result.push_back(FSNode(fileInformation.cFileName, (fileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)); 853 } while (FindNextFile(fileHandle, &fileInformation) == TRUE); 854 855 FindClose(fileHandle); 856 #else 857 DIR *dirp = opendir(dir.c_str()); 858 struct dirent *dp = NULL; 859 860 if (dirp == NULL) 861 return result; 862 863 while ((dp = readdir(dirp)) != NULL) { 864 if (dp->d_name[0] == '.') 865 continue; 866 867 struct stat st; 868 if (stat((dir + '/' + dp->d_name).c_str(), &st)) 869 continue; 870 871 result.push_back(FSNode(dp->d_name, S_ISDIR(st.st_mode))); 872 } 873 874 closedir(dirp); 875 #endif 876 return result; 877 } 878 879 /** 880 * Scans the specified directory against files, which should be included 881 * in the project files. It will not include files present in the exclude list. 882 * 883 * @param dir Directory in which to search for files. 884 * @param includeList Files to include in the project. 885 * @param excludeList Files to exclude from the project. 886 * @return Returns a file node for the specific directory. 887 */ 888 FileNode *scanFiles(const std::string &dir, const StringList &includeList, const StringList &excludeList) { 889 FileList files = listDirectory(dir); 890 891 if (files.empty()) 892 return 0; 893 894 FileNode *result = new FileNode(dir); 895 assert(result); 896 897 for (FileList::const_iterator i = files.begin(); i != files.end(); ++i) { 898 if (i->isDirectory) { 899 const std::string subDirName = dir + '/' + i->name; 900 if (!isInList(subDirName, std::string(), includeList)) 901 continue; 902 903 FileNode *subDir = scanFiles(subDirName, includeList, excludeList); 904 905 if (subDir) { 906 subDir->name = i->name; 907 result->children.push_back(subDir); 908 } 909 continue; 910 } 911 912 if (isInList(dir, i->name, excludeList)) 913 continue; 914 915 std::string name, ext; 916 splitFilename(i->name, name, ext); 917 918 if (ext != "h") { 919 if (!isInList(dir, i->name, includeList)) 920 continue; 921 } 922 923 FileNode *child = new FileNode(i->name); 924 assert(child); 925 result->children.push_back(child); 926 } 927 928 if (result->children.empty()) { 929 delete result; 930 return 0; 931 } else { 932 result->children.sort(compareNodes); 933 return result; 934 } 935 } 936 937 ////////////////////////////////////////////////////////////////////////// 938 // Project Provider methods 939 ////////////////////////////////////////////////////////////////////////// 940 ProjectProvider::ProjectProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version) 941 : _version(version), _globalWarnings(global_warnings), _projectWarnings(project_warnings) { 942 } 943 944 void ProjectProvider::createProject(const BuildSetup &setup) { 945 _uuidMap = createUUIDMap(setup); 946 947 // We also need to add the UUID of the main project file. 948 const std::string svmUUID = _uuidMap["scummvm"] = createUUID(); 949 950 // Create Solution/Workspace file 951 createWorkspace(setup); 952 953 StringList in, ex; 954 955 // Create engine project files 956 for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { 957 if (i->first == "scummvm") 958 continue; 959 960 in.clear(); ex.clear(); 961 const std::string moduleDir = setup.srcDir + "/engines/" + i->first; 962 963 createModuleList(moduleDir, setup.defines, in, ex); 964 createProjectFile(i->first, i->second, setup, moduleDir, in, ex); 965 } 966 967 // Last but not least create the main ScummVM project file. 968 in.clear(); ex.clear(); 969 970 // File list for the ScummVM project file 971 createModuleList(setup.srcDir + "/backends", setup.defines, in, ex); 972 createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, in, ex); 973 createModuleList(setup.srcDir + "/base", setup.defines, in, ex); 974 createModuleList(setup.srcDir + "/common", setup.defines, in, ex); 975 createModuleList(setup.srcDir + "/engines", setup.defines, in, ex); 976 createModuleList(setup.srcDir + "/graphics", setup.defines, in, ex); 977 createModuleList(setup.srcDir + "/gui", setup.defines, in, ex); 978 createModuleList(setup.srcDir + "/sound", setup.defines, in, ex); 979 createModuleList(setup.srcDir + "/sound/softsynth/mt32", setup.defines, in, ex); 980 981 // Resource files 982 in.push_back(setup.srcDir + "/icons/scummvm.ico"); 983 in.push_back(setup.srcDir + "/dists/scummvm.rc"); 984 985 // Various text files 986 in.push_back(setup.srcDir + "/AUTHORS"); 987 in.push_back(setup.srcDir + "/COPYING"); 988 in.push_back(setup.srcDir + "/COPYING.LGPL"); 989 in.push_back(setup.srcDir + "/COPYRIGHT"); 990 in.push_back(setup.srcDir + "/NEWS"); 991 in.push_back(setup.srcDir + "/README"); 992 in.push_back(setup.srcDir + "/TODO"); 993 994 // Create the scummvm project file. 995 createProjectFile("scummvm", svmUUID, setup, setup.srcDir, in, ex); 996 997 // Create other misc. build files 998 createOtherBuildFiles(setup); 999 } 1000 1001 ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const { 1002 UUIDMap result; 1003 1004 for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) { 1005 if (!i->enable || isSubEngine(i->name, setup.engines)) 1006 continue; 1007 1008 result[i->name] = createUUID(); 1009 } 1010 1011 return result; 1012 } 1013 1014 std::string ProjectProvider::createUUID() const { 1015 #if defined(_WIN32) || defined(WIN32) 1016 UUID uuid; 1017 if (UuidCreate(&uuid) != RPC_S_OK) 1018 error("UuidCreate failed"); 1019 1020 unsigned char *string = 0; 1021 if (UuidToStringA(&uuid, &string) != RPC_S_OK) 1022 error("UuidToStringA failed"); 1023 1024 std::string result = std::string((char *)string); 1025 std::transform(result.begin(), result.end(), result.begin(), toupper); 1026 RpcStringFreeA(&string); 1027 return result; 1028 #else 1029 unsigned char uuid[16]; 1030 1031 for (int i = 0; i < 16; ++i) 1032 uuid[i] = (unsigned char)((std::rand() / (double)(RAND_MAX)) * 0xFF); 1033 1034 uuid[8] &= 0xBF; uuid[8] |= 0x80; 1035 uuid[6] &= 0x4F; uuid[6] |= 0x40; 1036 1037 std::stringstream uuidString; 1038 uuidString << std::hex << std::uppercase << std::setfill('0'); 1039 for (int i = 0; i < 16; ++i) { 1040 uuidString << std::setw(2) << (int)uuid[i]; 1041 if (i == 3 || i == 5 || i == 7 || i == 9) { 1042 uuidString << std::setw(0) << '-'; 1043 } 1044 } 1045 1046 return uuidString.str(); 1047 #endif 1048 } 1049 1050 void ProjectProvider::addFilesToProject(const std::string &dir, std::ofstream &projectFile, 1051 const StringList &includeList, const StringList &excludeList, 1052 const std::string &filePrefix) { 1053 // Check for duplicate object file names 1054 StringList duplicate; 1055 1056 for (StringList::const_iterator i = includeList.begin(); i != includeList.end(); ++i) { 1057 const std::string fileName = getLastPathComponent(*i); 1058 1059 // Leave out non object file names. 1060 if (fileName.size() < 2 || fileName.compare(fileName.size() - 2, 2, ".o")) 1061 continue; 1062 1063 // Check whether an duplicate has been found yet 1064 if (std::find(duplicate.begin(), duplicate.end(), fileName) != duplicate.end()) 1065 continue; 1066 1067 // Search for duplicates 1068 StringList::const_iterator j = i; ++j; 1069 for (; j != includeList.end(); ++j) { 1070 if (fileName == getLastPathComponent(*j)) { 1071 duplicate.push_back(fileName); 1072 break; 1073 } 1074 } 1075 } 1076 1077 FileNode *files = scanFiles(dir, includeList, excludeList); 1078 1079 writeFileListToProject(*files, projectFile, 0, duplicate, std::string(), filePrefix + '/'); 1080 1081 delete files; 1082 } 1083 1084 void ProjectProvider::createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const { 1085 const std::string moduleMkFile = moduleDir + "/module.mk"; 1086 std::ifstream moduleMk(moduleMkFile.c_str()); 1087 if (!moduleMk) 1088 error(moduleMkFile + " is not present"); 1089 1090 includeList.push_back(moduleMkFile); 1091 1092 std::stack<bool> shouldInclude; 1093 shouldInclude.push(true); 1094 1095 bool hadModule = false; 1096 std::string line; 1097 for (;;) { 1098 std::getline(moduleMk, line); 1099 1100 if (moduleMk.eof()) 1101 break; 1102 1103 if (moduleMk.fail()) 1104 error("Failed while reading from " + moduleMkFile); 1105 1106 TokenList tokens = tokenize(line); 1107 if (tokens.empty()) 1108 continue; 1109 1110 TokenList::const_iterator i = tokens.begin(); 1111 if (*i == "MODULE") { 1112 if (hadModule) 1113 error("More than one MODULE definition in " + moduleMkFile); 1114 // Format: "MODULE := path/to/module" 1115 if (tokens.size() < 3) 1116 error("Malformed MODULE definition in " + moduleMkFile); 1117 ++i; 1118 if (*i != ":=") 1119 error("Malformed MODULE definition in " + moduleMkFile); 1120 ++i; 1121 1122 std::string moduleRoot = unifyPath(*i); 1123 if (moduleDir.compare(moduleDir.size() - moduleRoot.size(), moduleRoot.size(), moduleRoot)) 1124 error("MODULE root " + moduleRoot + " does not match base dir " + moduleDir); 1125 1126 hadModule = true; 1127 } else if (*i == "MODULE_OBJS") { 1128 if (tokens.size() < 3) 1129 error("Malformed MODULE_OBJS definition in " + moduleMkFile); 1130 ++i; 1131 1132 // This is not exactly correct, for example an ":=" would usually overwrite 1133 // all already added files, but since we do only save the files inside 1134 // includeList or excludeList currently, we couldn't handle such a case easily. 1135 // (includeList and excludeList should always preserve their entries, not added 1136 // by this function, thus we can't just clear them on ":=" or "="). 1137 // But hopefully our module.mk files will never do such things anyway. 1138 if (*i != ":=" && *i != "+=" && *i != "=") 1139 error("Malformed MODULE_OBJS definition in " + moduleMkFile); 1140 1141 ++i; 1142 1143 while (i != tokens.end()) { 1144 if (*i == "\\") { 1145 std::getline(moduleMk, line); 1146 tokens = tokenize(line); 1147 i = tokens.begin(); 1148 } else { 1149 if (shouldInclude.top()) 1150 includeList.push_back(moduleDir + "/" + unifyPath(*i)); 1151 else 1152 excludeList.push_back(moduleDir + "/" + unifyPath(*i)); 1153 ++i; 1154 } 1155 } 1156 } else if (*i == "ifdef") { 1157 if (tokens.size() < 2) 1158 error("Malformed ifdef in " + moduleMkFile); 1159 ++i; 1160 1161 if (std::find(defines.begin(), defines.end(), *i) == defines.end()) 1162 shouldInclude.push(false); 1163 else 1164 shouldInclude.push(true); 1165 } else if (*i == "ifndef") { 1166 if (tokens.size() < 2) 1167 error("Malformed ifndef in " + moduleMkFile); 1168 ++i; 1169 1170 if (std::find(defines.begin(), defines.end(), *i) == defines.end()) 1171 shouldInclude.push(true); 1172 else 1173 shouldInclude.push(false); 1174 } else if (*i == "else") { 1175 shouldInclude.top() = !shouldInclude.top(); 1176 } else if (*i == "endif") { 1177 if (shouldInclude.size() <= 1) 1178 error("endif without ifdef found in " + moduleMkFile); 1179 shouldInclude.pop(); 1180 } else if (*i == "elif") { 1181 error("Unsupported operation 'elif' in " + moduleMkFile); 1182 } else if (*i == "ifeq") { 1183 //XXX 1184 shouldInclude.push(false); 1185 } 1186 } 1187 1188 if (shouldInclude.size() != 1) 1189 error("Malformed file " + moduleMkFile); 1190 } 1191 1192 } // End of anonymous namespace 1193 1194 void error(const std::string &message) { 1195 std::cerr << "ERROR: " << message << "!" << std::endl; 1196 std::exit(-1); 1197 } -
new file tools/create_project/create_project.h
diff -r e24b1c8ca942 tools/create_project/create_project.h
- + 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #ifndef TOOLS_CREATE_PROJECT_H 27 #define TOOLS_CREATE_PROJECT_H 28 29 #include <map> 30 #include <list> 31 #include <string> 32 33 #include <cassert> 34 35 // The PP_NARG macro returns the number of arguments that have been passed to it. 36 #define PP_NARG(...) \ 37 PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) 38 #define PP_NARG_(...) \ 39 PP_ARG_N(__VA_ARGS__) 40 #define PP_ARG_N( \ 41 _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ 42 _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ 43 _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ 44 _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ 45 _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ 46 _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ 47 _61,_62,_63,N,...) N 48 #define PP_RSEQ_N() \ 49 63,62,61,60, \ 50 59,58,57,56,55,54,53,52,51,50, \ 51 49,48,47,46,45,44,43,42,41,40, \ 52 39,38,37,36,35,34,33,32,31,30, \ 53 29,28,27,26,25,24,23,22,21,20, \ 54 19,18,17,16,15,14,13,12,11,10, \ 55 9,8,7,6,5,4,3,2,1,0 56 57 #define SET_VALUES(list, ...) \ 58 { \ 59 std::string values[PP_NARG(__VA_ARGS__)] = { __VA_ARGS__ }; \ 60 list.assign(values, values + (sizeof(values) / sizeof(values[0]))); \ 61 } 62 63 typedef std::list<std::string> StringList; 64 65 /** 66 * Structure to describe a game engine to be built into ScummVM. 67 * 68 * We do get the game engines available by parsing the "configure" 69 * script of our source distribution. See "parseConfigure" for more 70 * information on that. 71 * @see parseConfigure 72 */ 73 struct EngineDesc { 74 /** 75 * The name of the engine. We use this to determine the directory 76 * the engine is in and to create the define, which needs to be 77 * set to enable the engine. 78 */ 79 std::string name; 80 81 /** 82 * A human readable description of the engine. We will use this 83 * to display a description of the engine to the user in the list 84 * of which engines are built and which are disabled. 85 */ 86 std::string desc; 87 88 /** 89 * Whether the engine should be included in the build or not. 90 */ 91 bool enable; 92 93 /** 94 * A list of all available sub engine names. Sub engines are engines 95 * which are built on top of an existing engines and can be only 96 * enabled when the parten engine is enabled. 97 */ 98 StringList subEngines; 99 100 bool operator==(const std::string &n) const { 101 return (name == n); 102 } 103 }; 104 105 typedef std::list<EngineDesc> EngineDescList; 106 107 /** 108 * This function parses the ScummVM configure file and creates a list 109 * of available engines. 110 * 111 * It will also automatically setup the default build state (enabled 112 * or disabled) to the state specified in the "configure" file. 113 * 114 * @param srcDir Path to the root of the ScummVM source. 115 * @return List of available engines. 116 */ 117 EngineDescList parseConfigure(const std::string &srcDir); 118 119 /** 120 * Checks whether the specified engine is a sub engine. To determine this 121 * there is a fully setup engine list needed. 122 * 123 * @param name Name of the engine to check. 124 * @param engines List of engines. 125 * @return "true", when the engine is a sub engine, "false" otherwise. 126 */ 127 bool isSubEngine(const std::string &name, const EngineDescList &engines); 128 129 /** 130 * Enables or disables the specified engine in the engines list. 131 * 132 * This function also disables all sub engines of an engine, when it is 133 * to be disabled. 134 * Also this function does enable the parent of a sub engine, when a 135 * sub engine is to be enabled. 136 * 137 * @param name Name of the engine to be enabled or disabled. 138 * @param engines The list of engines, which should be operated on. 139 * @param enable Whether the engine should be enabled or disabled. 140 * @return "true", when it succeeded, "false" otherwise. 141 */ 142 bool setEngineBuildState(const std::string &name, EngineDescList &engines, bool enable); 143 144 /** 145 * Returns a list of all defines, according to the engine list passed. 146 * 147 * @param features The list of engines, which should be operated on. (this may contain engines, which are *not* enabled!) 148 */ 149 StringList getEngineDefines(const EngineDescList &engines); 150 151 /** 152 * Structure to define a given feature, usually an external library, 153 * used to build ScummVM. 154 */ 155 struct Feature { 156 const char *name; ///< Name of the feature 157 const char *define; ///< Define of the feature 158 159 const char *libraries; ///< Libraries, which need to be linked, for the feature 160 161 bool enable; ///< Whether the feature is enabled or not 162 163 const char *description; ///< Human readable description of the feature 164 165 bool operator==(const std::string &n) const { 166 return (name == n); 167 } 168 }; 169 typedef std::list<Feature> FeatureList; 170 171 /** 172 * Creates a list of all features available for MSVC. 173 * 174 * @return A list including all features available. 175 */ 176 FeatureList getAllFeatures(); 177 178 /** 179 * Returns a list of all defines, according to the feature set 180 * passed. 181 * 182 * @param features List of features for the build (this may contain features, which are *not* enabled!) 183 */ 184 StringList getFeatureDefines(const FeatureList &features); 185 186 /** 187 * Returns a list of all external library files, according to the 188 * feature set passed. 189 * 190 * @param features List of features for the build (this may contain features, which are *not* enabled!) 191 */ 192 StringList getFeatureLibraries(const FeatureList &features); 193 194 /** 195 * Sets the state of a given feature. This can be used to 196 * either include or exclude an feature. 197 * 198 * @param name Name of the feature. 199 * @param features List of features to operate on. 200 * @param enable Whether the feature should be enabled or disabled. 201 * @return "true", when it succeeded, "false" otherwise. 202 */ 203 bool setFeatureBuildState(const std::string &name, FeatureList &features, bool enable); 204 205 /** 206 * Structure to describe a MSVC build setup. 207 * 208 * This includes various information about which engines to 209 * enable, which features should be built into ScummVM. 210 * It also contains the path to the ScummVM souce root. 211 */ 212 struct BuildSetup { 213 std::string srcDir; ///< Path to the ScummVM sources. 214 std::string filePrefix; ///< Prefix for the relative path arguments in the project files. 215 std::string outputDir; ///< Path where to put the MSVC project files. 216 217 EngineDescList engines; ///< Engine list for the build (this may contain engines, which are *not* enabled!). 218 FeatureList features; ///< Feature list for the build (this may contain features, which are *not* enabled!). 219 220 StringList defines; ///< List of all defines for the build. 221 StringList libraries; ///< List of all external libraries required for the build. 222 }; 223 224 /** 225 * Quits the program with the specified error message. 226 * 227 * @param message The error message to print to stderr. 228 */ 229 #if defined(__GNUC__) 230 #define NORETURN_POST __attribute__((__noreturn__)) 231 #elif defined(_MSC_VER) 232 #define NORETURN_PRE __declspec(noreturn) 233 #endif 234 235 #ifndef NORETURN_PRE 236 #define NORETURN_PRE 237 #endif 238 239 #ifndef NORETURN_POST 240 #define NORETURN_POST 241 #endif 242 void NORETURN_PRE error(const std::string &message) NORETURN_POST; 243 244 namespace CreateProjectTool { 245 246 /** 247 * Gets a proper sequence of \t characters for the given 248 * indentation level. 249 * 250 * For example with an indentation level of 2 this will 251 * produce: 252 * \t\t 253 * 254 * @param indentation The indentation level 255 * @return Sequence of \t characters. 256 */ 257 std::string getIndent(const int indentation); 258 259 /** 260 * Converts the given path to only use backslashes. 261 * This means that for example the path: 262 * foo/bar\test.txt 263 * will be converted to: 264 * foo\bar\test.txt 265 * 266 * @param path Path string. 267 * @return Converted path. 268 */ 269 std::string convertPathToWin(const std::string &path); 270 271 /** 272 * Splits a file name into name and extension. 273 * The file name must be only the filename, no 274 * additional path name. 275 * 276 * @param fileName Filename to split 277 * @param name Reference to a string, where to store the name. 278 * @param ext Reference to a string, where to store the extension. 279 */ 280 void splitFilename(const std::string &fileName, std::string &name, std::string &ext); 281 282 /** 283 * Checks whether the given file will produce an object file or not. 284 * 285 * @param fileName Name of the file. 286 * @return "true" when it will produce a file, "false" otherwise. 287 */ 288 bool producesObjectFile(const std::string &fileName); 289 290 /** 291 * Structure representing a file tree. This contains two 292 * members: name and children. "name" holds the name of 293 * the node. "children" does contain all the node's children. 294 * When the list "children" is empty, the node is a file entry, 295 * otherwise it's a directory. 296 */ 297 struct FileNode { 298 typedef std::list<FileNode *> NodeList; 299 300 explicit FileNode(const std::string &n) : name(n), children() {} 301 302 ~FileNode() { 303 for (NodeList::iterator i = children.begin(); i != children.end(); ++i) 304 delete *i; 305 } 306 307 std::string name; ///< Name of the node 308 NodeList children; ///< List of children for the node 309 }; 310 311 class ProjectProvider { 312 public: 313 typedef std::map<std::string, std::string> UUIDMap; 314 315 /** 316 * Instantiate new ProjectProvider class 317 * 318 * @param global_warnings List of warnings that apply to all projects 319 * @param project_warnings List of project-specific warnings 320 * @param version Target project version. 321 */ 322 ProjectProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version = 0); 323 virtual ~ProjectProvider() {} 324 325 /** 326 * Creates all build files 327 * 328 * @param setup Description of the desired build setup. 329 */ 330 void createProject(const BuildSetup &setup); 331 332 protected: 333 const int _version; ///< Target project version 334 StringList &_globalWarnings; ///< Global warnings 335 std::map<std::string, StringList> &_projectWarnings; ///< Per-project warnings 336 337 UUIDMap _uuidMap; ///< List of (project name, UUID) pairs 338 339 /** 340 * Create workspace/solution file 341 * 342 * @param setup Description of the desired build setup. 343 */ 344 virtual void createWorkspace(const BuildSetup &setup) = 0; 345 346 /** 347 * Create other files (such as build properties) 348 * 349 * @param setup Description of the desired build setup. 350 */ 351 virtual void createOtherBuildFiles(const BuildSetup &setup) = 0; 352 353 /** 354 * Create a project file for the specified list of files. 355 * 356 * @param name Name of the project file. 357 * @param uuid UUID of the project file. 358 * @param setup Description of the desired build. 359 * @param moduleDir Path to the module. 360 * @param includeList Files to include (must have "moduleDir" as prefix). 361 * @param excludeList Files to exclude (must have "moduleDir" as prefix). 362 */ 363 virtual void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, 364 const StringList &includeList, const StringList &excludeList) = 0; 365 366 /** 367 * Writes file entries for the specified directory node into 368 * the given project file. It will also take care of duplicate 369 * object files. 370 * 371 * @param dir Directory node. 372 * @param projectFile File stream to write to. 373 * @param indentation Indentation level to use. 374 * @param duplicate List of duplicate object file names. 375 * @param objPrefix Prefix to use for object files, which would name clash. 376 * @param filePrefix Generic prefix to all files of the node. 377 */ 378 virtual void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, 379 const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) = 0; 380 381 /** 382 * Output a list of project references to the file stream 383 * 384 * @param output File stream to write to. 385 */ 386 virtual void writeReferences(std::ofstream &) {}; 387 388 /** 389 * Get the file extension for project files 390 */ 391 virtual const char *getProjectExtension() { return ""; } 392 393 /** 394 * Adds files of the specified directory recursively to given project file. 395 * 396 * @param dir Path to the directory. 397 * @param projectFile Output stream object, where all data should be written to. 398 * @param includeList Files to include (must have a relative directory as prefix). 399 * @param excludeList Files to exclude (must have a relative directory as prefix). 400 * @param filePrefix Prefix to use for relative path arguments. 401 */ 402 void addFilesToProject(const std::string &dir, std::ofstream &projectFile, 403 const StringList &includeList, const StringList &excludeList, 404 const std::string &filePrefix); 405 406 /** 407 * Creates a list of files of the specified module. This also 408 * creates a list of files, which should not be included. 409 * All filenames will have "moduleDir" as prefix. 410 * 411 * @param moduleDir Path to the module. 412 * @param defines List of set defines. 413 * @param includeList Reference to a list, where included files should be added. 414 * @param excludeList Reference to a list, where excluded files should be added. 415 */ 416 void createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const; 417 418 /** 419 * Creates an UUID for every enabled engine of the 420 * passed build description. 421 * 422 * @param setup Description of the desired build. 423 * @return A map, which includes UUIDs for all enabled engines. 424 */ 425 UUIDMap createUUIDMap(const BuildSetup &setup) const; 426 427 /** 428 * Creates an UUID and returns it in string representation. 429 * 430 * @return A new UUID as string. 431 */ 432 std::string createUUID() const; 433 }; 434 435 } // End of CreateProjectTool namespace 436 437 #endif // TOOLS_CREATE_PROJECT_H -
new file tools/create_project/module.mk
diff -r e24b1c8ca942 tools/create_project/module.mk
- + 1 # $URL$ 2 # $Id$ 3 4 MODULE := tools/create_project 5 6 MODULE_OBJS := \ 7 create_project.o \ 8 codeblocks.o \ 9 msvc.o 10 11 # Set the name of the executable 12 TOOL_EXECUTABLE := create_project 13 14 # Include common rules 15 include $(srcdir)/rules.mk 16 17 # Silence variadic macros warning for C++ 18 CXXFLAGS := $(CXXFLAGS) -Wno-variadic-macros -
new file tools/create_project/msvc.cpp
diff -r e24b1c8ca942 tools/create_project/msvc.cpp
- + 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #include "msvc.h" 27 28 #include <fstream> 29 30 #include <algorithm> 31 32 namespace CreateProjectTool { 33 34 ////////////////////////////////////////////////////////////////////////// 35 // MSVC Provider (Base class) 36 ////////////////////////////////////////////////////////////////////////// 37 MSVCProvider::MSVCProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version) 38 : ProjectProvider(global_warnings, project_warnings, version) { 39 } 40 41 void MSVCProvider::createWorkspace(const BuildSetup &setup) { 42 UUIDMap::const_iterator svmUUID = _uuidMap.find("scummvm"); 43 if (svmUUID == _uuidMap.end()) 44 error("No UUID for \"scummvm\" project created"); 45 46 const std::string svmProjectUUID = svmUUID->second; 47 assert(!svmProjectUUID.empty()); 48 49 std::string solutionUUID = createUUID(); 50 51 std::ofstream solution((setup.outputDir + '/' + "scummvm.sln").c_str()); 52 if (!solution) 53 error("Could not open \"" + setup.outputDir + '/' + "scummvm.sln\" for writing"); 54 55 solution << "Microsoft Visual Studio Solution File, Format Version " << _version + 1 << ".00\n"; 56 solution << "# Visual Studio " << getVisualStudioVersion() << "\n"; 57 58 solution << "Project(\"{" << solutionUUID << "}\") = \"scummvm\", \"scummvm" << getProjectExtension() << "\", \"{" << svmProjectUUID << "}\"\n"; 59 60 // Project dependencies are moved to vcxproj files in Visual Studio 2010 61 if (_version < 10) 62 writeReferences(solution); 63 64 solution << "EndProject\n"; 65 66 // Note we assume that the UUID map only includes UUIDs for enabled engines! 67 for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { 68 if (i->first == "scummvm") 69 continue; 70 71 solution << "Project(\"{" << solutionUUID << "}\") = \"" << i->first << "\", \"" << i->first << getProjectExtension() << "\", \"{" << i->second << "}\"\n" 72 << "EndProject\n"; 73 } 74 75 solution << "Global\n" 76 "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" 77 "\t\tDebug|Win32 = Debug|Win32\n" 78 "\t\tRelease|Win32 = Release|Win32\n" 79 "\t\tDebug|x64 = Debug|x64\n" 80 "\t\tRelease|x64 = Release|x64\n" 81 "\tEndGlobalSection\n" 82 "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"; 83 84 for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { 85 solution << "\t\t{" << i->second << "}.Debug|Win32.ActiveCfg = Debug|Win32\n" 86 << "\t\t{" << i->second << "}.Debug|Win32.Build.0 = Debug|Win32\n" 87 << "\t\t{" << i->second << "}.Release|Win32.ActiveCfg = Release|Win32\n" 88 << "\t\t{" << i->second << "}.Release|Win32.Build.0 = Release|Win32\n" 89 << "\t\t{" << i->second << "}.Debug|x64.ActiveCfg = Debug|x64\n" 90 << "\t\t{" << i->second << "}.Debug|x64.Build.0 = Debug|x64\n" 91 << "\t\t{" << i->second << "}.Release|x64.ActiveCfg = Release|x64\n" 92 << "\t\t{" << i->second << "}.Release|x64.Build.0 = Release|x64\n"; 93 } 94 95 solution << "\tEndGlobalSection\n" 96 "\tGlobalSection(SolutionProperties) = preSolution\n" 97 "\t\tHideSolutionNode = FALSE\n" 98 "\tEndGlobalSection\n" 99 "EndGlobal\n"; 100 } 101 102 void MSVCProvider::createOtherBuildFiles(const BuildSetup &setup) { 103 // Create the global property file 104 createGlobalProp(setup); 105 106 // Create the configuration property files (for Debug and Release with 32 and 64bits versions) 107 createBuildProp(setup, true, false); 108 createBuildProp(setup, true, true); 109 createBuildProp(setup, false, false); 110 createBuildProp(setup, false, true); 111 } 112 113 void MSVCProvider::createGlobalProp(const BuildSetup &setup) { 114 std::ofstream properties((setup.outputDir + '/' + "ScummVM_Global" + getPropertiesExtension()).c_str()); 115 if (!properties) 116 error("Could not open \"" + setup.outputDir + '/' + "ScummVM_Global" + getPropertiesExtension() + "\" for writing"); 117 118 outputGlobalPropFile(properties, 32, setup.defines, convertPathToWin(setup.filePrefix)); 119 properties.close(); 120 121 properties.open((setup.outputDir + '/' + "ScummVM_Global64" + getPropertiesExtension()).c_str()); 122 if (!properties) 123 error("Could not open \"" + setup.outputDir + '/' + "ScummVM_Global64" + getPropertiesExtension() + "\" for writing"); 124 125 // HACK: We must disable the "nasm" feature for x64. To achieve that we must duplicate the feature list and 126 // recreate a define list. 127 FeatureList x64Features = setup.features; 128 setFeatureBuildState("nasm", x64Features, false); 129 StringList x64Defines = getFeatureDefines(x64Features); 130 StringList x64EngineDefines = getEngineDefines(setup.engines); 131 x64Defines.splice(x64Defines.end(), x64EngineDefines); 132 133 outputGlobalPropFile(properties, 64, x64Defines, convertPathToWin(setup.filePrefix)); 134 } 135 136 std::string MSVCProvider::getRevisionToolCommandLine() const { 137 std::string cmdLine = ""; 138 139 cmdLine = "@echo off\n" 140 "ECHO Generating revision number\n" 141 "IF NOT EXIST "$(SolutionDir)../../.svn/" GOTO working_copy\n" 142 "SubWCRev.exe "$(SolutionDir)../.." "$(SolutionDir)../../base/internal_version.h.tpl" "$(SolutionDir)../../base/internal_version.h"\n" 143 "IF NOT %errorlevel%==0 GOTO error\n" 144 ":working_copy\n" 145 "ECHO Not a working copy, skipping...\n" 146 "EXIT /B0\n" 147 ":error\n" 148 "ECHO SubWCRev not found, skipping...\n" 149 "EXIT /B0"; 150 151 return cmdLine; 152 } 153 154 std::string MSVCProvider::getCopyDataCommandLine(bool isWin32) const { 155 std::string cmdLine = ""; 156 157 // Copy data files and themes 158 cmdLine = "@echo off\n" 159 "ECHO Copying data files\n" 160 "xcopy /F /Y "$(SolutionDir)../engine-data/*.dat" $(OutDir)\n" 161 "xcopy /F /Y "$(SolutionDir)../engine-data/*.tbl" $(OutDir)\n" 162 "xcopy /F /Y "$(SolutionDir)../engine-data/*.cpt" $(OutDir)\n" 163 "xcopy /F /Y "$(SolutionDir)../engine-data/README" $(OutDir)\n" 164 "xcopy /F /Y "$(SolutionDir)../../gui/themes/*.zip" $(OutDir)\n" 165 "xcopy /F /Y "$(SolutionDir)../../gui/themes/translations.dat" $(OutDir)\n"; 166 167 cmdLine += "xcopy /F /Y "$(SCUMMVM_LIBS)/lib/"; 168 cmdLine += (isWin32 ? "x86" : "x64"); 169 cmdLine += "/SDL.dll" $(OutDir)"; 170 171 return cmdLine; 172 } 173 174 ////////////////////////////////////////////////////////////////////////// 175 // Visual Studio Provider 176 ////////////////////////////////////////////////////////////////////////// 177 178 VisualStudioProvider::VisualStudioProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version) 179 : MSVCProvider(global_warnings, project_warnings, version) { 180 } 181 182 const char *VisualStudioProvider::getProjectExtension() { 183 return ".vcproj"; 184 } 185 186 const char *VisualStudioProvider::getPropertiesExtension() { 187 return ".vsprops"; 188 } 189 190 int VisualStudioProvider::getVisualStudioVersion() { 191 if (_version == 9) 192 return 2008; 193 194 if (_version == 8) 195 return 2005; 196 197 error("Unsupported version passed to createScummVMSolution"); 198 } 199 200 void VisualStudioProvider::createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, 201 const StringList &includeList, const StringList &excludeList) { 202 const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension(); 203 std::ofstream project(projectFile.c_str()); 204 if (!project) 205 error("Could not open \"" + projectFile + "\" for writing"); 206 207 project << "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\n" 208 "<VisualStudioProject\n" 209 "\tProjectType=\"Visual C++\"\n" 210 "\tVersion=\"" << _version << ".00\"\n" 211 "\tName=\"" << name << "\"\n" 212 "\tProjectGUID=\"{" << uuid << "}\"\n" 213 "\tRootNamespace=\"" << name << "\"\n" 214 "\tKeyword=\"Win32Proj\"\n"; 215 216 if (_version >= 9) 217 project << "\tTargetFrameworkVersion=\"131072\"\n"; 218 219 project << "\t>\n" 220 "\t<Platforms>\n" 221 "\t\t<Platform Name=\"Win32\" />\n" 222 "\t\t<Platform Name=\"x64\" />\n" 223 "\t</Platforms>\n" 224 "\t<Configurations>\n"; 225 226 // Check for project-specific warnings: 227 std::map< std::string, std::list<std::string> >::iterator warningsIterator = _projectWarnings.find(name); 228 229 if (name == "scummvm") { 230 std::string libraries; 231 232 for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) 233 libraries += ' ' + *i + ".lib"; 234 235 // Win32 236 project << "\t\t<Configuration Name=\"Debug|Win32\" ConfigurationType=\"1\" InheritedPropertySheets=\".\\ScummVM_Debug.vsprops\">\n" 237 "\t\t\t<Tool\tName=\"VCCLCompilerTool\" DisableLanguageExtensions=\"false\" />\n" 238 "\t\t\t<Tool\tName=\"VCLinkerTool\" OutputFile=\"$(OutDir)/scummvm.exe\"\n" 239 "\t\t\t\tAdditionalDependencies=\"" << libraries << "\"\n" 240 "\t\t\t/>\n" 241 "\t\t\t<Tool\tName=\"VCPreBuildEventTool\"\n" 242 "\t\t\t\tCommandLine=\"" << getRevisionToolCommandLine() << "\"\n" 243 "\t\t\t/>\n" 244 "\t\t\t<Tool\tName=\"VCPostBuildEventTool\"\n" 245 "\t\t\t\tCommandLine=\"" << getCopyDataCommandLine(true) << "\"\n" 246 "\t\t\t/>\n" 247 "\t\t</Configuration>\n" 248 "\t\t<Configuration Name=\"Release|Win32\" ConfigurationType=\"1\" InheritedPropertySheets=\".\\ScummVM_Release.vsprops\">\n" 249 "\t\t\t<Tool\tName=\"VCCLCompilerTool\" DisableLanguageExtensions=\"false\" />\n" 250 "\t\t\t<Tool\tName=\"VCLinkerTool\" OutputFile=\"$(OutDir)/scummvm.exe\"\n" 251 "\t\t\t\tAdditionalDependencies=\"" << libraries << "\"\n" 252 "\t\t\t/>\n" 253 "\t\t</Configuration>\n"; 254 255 // x64 256 // For 'x64' we must disable NASM support. Usually we would need to disable the "nasm" feature for that and 257 // re-create the library list, BUT since NASM doesn't link any additional libraries, we can just use the 258 // libraries list created for IA-32. If that changes in the future, we need to adjust this part! 259 project << "\t\t<Configuration Name=\"Debug|x64\" ConfigurationType=\"1\" InheritedPropertySheets=\".\\ScummVM_Debug64.vsprops\">\n" 260 "\t\t\t<Tool\tName=\"VCCLCompilerTool\" DisableLanguageExtensions=\"false\" />\n" 261 "\t\t\t<Tool\tName=\"VCLinkerTool\" OutputFile=\"$(OutDir)/scummvm.exe\"\n" 262 "\t\t\t\tAdditionalDependencies=\"" << libraries << "\"\n" 263 "\t\t\t/>\n" 264 "\t\t\t<Tool\tName=\"VCPreBuildEventTool\"\n" 265 "\t\t\t\tCommandLine=\"" << getRevisionToolCommandLine() << "\"\n" 266 "\t\t\t/>\n" 267 "\t\t\t<Tool\tName=\"VCPostBuildEventTool\"\n" 268 "\t\t\t\tCommandLine=\"" << getCopyDataCommandLine(false) << "\"\n" 269 "\t\t\t/>\n" 270 "\t\t</Configuration>\n" 271 "\t\t<Configuration Name=\"Release|x64\" ConfigurationType=\"1\" InheritedPropertySheets=\".\\ScummVM_Release64.vsprops\">\n" 272 "\t\t\t<Tool\tName=\"VCCLCompilerTool\" DisableLanguageExtensions=\"false\" />\n" 273 "\t\t\t<Tool\tName=\"VCLinkerTool\" OutputFile=\"$(OutDir)/scummvm.exe\"\n" 274 "\t\t\t\tAdditionalDependencies=\"" << libraries << "\"\n" 275 "\t\t\t/>\n" 276 "\t\t</Configuration>\n"; 277 } else { 278 std::string warnings = ""; 279 if (warningsIterator != _projectWarnings.end()) 280 for (StringList::const_iterator i = warningsIterator->second.begin(); i != warningsIterator->second.end(); ++i) 281 warnings += *i + ';'; 282 283 std::string toolConfig; 284 toolConfig = (!warnings.empty() ? "DisableSpecificWarnings=\"" + warnings + "\"" : ""); 285 toolConfig += (name == "tinsel" ? "DebugInformationFormat=\"3\" " : ""); 286 toolConfig += (name == "sword25" ? "DisableLanguageExtensions=\"false\" " : ""); 287 288 // Win32 289 project << "\t\t<Configuration Name=\"Debug|Win32\" ConfigurationType=\"4\" InheritedPropertySheets=\".\\ScummVM_Debug.vsprops\">\n" 290 "\t\t\t<Tool Name=\"VCCLCompilerTool\" "<< toolConfig << "/>\n" 291 "\t\t</Configuration>\n" 292 293 "\t\t<Configuration Name=\"Release|Win32\" ConfigurationType=\"4\" InheritedPropertySheets=\".\\ScummVM_Release.vsprops\">\n" 294 "\t\t\t<Tool Name=\"VCCLCompilerTool\" " << toolConfig << " />\n" 295 "\t\t</Configuration>\n"; 296 // x64 297 project << "\t\t<Configuration Name=\"Debug|x64\" ConfigurationType=\"4\" InheritedPropertySheets=\".\\ScummVM_Debug64.vsprops\">\n" 298 "\t\t\t<Tool Name=\"VCCLCompilerTool\" " << toolConfig << " />\n" 299 "\t\t</Configuration>\n" 300 "\t\t<Configuration Name=\"Release|x64\" ConfigurationType=\"4\" InheritedPropertySheets=\".\\ScummVM_Release64.vsprops\">\n" 301 "\t\t\t<Tool Name=\"VCCLCompilerTool\" " << toolConfig << " />\n" 302 "\t\t</Configuration>\n"; 303 } 304 305 project << "\t</Configurations>\n" 306 "\t<Files>\n"; 307 308 std::string modulePath; 309 if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) { 310 modulePath = moduleDir.substr(setup.srcDir.size()); 311 if (!modulePath.empty() && modulePath.at(0) == '/') 312 modulePath.erase(0, 1); 313 } 314 315 if (modulePath.size()) 316 addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix + '/' + modulePath); 317 else 318 addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix); 319 320 project << "\t</Files>\n" 321 "</VisualStudioProject>\n"; 322 } 323 324 void VisualStudioProvider::writeReferences(std::ofstream &output) { 325 output << "\tProjectSection(ProjectDependencies) = postProject\n"; 326 327 for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { 328 if (i->first == "scummvm") 329 continue; 330 331 output << "\t\t{" << i->second << "} = {" << i->second << "}\n"; 332 } 333 334 output << "\tEndProjectSection\n"; 335 } 336 337 void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix) { 338 std::string warnings; 339 for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) 340 warnings += *i + ';'; 341 342 std::string definesList; 343 for (StringList::const_iterator i = defines.begin(); i != defines.end(); ++i) { 344 if (i != defines.begin()) 345 definesList += ';'; 346 definesList += *i; 347 } 348 349 properties << "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n" 350 "<VisualStudioPropertySheet\n" 351 "\tProjectType=\"Visual C++\"\n" 352 "\tVersion=\"8.00\"\n" 353 "\tName=\"ScummVM_Global\"\n" 354 "\tOutputDirectory=\"$(ConfigurationName)" << bits << "\"\n" 355 "\tIntermediateDirectory=\"$(ConfigurationName)" << bits << "/$(ProjectName)\"\n" 356 "\t>\n" 357 "\t<Tool\n" 358 "\t\tName=\"VCCLCompilerTool\"\n" 359 "\t\tDisableLanguageExtensions=\"true\"\n" 360 "\t\tDisableSpecificWarnings=\"" << warnings << "\"\n" 361 "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;$(SCUMMVM_LIBS)\\include\"\n" 362 "\t\tPreprocessorDefinitions=\"" << definesList << "\"\n" 363 "\t\tExceptionHandling=\"0\"\n" 364 "\t\tRuntimeTypeInfo=\"false\"\n" 365 "\t\tWarningLevel=\"4\"\n" 366 "\t\tWarnAsError=\"false\"\n" 367 "\t\tCompileAs=\"0\"\n" 368 "\t\t/>\n" 369 "\t<Tool\n" 370 "\t\tName=\"VCLibrarianTool\"\n" 371 "\t\tIgnoreDefaultLibraryNames=\"\"\n" 372 "\t/>\n" 373 "\t<Tool\n" 374 "\t\tName=\"VCLinkerTool\"\n" 375 "\t\tIgnoreDefaultLibraryNames=\"\"\n" 376 "\t\tSubSystem=\"1\"\n" 377 "\t\tEntryPointSymbol=\"WinMainCRTStartup\"\n" 378 "\t/>\n" 379 "\t<Tool\n" 380 "\t\tName=\"VCResourceCompilerTool\"\n" 381 "\t\tPreprocessorDefinitions=\"HAS_INCLUDE_SET\"\n" 382 "\t\tAdditionalIncludeDirectories=\"$(SCUMMVM_LIBS)\\lib\\" << (bits == 32 ? "x86" : "x64") << "\"\n" 383 "\t/>\n" 384 "</VisualStudioPropertySheet>\n"; 385 386 properties.flush(); 387 } 388 389 void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32) { 390 const std::string outputType = (isRelease ? "Release" : "Debug"); 391 const std::string outputBitness = (isWin32 ? "32" : "64"); 392 393 std::ofstream properties((setup.outputDir + '/' + "ScummVM_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); 394 if (!properties) 395 error("Could not open \"" + setup.outputDir + '/' + "ScummVM_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); 396 397 properties << "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n" 398 "<VisualStudioPropertySheet\n" 399 "\tProjectType=\"Visual C++\"\n" 400 "\tVersion=\"8.00\"\n" 401 "\tName=\"ScummVM_" << outputType << outputBitness << "\"\n" 402 "\tInheritedPropertySheets=\".\\ScummVM_Global" << (isWin32 ? "" : "64") << ".vsprops\"\n" 403 "\t>\n" 404 "\t<Tool\n" 405 "\t\tName=\"VCCLCompilerTool\"\n"; 406 407 if (isRelease) { 408 properties << "\t\tEnableIntrinsicFunctions=\"true\"\n" 409 "\t\tWholeProgramOptimization=\"true\"\n" 410 "\t\tPreprocessorDefinitions=\"WIN32;RELEASE_BUILD\"\n" 411 "\t\tStringPooling=\"true\"\n" 412 "\t\tBufferSecurityCheck=\"false\"\n" 413 "\t\tDebugInformationFormat=\"0\"\n" 414 "\t/>\n" 415 "\t<Tool\n" 416 "\t\tName=\"VCLinkerTool\"\n" 417 "\t\tLinkIncremental=\"1\"\n" 418 "\t\tIgnoreDefaultLibraryNames=\"\"\n" 419 "\t\tSetChecksum=\"true\"\n"; 420 } else { 421 properties << "\t\tOptimization=\"0\"\n" 422 "\t\tPreprocessorDefinitions=\"WIN32\"\n" 423 "\t\tMinimalRebuild=\"true\"\n" 424 "\t\tBasicRuntimeChecks=\"3\"\n" 425 "\t\tRuntimeLibrary=\"1\"\n" 426 "\t\tEnableFunctionLevelLinking=\"true\"\n" 427 "\t\tWarnAsError=\"false\"\n" 428 "\t\tDebugInformationFormat=\"" << (isWin32 ? "4" : "3") << "\"\n" // For x64 format "4" (Edit and continue) is not supported, thus we default to "3" 429 "\t/>\n" 430 "\t<Tool\n" 431 "\t\tName=\"VCLinkerTool\"\n" 432 "\t\tLinkIncremental=\"2\"\n" 433 "\t\tGenerateDebugInformation=\"true\"\n" 434 "\t\tIgnoreDefaultLibraryNames=\"libcmt.lib\"\n"; 435 } 436 437 properties << "\t/>\n" 438 "</VisualStudioPropertySheet>\n"; 439 440 properties.flush(); 441 properties.close(); 442 } 443 444 void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, 445 const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) { 446 const std::string indentString = getIndent(indentation + 2); 447 448 if (indentation) 449 projectFile << getIndent(indentation + 1) << "<Filter\tName=\"" << dir.name << "\">\n"; 450 451 for (FileNode::NodeList::const_iterator i = dir.children.begin(); i != dir.children.end(); ++i) { 452 const FileNode *node = *i; 453 454 if (!node->children.empty()) { 455 writeFileListToProject(*node, projectFile, indentation + 1, duplicate, objPrefix + node->name + '_', filePrefix + node->name + '/'); 456 } else { 457 if (producesObjectFile(node->name)) { 458 std::string name, ext; 459 splitFilename(node->name, name, ext); 460 const bool isDuplicate = (std::find(duplicate.begin(), duplicate.end(), name + ".o") != duplicate.end()); 461 462 if (ext == "asm") { 463 std::string objFileName = "$(IntDir)\\"; 464 if (isDuplicate) 465 objFileName += objPrefix; 466 objFileName += "$(InputName).obj"; 467 468 const std::string toolLine = indentString + "\t\t<Tool Name=\"VCCustomBuildTool\" CommandLine=\"nasm.exe -f win32 -g -o "" + objFileName + "" "$(InputPath)"
\" Outputs=\"" + objFileName + "\" />\n"; 469 470 // NASM is not supported for x64, thus we do not need to add additional entries here :-). 471 projectFile << indentString << "<File RelativePath=\"" << convertPathToWin(filePrefix + node->name) << "\">\n" 472 << indentString << "\t<FileConfiguration Name=\"Debug|Win32\">\n" 473 << toolLine 474 << indentString << "\t</FileConfiguration>\n" 475 << indentString << "\t<FileConfiguration Name=\"Release|Win32\">\n" 476 << toolLine 477 << indentString << "\t</FileConfiguration>\n" 478 << indentString << "</File>\n"; 479 } else { 480 if (isDuplicate) { 481 const std::string toolLine = indentString + "\t\t<Tool Name=\"VCCLCompilerTool\" ObjectFile=\"$(IntDir)\\" + objPrefix + "$(InputName).obj\" XMLDocumentationFileName=\"$(IntDir)\\" + objPrefix + "$(InputName).xdc\" />\n"; 482 483 projectFile << indentString << "<File RelativePath=\"" << convertPathToWin(filePrefix + node->name) << "\">\n" 484 << indentString << "\t<FileConfiguration Name=\"Debug|Win32\">\n" 485 << toolLine 486 << indentString << "\t</FileConfiguration>\n" 487 << indentString << "\t<FileConfiguration Name=\"Release|Win32\">\n" 488 << toolLine 489 << indentString << "\t</FileConfiguration>\n" 490 << indentString << "\t<FileConfiguration Name=\"Debug|x64\">\n" 491 << toolLine 492 << indentString << "\t</FileConfiguration>\n" 493 << indentString << "\t<FileConfiguration Name=\"Release|x64\">\n" 494 << toolLine 495 << indentString << "\t</FileConfiguration>\n" 496 << indentString << "</File>\n"; 497 } else { 498 projectFile << indentString << "<File RelativePath=\"" << convertPathToWin(filePrefix + node->name) << "\" />\n"; 499 } 500 } 501 } else { 502 projectFile << indentString << "<File RelativePath=\"" << convertPathToWin(filePrefix + node->name) << "\" />\n"; 503 } 504 } 505 } 506 507 if (indentation) 508 projectFile << getIndent(indentation + 1) << "</Filter>\n"; 509 } 510 511 ////////////////////////////////////////////////////////////////////////// 512 // MSBuild Provider (Visual Studio 2010) 513 ////////////////////////////////////////////////////////////////////////// 514 515 MSBuildProvider::MSBuildProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version) 516 : MSVCProvider(global_warnings, project_warnings, version) { 517 518 } 519 520 const char *MSBuildProvider::getProjectExtension() { 521 return ".vcxproj"; 522 } 523 524 const char *MSBuildProvider::getPropertiesExtension() { 525 return ".props"; 526 } 527 528 int MSBuildProvider::getVisualStudioVersion() { 529 return 2010; 530 } 531 532 #define OUTPUT_CONFIGURATION_MSBUILD(config, platform) \ 533 (project << "\t\t<ProjectConfiguration Include=\"" << config << "|" << platform << "\">\n" \ 534 "\t\t\t<Configuration>" << config << "</Configuration>\n" \ 535 "\t\t\t<Platform>" << platform << "</Platform>\n" \ 536 "\t\t</ProjectConfiguration>\n") 537 538 #define OUTPUT_CONFIGURATION_TYPE_MSBUILD(config) \ 539 (project << "\t<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='" << config << "'\" Label=\"Configuration\">\n" \ 540 "\t\t<ConfigurationType>" << (name == "scummvm" ? "Application" : "StaticLibrary") << "</ConfigurationType>\n" \ 541 "\t</PropertyGroup>\n") 542 543 #define OUTPUT_PROPERTIES_MSBUILD(config, properties) \ 544 (project << "\t<ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='" << config << "'\" Label=\"PropertySheets\">\n" \ 545 "\t\t<Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n" \ 546 "\t\t<Import Project=\"" << properties << "\" />\n" \ 547 "\t</ImportGroup>\n") 548 549 void MSBuildProvider::createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, 550 const StringList &includeList, const StringList &excludeList) { 551 const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension(); 552 std::ofstream project(projectFile.c_str()); 553 if (!project) 554 error("Could not open \"" + projectFile + "\" for writing"); 555 556 project << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 557 "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" 558 "\t<ItemGroup Label=\"ProjectConfigurations\">\n"; 559 560 OUTPUT_CONFIGURATION_MSBUILD("Debug", "Win32"); 561 OUTPUT_CONFIGURATION_MSBUILD("Debug", "x64"); 562 OUTPUT_CONFIGURATION_MSBUILD("Release", "Win32"); 563 OUTPUT_CONFIGURATION_MSBUILD("Release", "x64"); 564 565 project << "\t</ItemGroup>\n"; 566 567 // Project name & Guid 568 project << "\t<PropertyGroup Label=\"Globals\">\n" 569 "\t\t<ProjectGuid>{" << uuid << "}</ProjectGuid>\n" 570 "\t\t<RootNamespace>" << name << "</RootNamespace>\n" 571 "\t\t<Keyword>Win32Proj</Keyword>\n" 572 "\t</PropertyGroup>\n"; 573 574 // Shared configuration 575 project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n"; 576 577 OUTPUT_CONFIGURATION_TYPE_MSBUILD("Release|Win32"); 578 OUTPUT_CONFIGURATION_TYPE_MSBUILD("Debug|Win32"); 579 OUTPUT_CONFIGURATION_TYPE_MSBUILD("Release|x64"); 580 OUTPUT_CONFIGURATION_TYPE_MSBUILD("Debug|x64"); 581 582 project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n" 583 "\t<ImportGroup Label=\"ExtensionSettings\">\n" 584 "\t</ImportGroup>\n"; 585 586 OUTPUT_PROPERTIES_MSBUILD("Release|Win32", "ScummVM_Release.props"); 587 OUTPUT_PROPERTIES_MSBUILD("Debug|Win32", "ScummVM_Debug.props"); 588 OUTPUT_PROPERTIES_MSBUILD("Release|x64", "ScummVM_Release64.props"); 589 OUTPUT_PROPERTIES_MSBUILD("Debug|x64", "ScummVM_Debug64.props"); 590 591 project << "\t<PropertyGroup Label=\"UserMacros\" />\n"; 592 593 // Project-specific settings 594 outputProjectSettings(project, name, setup, false, true); 595 outputProjectSettings(project, name, setup, true, true); 596 outputProjectSettings(project, name, setup, false, false); 597 outputProjectSettings(project, name, setup, true, false); 598 599 // Files 600 std::string modulePath; 601 if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) { 602 modulePath = moduleDir.substr(setup.srcDir.size()); 603 if (!modulePath.empty() && modulePath.at(0) == '/') 604 modulePath.erase(0, 1); 605 } 606 607 if (modulePath.size()) 608 addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix + '/' + modulePath); 609 else 610 addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix); 611 612 // Output references for scummvm project 613 if (name == "scummvm") 614 writeReferences(project); 615 616 project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n" 617 "\t<ImportGroup Label=\"ExtensionTargets\">\n" 618 "\t</ImportGroup>\n" 619 "</Project>\n"; 620 621 // Output filter file if necessary 622 createFiltersFile(setup, name); 623 } 624 625 #define OUTPUT_FILTER_MSBUILD(files, action) \ 626 if (!files.empty()) { \ 627 filters << "\t<ItemGroup>\n"; \ 628 for (std::list<FileEntry>::const_iterator entry = files.begin(); entry != files.end(); ++entry) { \ 629 if ((*entry).filter != "") { \ 630 filters << "\t\t<" action " Include=\"" << (*entry).path << "\">\n" \ 631 "\t\t\t<Filter>" << (*entry).filter << "</Filter>\n" \ 632 "\t\t</" action ">\n"; \ 633 } else { \ 634 filters << "\t\t<" action " Include=\"" << (*entry).path << "\" />\n"; \ 635 } \ 636 } \ 637 filters << "\t</ItemGroup>\n"; \ 638 } 639 640 void MSBuildProvider::createFiltersFile(const BuildSetup &setup, const std::string &name) { 641 // No filters => no need to create a filter file 642 if (_filters.empty()) 643 return; 644 645 // Sort all list alphabetically 646 _filters.sort(); 647 _compileFiles.sort(); 648 _includeFiles.sort(); 649 _otherFiles.sort(); 650 _resourceFiles.sort(); 651 _asmFiles.sort(); 652 653 const std::string filtersFile = setup.outputDir + '/' + name + getProjectExtension() + ".filters"; 654 std::ofstream filters(filtersFile.c_str()); 655 if (!filters) 656 error("Could not open \"" + filtersFile + "\" for writing"); 657 658 filters << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 659 "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"; 660 661 // Output the list of filters 662 filters << "\t<ItemGroup>\n"; 663 for (std::list<std::string>::iterator filter = _filters.begin(); filter != _filters.end(); ++filter) { 664 filters << "\t\t<Filter Include=\"" << *filter << "\">\n" 665 "\t\t\t<UniqueIdentifier>" << createUUID() << "</UniqueIdentifier>\n" 666 "\t\t</Filter>\n"; 667 } 668 filters << "\t</ItemGroup>\n"; 669 670 // Output files 671 OUTPUT_FILTER_MSBUILD(_compileFiles, "ClCompile") 672 OUTPUT_FILTER_MSBUILD(_includeFiles, "ClInclude") 673 OUTPUT_FILTER_MSBUILD(_otherFiles, "None") 674 OUTPUT_FILTER_MSBUILD(_resourceFiles, "ResourceCompile") 675 OUTPUT_FILTER_MSBUILD(_asmFiles, "CustomBuild") 676 677 filters << "</Project>"; 678 } 679 680 void MSBuildProvider::writeReferences(std::ofstream &output) { 681 output << "\t<ItemGroup>\n"; 682 683 for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { 684 if (i->first == "scummvm") 685 continue; 686 687 output << "\t<ProjectReference Include=\"" << i->first << ".vcxproj\">\n" 688 "\t\t<Project>{" << i->second << "}</Project>\n" 689 "\t</ProjectReference>\n"; 690 } 691 692 output << "\t</ItemGroup>\n"; 693 } 694 695 void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32) { 696 // Check for project-specific warnings: 697 std::map<std::string, StringList>::iterator warningsIterator = _projectWarnings.find(name); 698 699 // Nothing to add here, move along! 700 if (name != "scummvm" && name != "sword25" && name != "tinsel" && warningsIterator == _projectWarnings.end()) 701 return; 702 703 std::string warnings = ""; 704 if (warningsIterator != _projectWarnings.end()) 705 for (StringList::const_iterator i = warningsIterator->second.begin(); i != warningsIterator->second.end(); ++i) 706 warnings += *i + ';'; 707 708 project << "\t<ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='" << (isRelease ? "Release" : "Debug") << "|" << (isWin32 ? "Win32" : "x64") << "'\">\n" 709 "\t\t<ClCompile>\n"; 710 711 // Compile configuration 712 if (name == "scummvm" || name == "sword25") { 713 project << "\t\t\t<DisableLanguageExtensions>false</DisableLanguageExtensions>\n"; 714 } else { 715 if (name == "tinsel" && !isRelease) 716 project << "\t\t\t<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n"; 717 718 if (warningsIterator != _projectWarnings.end()) 719 project << "\t\t\t<DisableSpecificWarnings>" << warnings << ";%(DisableSpecificWarnings)</DisableSpecificWarnings>\n"; 720 } 721 722 project << "\t\t</ClCompile>\n"; 723 724 // Link configuration for scummvm project 725 if (name == "scummvm") { 726 std::string libraries; 727 728 for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) 729 libraries += *i + ".lib;"; 730 731 project << "\t\t<Link>\n" 732 "\t\t\t<OutputFile>$(OutDir)scummvm.exe</OutputFile>\n" 733 "\t\t\t<AdditionalDependencies>" << libraries << "%(AdditionalDependencies)</AdditionalDependencies>\n" 734 "\t\t</Link>\n"; 735 736 // Only generate revision number in debug builds 737 if (!isRelease) { 738 project << "\t\t<PreBuildEvent>\n" 739 "\t\t\t<Message>Generate internal_version.h</Message>\n" 740 "\t\t\t<Command>" << getRevisionToolCommandLine() << "</Command>\n" 741 "\t\t</PreBuildEvent>\n"; 742 } 743 744 // Copy data files to the build folder 745 project << "\t\t<PostBuildEvent>\n" 746 "\t\t\t<Message>Copy data files to the build folder</Message>\n" 747 "\t\t\t<Command>" << getCopyDataCommandLine(isWin32) << "</Command>\n" 748 "\t\t</PostBuildEvent>\n"; 749 } 750 751 project << "\t</ItemDefinitionGroup>\n"; 752 } 753 754 void MSBuildProvider::outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix) { 755 756 std::string warnings; 757 for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) 758 warnings += *i + ';'; 759 760 std::string definesList; 761 for (StringList::const_iterator i = defines.begin(); i != defines.end(); ++i) 762 definesList += *i + ';'; 763 764 properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 765 "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" 766 "\t<PropertyGroup>\n" 767 "\t\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\n" 768 "\t\t<_PropertySheetDisplayName>ScummVM_Global</_PropertySheetDisplayName>\n" 769 "\t\t<ExecutablePath>$(SCUMMVM_LIBS)\\bin;$(ExecutablePath)</ExecutablePath>\n" 770 "\t\t<LibraryPath>$(SCUMMVM_LIBS)\\lib\\" << (bits == 32 ? "x86" : "x64") << ";$(LibraryPath)</LibraryPath>\n" 771 "\t\t<IncludePath>$(SCUMMVM_LIBS)\\include;$(IncludePath)</IncludePath>\n" 772 "\t\t<OutDir>$(Configuration)" << bits << "\\</OutDir>\n" 773 "\t\t<IntDir>$(Configuration)" << bits << "/$(ProjectName)\\</IntDir>\n" 774 "\t</PropertyGroup>\n" 775 "\t<ItemDefinitionGroup>\n" 776 "\t\t<ClCompile>\n" 777 "\t\t\t<DisableLanguageExtensions>true</DisableLanguageExtensions>\n" 778 "\t\t\t<DisableSpecificWarnings>" << warnings << ";%(DisableSpecificWarnings)</DisableSpecificWarnings>\n" 779 "\t\t\t<AdditionalIncludeDirectories>$(SCUMMVM_LIBS)\\include;" << prefix << ";" << prefix << "\\engines;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" 780 "\t\t\t<PreprocessorDefinitions>" << definesList << "%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" 781 "\t\t\t<ExceptionHandling></ExceptionHandling>\n" 782 "\t\t\t<RuntimeTypeInfo>false</RuntimeTypeInfo>\n" 783 "\t\t\t<WarningLevel>Level4</WarningLevel>\n" 784 "\t\t\t<TreatWarningAsError>false</TreatWarningAsError>\n" 785 "\t\t\t<CompileAs>Default</CompileAs>\n" 786 "\t\t</ClCompile>\n" 787 "\t\t<Link>\n" 788 "\t\t\t<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n" 789 "\t\t\t<SubSystem>Console</SubSystem>\n" 790 "\t\t\t<EntryPointSymbol>WinMainCRTStartup</EntryPointSymbol>\n" 791 "\t\t</Link>\n" 792 "\t\t<ResourceCompile>\n" 793 "\t\t\t<PreprocessorDefinitions>HAS_INCLUDE_SET;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" 794 "\t\t\t<AdditionalIncludeDirectories>" << prefix << ";%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" 795 "\t\t</ResourceCompile>\n" 796 "\t</ItemDefinitionGroup>\n" 797 "</Project>\n"; 798 799 properties.flush(); 800 } 801 802 void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32) { 803 const std::string outputType = (isRelease ? "Release" : "Debug"); 804 const std::string outputBitness = (isWin32 ? "32" : "64"); 805 806 std::ofstream properties((setup.outputDir + '/' + "ScummVM_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); 807 if (!properties) 808 error("Could not open \"" + setup.outputDir + '/' + "ScummVM_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); 809 810 properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 811 "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" 812 "\t<ImportGroup Label=\"PropertySheets\">\n" 813 "\t\t<Import Project=\"ScummVM_Global" << (isWin32 ? "" : "64") << ".props\" />\n" 814 "\t</ImportGroup>\n" 815 "\t<PropertyGroup>\n" 816 "\t\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\n" 817 "\t\t<_PropertySheetDisplayName>ScummVM_" << outputType << outputBitness << "</_PropertySheetDisplayName>\n" 818 "\t\t<LinkIncremental>" << (isRelease ? "false" : "true") << "</LinkIncremental>\n" 819 "\t</PropertyGroup>\n" 820 "\t<ItemDefinitionGroup>\n" 821 "\t\t<ClCompile>\n"; 822 823 if (isRelease) { 824 properties << "\t\t\t<IntrinsicFunctions>true</IntrinsicFunctions>\n" 825 "\t\t\t<WholeProgramOptimization>true</WholeProgramOptimization>\n" 826 "\t\t\t<PreprocessorDefinitions>WIN32;RELEASE_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" 827 "\t\t\t<StringPooling>true</StringPooling>\n" 828 "\t\t\t<BufferSecurityCheck>false</BufferSecurityCheck>\n" 829 "\t\t\t<DebugInformationFormat></DebugInformationFormat>\n" 830 "\t\t</ClCompile>\n" 831 "\t\t<Link>\n" 832 "\t\t\t<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n" 833 "\t\t\t<SetChecksum>true</SetChecksum>\n"; 834 } else { 835 properties << "\t\t\t<Optimization>Disabled</Optimization>\n" 836 "\t\t\t<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" 837 "\t\t\t<MinimalRebuild>true</MinimalRebuild>\n" 838 "\t\t\t<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n" 839 "\t\t\t<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n" 840 "\t\t\t<FunctionLevelLinking>true</FunctionLevelLinking>\n" 841 "\t\t\t<TreatWarningAsError>false</TreatWarningAsError>\n" 842 "\t\t\t<DebugInformationFormat>" << (isWin32 ? "EditAndContinue" : "ProgramDatabase") << "</DebugInformationFormat>\n" // For x64 format Edit and continue is not supported, thus we default to Program Database 843 "\t\t</ClCompile>\n" 844 "\t\t<Link>\n" 845 "\t\t\t<GenerateDebugInformation>true</GenerateDebugInformation>\n" 846 "\t\t\t<IgnoreSpecificDefaultLibraries>libcmt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n"; 847 } 848 849 properties << "\t\t</Link>\n" 850 "\t</ItemDefinitionGroup>\n" 851 "</Project>\n"; 852 853 properties.flush(); 854 properties.close(); 855 } 856 857 #define OUTPUT_NASM_COMMAND_MSBUILD(config) \ 858 projectFile << "\t\t\t<Command Condition=\"'$(Configuration)|$(Platform)'=='" << config << "|Win32'\">nasm.exe -f win32 -g -o \"$(IntDir)" << (isDuplicate ? (*entry).prefix : "") << "%(Filename).obj\" \"%(FullPath)\"</Command>\n" \ 859 "\t\t\t<Outputs Condition=\"'$(Configuration)|$(Platform)'=='" << config << "|Win32'\">$(IntDir)" << (isDuplicate ? (*entry).prefix : "") << "%(Filename).obj;%(Outputs)</Outputs>\n"; 860 861 #define OUPUT_OBJECT_FILENAME_MSBUILD(config, platform, prefix) \ 862 projectFile << "\t\t<ObjectFileName Condition=\"'$(Configuration)|$(Platform)'=='" << config << "|" << platform << "'\">$(IntDir)" << prefix << "%(Filename).obj</ObjectFileName>\n" \ 863 "\t\t<XMLDocumentationFileName Condition=\"'$(Configuration)|$(Platform)'=='" << config << "|" << platform << "'\">$(IntDir)" << prefix << "%(Filename).xdc</XMLDocumentationFileName>\n"; 864 865 #define OUPUT_FILES_MSBUILD(files, action) \ 866 if (!files.empty()) { \ 867 projectFile << "\t<ItemGroup>\n"; \ 868 for (std::list<FileEntry>::const_iterator entry = files.begin(); entry != files.end(); ++entry) { \ 869 projectFile << "\t\t<" action " Include=\"" << (*entry).path << "\" />\n"; \ 870 } \ 871 projectFile << "\t</ItemGroup>\n"; \ 872 } 873 874 void MSBuildProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int, const StringList &duplicate, 875 const std::string &objPrefix, const std::string &filePrefix) { 876 // Reset lists 877 _filters.clear(); 878 _compileFiles.clear(); 879 _includeFiles.clear(); 880 _otherFiles.clear(); 881 _resourceFiles.clear(); 882 _asmFiles.clear(); 883 884 // Compute the list of files 885 _filters.push_back(""); // init filters 886 computeFileList(dir, duplicate, objPrefix, filePrefix); 887 _filters.pop_back(); // remove last empty filter 888 889 // Output compile files 890 if (!_compileFiles.empty()) { 891 projectFile << "\t<ItemGroup>\n"; 892 for (std::list<FileEntry>::const_iterator entry = _compileFiles.begin(); entry != _compileFiles.end(); ++entry) { 893 const bool isDuplicate = (std::find(duplicate.begin(), duplicate.end(), (*entry).name + ".o") != duplicate.end()); 894 895 // Deal with duplicated file names 896 if (isDuplicate) { 897 projectFile << "\t\t<ClCompile Include=\"" << (*entry).path << "\">\n"; 898 OUPUT_OBJECT_FILENAME_MSBUILD("Debug", "Win32", (*entry).prefix) 899 OUPUT_OBJECT_FILENAME_MSBUILD("Debug", "x64", (*entry).prefix) 900 OUPUT_OBJECT_FILENAME_MSBUILD("Release", "Win32", (*entry).prefix) 901 OUPUT_OBJECT_FILENAME_MSBUILD("Release", "x64", (*entry).prefix) 902 projectFile << "\t\t</ClCompile>\n"; 903 } else { 904 projectFile << "\t\t<ClCompile Include=\"" << (*entry).path << "\" />\n"; 905 } 906 } 907 projectFile << "\t</ItemGroup>\n"; 908 } 909 910 // Output include, other and resource files 911 OUPUT_FILES_MSBUILD(_includeFiles, "ClInclude") 912 OUPUT_FILES_MSBUILD(_otherFiles, "None") 913 OUPUT_FILES_MSBUILD(_resourceFiles, "ResourceCompile") 914 915 // Output asm files 916 if (!_asmFiles.empty()) { 917 projectFile << "\t<ItemGroup>\n"; 918 for (std::list<FileEntry>::const_iterator entry = _asmFiles.begin(); entry != _asmFiles.end(); ++entry) { 919 920 const bool isDuplicate = (std::find(duplicate.begin(), duplicate.end(), (*entry).name + ".o") != duplicate.end()); 921 922 projectFile << "\t\t<CustomBuild Include=\"" << (*entry).path << "\">\n" 923 "\t\t\t<FileType>Document</FileType>\n"; 924 925 OUTPUT_NASM_COMMAND_MSBUILD("Debug") 926 OUTPUT_NASM_COMMAND_MSBUILD("Release") 927 928 projectFile << "\t\t</CustomBuild>\n"; 929 } 930 projectFile << "\t</ItemGroup>\n"; 931 } 932 } 933 934 void MSBuildProvider::computeFileList(const FileNode &dir, const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) { 935 for (FileNode::NodeList::const_iterator i = dir.children.begin(); i != dir.children.end(); ++i) { 936 const FileNode *node = *i; 937 938 if (!node->children.empty()) { 939 // Update filter 940 std::string _currentFilter = _filters.back(); 941 _filters.back().append((_filters.back() == "" ? "" : "\\") + node->name); 942 943 computeFileList(*node, duplicate, objPrefix + node->name + '_', filePrefix + node->name + '/'); 944 945 // Reset filter 946 _filters.push_back(_currentFilter); 947 } else { 948 // Filter files by extension 949 std::string name, ext; 950 splitFilename(node->name, name, ext); 951 952 FileEntry entry; 953 entry.name = name; 954 entry.path = convertPathToWin(filePrefix + node->name); 955 entry.filter = _filters.back(); 956 entry.prefix = objPrefix; 957 958 if (ext == "cpp" || ext == "c") 959 _compileFiles.push_back(entry); 960 else if (ext == "h") 961 _includeFiles.push_back(entry); 962 else if (ext == "rc") 963 _resourceFiles.push_back(entry); 964 else if (ext == "asm") 965 _asmFiles.push_back(entry); 966 else 967 _otherFiles.push_back(entry); 968 } 969 } 970 } 971 972 } // End of CreateProjectTool namespace -
new file tools/create_project/msvc.h
diff -r e24b1c8ca942 tools/create_project/msvc.h
- + 1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL$ 22 * $Id$ 23 * 24 */ 25 26 #ifndef TOOLS_CREATE_PROJECT_MSVC_H 27 #define TOOLS_CREATE_PROJECT_MSVC_H 28 29 #include "create_project.h" 30 31 namespace CreateProjectTool { 32 33 class MSVCProvider : public ProjectProvider { 34 public: 35 MSVCProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version); 36 37 protected: 38 39 void createWorkspace(const BuildSetup &setup); 40 41 void createOtherBuildFiles(const BuildSetup &setup); 42 43 /** 44 * Create the global project properties. 45 * 46 * @param setup Description of the desired build setup. 47 */ 48 void createGlobalProp(const BuildSetup &setup); 49 50 /** 51 * Outputs a property file based on the input parameters. 52 * 53 * It can be easily used to create different global properties files 54 * for a 64 bit and a 32 bit version. It will also take care that the 55 * two platform configurations will output their files into different 56 * directories. 57 * 58 * @param properties File stream in which to write the property settings. 59 * @param bits Number of bits the platform supports. 60 * @param defines Defines the platform needs to have set. 61 * @param prefix File prefix, used to add additional include paths. 62 */ 63 virtual void outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix) = 0; 64 65 /** 66 * Generates the project properties for debug and release settings. 67 * 68 * @param setup Description of the desired build setup. 69 * @param isRelease Type of property file 70 * @param isWin32 Bitness of property file 71 */ 72 virtual void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32) = 0; 73 74 /** 75 * Get the file extension for property files 76 */ 77 virtual const char *getPropertiesExtension() = 0; 78 79 /** 80 * Get the Visual Studio version (used by the VS shell extension to launch the correct VS version) 81 */ 82 virtual int getVisualStudioVersion() = 0; 83 84 /** 85 * Get the command line for the revision tool (shared between all Visual Studio based providers) 86 */ 87 std::string getRevisionToolCommandLine() const; 88 89 /** 90 * Get the command line for copying data files to the build directory 91 * 92 * @param isWin32 Bitness of property file 93 */ 94 std::string getCopyDataCommandLine(bool isWin32) const; 95 }; 96 97 class VisualStudioProvider : public MSVCProvider { 98 public: 99 VisualStudioProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version); 100 101 protected: 102 void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, 103 const StringList &includeList, const StringList &excludeList); 104 105 void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, 106 const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); 107 108 void writeReferences(std::ofstream &output); 109 110 void outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix); 111 112 void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32); 113 114 const char *getProjectExtension(); 115 const char *getPropertiesExtension(); 116 int getVisualStudioVersion(); 117 }; 118 119 class MSBuildProvider : public MSVCProvider { 120 public: 121 MSBuildProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version); 122 123 protected: 124 void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, 125 const StringList &includeList, const StringList &excludeList); 126 127 void outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32); 128 129 void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, 130 const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); 131 132 void writeReferences(std::ofstream &output); 133 134 void outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix); 135 136 void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32); 137 138 const char *getProjectExtension(); 139 const char *getPropertiesExtension(); 140 int getVisualStudioVersion(); 141 142 private: 143 struct FileEntry { 144 std::string name; 145 std::string path; 146 std::string filter; 147 std::string prefix; 148 149 bool operator<(const FileEntry& rhs) const { 150 return path.compare(rhs.path) == -1; // Not exactly right for alphabetical order, but good enough 151 } 152 }; 153 typedef std::list<FileEntry> FileEntries; 154 155 std::list<std::string> _filters; // list of filters (we need to create a GUID for each filter id) 156 FileEntries _compileFiles; 157 FileEntries _includeFiles; 158 FileEntries _otherFiles; 159 FileEntries _asmFiles; 160 FileEntries _resourceFiles; 161 162 void computeFileList(const FileNode &dir, const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); 163 void createFiltersFile(const BuildSetup &setup, const std::string &name); 164 }; 165 166 } // End of CreateProjectTool namespace 167 168 #endif // TOOLS_CREATE_PROJECT_MSVC_H -
new file tools/create_project/msvc10/create_project.sln
diff -r e24b1c8ca942 tools/create_project/msvc10/create_project.sln
- + 1 2 Microsoft Visual Studio Solution File, Format Version 11.00 3 # Visual Studio 2010 4 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcxproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}" 5 EndProject 6 Global 7 GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 Debug|Win32 = Debug|Win32 9 Release|Win32 = Release|Win32 10 EndGlobalSection 11 GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32 13 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32 14 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32 15 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32 16 EndGlobalSection 17 GlobalSection(SolutionProperties) = preSolution 18 HideSolutionNode = FALSE 19 EndGlobalSection 20 EndGlobal -
new file tools/create_project/msvc10/create_project.vcxproj
diff -r e24b1c8ca942 tools/create_project/msvc10/create_project.vcxproj
- + 1 <?xml version="1.0" encoding="utf-8"?> 2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3 <ItemGroup Label="ProjectConfigurations"> 4 <ProjectConfiguration Include="Debug|Win32"> 5 <Configuration>Debug</Configuration> 6 <Platform>Win32</Platform> 7 </ProjectConfiguration> 8 <ProjectConfiguration Include="Release|Win32"> 9 <Configuration>Release</Configuration> 10 <Platform>Win32</Platform> 11 </ProjectConfiguration> 12 </ItemGroup> 13 <PropertyGroup Label="Globals"> 14 <ProjectGuid>{CF177559-077D-4A08-AABE-BE0FD35F6C63}</ProjectGuid> 15 <RootNamespace>create_project</RootNamespace> 16 </PropertyGroup> 17 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> 18 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> 19 <ConfigurationType>Application</ConfigurationType> 20 <CharacterSet>MultiByte</CharacterSet> 21 <WholeProgramOptimization>true</WholeProgramOptimization> 22 </PropertyGroup> 23 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> 24 <ConfigurationType>Application</ConfigurationType> 25 <CharacterSet>MultiByte</CharacterSet> 26 </PropertyGroup> 27 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 28 <ImportGroup Label="ExtensionSettings"> 29 </ImportGroup> 30 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> 31 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 32 </ImportGroup> 33 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> 34 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 35 </ImportGroup> 36 <PropertyGroup Label="UserMacros" /> 37 <PropertyGroup> 38 <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> 39 <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir> 40 <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> 41 <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir> 42 <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> 43 </PropertyGroup> 44 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 45 <ClCompile> 46 <Optimization>Disabled</Optimization> 47 <MinimalRebuild>true</MinimalRebuild> 48 <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> 49 <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> 50 <WarningLevel>Level4</WarningLevel> 51 <DebugInformationFormat>EditAndContinue</DebugInformationFormat> 52 <DisableLanguageExtensions>false</DisableLanguageExtensions> 53 <DisableSpecificWarnings>4003;4512;4127</DisableSpecificWarnings> 54 </ClCompile> 55 <Link> 56 <AdditionalDependencies>Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> 57 <GenerateDebugInformation>true</GenerateDebugInformation> 58 <TargetMachine>MachineX86</TargetMachine> 59 </Link> 60 <PostBuildEvent> 61 <Command>xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc10\ 62 xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc9\ 63 xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc8\ 64 xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\</Command> 65 </PostBuildEvent> 66 </ItemDefinitionGroup> 67 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 68 <ClCompile> 69 <Optimization>MaxSpeed</Optimization> 70 <IntrinsicFunctions>true</IntrinsicFunctions> 71 <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> 72 <FunctionLevelLinking>true</FunctionLevelLinking> 73 <WarningLevel>Level3</WarningLevel> 74 <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> 75 <DisableSpecificWarnings>4003;4512;4127</DisableSpecificWarnings> 76 </ClCompile> 77 <Link> 78 <AdditionalDependencies>Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> 79 <GenerateDebugInformation>true</GenerateDebugInformation> 80 <OptimizeReferences>true</OptimizeReferences> 81 <EnableCOMDATFolding>true</EnableCOMDATFolding> 82 <TargetMachine>MachineX86</TargetMachine> 83 </Link> 84 <PostBuildEvent> 85 <Command>xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc10\ 86 xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc9\ 87 xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc8\ 88 xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\</Command> 89 </PostBuildEvent> 90 </ItemDefinitionGroup> 91 <ItemGroup> 92 <ClCompile Include="..\codeblocks.cpp" /> 93 <ClCompile Include="..\create_project.cpp" /> 94 <ClCompile Include="..\msvc.cpp" /> 95 </ItemGroup> 96 <ItemGroup> 97 <ClInclude Include="..\codeblocks.h" /> 98 <ClInclude Include="..\create_project.h" /> 99 <ClInclude Include="..\msvc.h" /> 100 </ItemGroup> 101 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> 102 <ImportGroup Label="ExtensionTargets"> 103 </ImportGroup> 104 </Project> 105 No newline at end of file -
new file tools/create_project/msvc10/create_project.vcxproj.filters
diff -r e24b1c8ca942 tools/create_project/msvc10/create_project.vcxproj.filters
- + 1 <?xml version="1.0" encoding="utf-8"?> 2 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3 <ItemGroup> 4 <Filter Include="Header Files"> 5 <UniqueIdentifier>{2e3580c8-ec3a-4c81-8351-b668c668db2a}</UniqueIdentifier> 6 </Filter> 7 <Filter Include="Source Files"> 8 <UniqueIdentifier>{31aaf58c-d3cb-4ed6-8eca-163b4a9b31a6}</UniqueIdentifier> 9 </Filter> 10 </ItemGroup> 11 <ItemGroup> 12 <ClInclude Include="..\codeblocks.h"> 13 <Filter>Header Files</Filter> 14 </ClInclude> 15 <ClInclude Include="..\create_project.h"> 16 <Filter>Header Files</Filter> 17 </ClInclude> 18 <ClInclude Include="..\msvc.h"> 19 <Filter>Header Files</Filter> 20 </ClInclude> 21 </ItemGroup> 22 <ItemGroup> 23 <ClCompile Include="..\codeblocks.cpp"> 24 <Filter>Source Files</Filter> 25 </ClCompile> 26 <ClCompile Include="..\create_project.cpp"> 27 <Filter>Source Files</Filter> 28 </ClCompile> 29 <ClCompile Include="..\msvc.cpp"> 30 <Filter>Source Files</Filter> 31 </ClCompile> 32 </ItemGroup> 33 </Project> 34 No newline at end of file -
new file tools/create_project/msvc8/create_project.sln
diff -r e24b1c8ca942 tools/create_project/msvc8/create_project.sln
- + 1 2 Microsoft Visual Studio Solution File, Format Version 9.00 3 # Visual Studio 2005 4 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}" 5 EndProject 6 Global 7 GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 Debug|Win32 = Debug|Win32 9 Release|Win32 = Release|Win32 10 EndGlobalSection 11 GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32 13 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32 14 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32 15 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32 16 EndGlobalSection 17 GlobalSection(SolutionProperties) = preSolution 18 HideSolutionNode = FALSE 19 EndGlobalSection 20 EndGlobal -
new file tools/create_project/msvc8/create_project.vcproj
diff -r e24b1c8ca942 tools/create_project/msvc8/create_project.vcproj
- + 1 <?xml version="1.0" encoding="Windows-1252"?> 2 <VisualStudioProject 3 ProjectType="Visual C++" 4 Version="8.00" 5 Name="create_project" 6 ProjectGUID="{CF177559-077D-4A08-AABE-BE0FD35F6C63}" 7 RootNamespace="create_project" 8 > 9 <Platforms> 10 <Platform 11 Name="Win32" 12 /> 13 </Platforms> 14 <ToolFiles> 15 </ToolFiles> 16 <Configurations> 17 <Configuration 18 Name="Debug|Win32" 19 OutputDirectory="$(SolutionDir)$(ConfigurationName)" 20 IntermediateDirectory="$(ConfigurationName)" 21 ConfigurationType="1" 22 CharacterSet="2" 23 > 24 <Tool 25 Name="VCPreBuildEventTool" 26 /> 27 <Tool 28 Name="VCCustomBuildTool" 29 /> 30 <Tool 31 Name="VCXMLDataGeneratorTool" 32 /> 33 <Tool 34 Name="VCWebServiceProxyGeneratorTool" 35 /> 36 <Tool 37 Name="VCMIDLTool" 38 /> 39 <Tool 40 Name="VCCLCompilerTool" 41 Optimization="0" 42 MinimalRebuild="true" 43 BasicRuntimeChecks="3" 44 RuntimeLibrary="3" 45 WarningLevel="4" 46 DebugInformationFormat="4" 47 DisableSpecificWarnings="4003;4512;4127" 48 /> 49 <Tool 50 Name="VCManagedResourceCompilerTool" 51 /> 52 <Tool 53 Name="VCResourceCompilerTool" 54 /> 55 <Tool 56 Name="VCPreLinkEventTool" 57 /> 58 <Tool 59 Name="VCLinkerTool" 60 AdditionalDependencies="Rpcrt4.lib" 61 GenerateDebugInformation="true" 62 TargetMachine="1" 63 /> 64 <Tool 65 Name="VCALinkTool" 66 /> 67 <Tool 68 Name="VCManifestTool" 69 /> 70 <Tool 71 Name="VCXDCMakeTool" 72 /> 73 <Tool 74 Name="VCBscMakeTool" 75 /> 76 <Tool 77 Name="VCFxCopTool" 78 /> 79 <Tool 80 Name="VCAppVerifierTool" 81 /> 82 <Tool 83 Name="VCPostBuildEventTool" 84 /> 85 </Configuration> 86 <Configuration 87 Name="Release|Win32" 88 OutputDirectory="$(SolutionDir)$(ConfigurationName)" 89 IntermediateDirectory="$(ConfigurationName)" 90 ConfigurationType="1" 91 CharacterSet="2" 92 WholeProgramOptimization="1" 93 > 94 <Tool 95 Name="VCPreBuildEventTool" 96 /> 97 <Tool 98 Name="VCCustomBuildTool" 99 /> 100 <Tool 101 Name="VCXMLDataGeneratorTool" 102 /> 103 <Tool 104 Name="VCWebServiceProxyGeneratorTool" 105 /> 106 <Tool 107 Name="VCMIDLTool" 108 /> 109 <Tool 110 Name="VCCLCompilerTool" 111 Optimization="2" 112 EnableIntrinsicFunctions="true" 113 RuntimeLibrary="2" 114 EnableFunctionLevelLinking="true" 115 WarningLevel="3" 116 DebugInformationFormat="3" 117 DisableSpecificWarnings="4003;4512;4127" 118 /> 119 <Tool 120 Name="VCManagedResourceCompilerTool" 121 /> 122 <Tool 123 Name="VCResourceCompilerTool" 124 /> 125 <Tool 126 Name="VCPreLinkEventTool" 127 /> 128 <Tool 129 Name="VCLinkerTool" 130 AdditionalDependencies="Rpcrt4.lib" 131 GenerateDebugInformation="true" 132 OptimizeReferences="2" 133 EnableCOMDATFolding="2" 134 TargetMachine="1" 135 /> 136 <Tool 137 Name="VCALinkTool" 138 /> 139 <Tool 140 Name="VCManifestTool" 141 /> 142 <Tool 143 Name="VCXDCMakeTool" 144 /> 145 <Tool 146 Name="VCBscMakeTool" 147 /> 148 <Tool 149 Name="VCFxCopTool" 150 /> 151 <Tool 152 Name="VCAppVerifierTool" 153 /> 154 <Tool 155 Name="VCPostBuildEventTool" 156 /> 157 </Configuration> 158 </Configurations> 159 <References> 160 </References> 161 <Files> 162 <Filter 163 Name="Source Files" 164 Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" 165 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" 166 > 167 <File 168 RelativePath="..\create_project.cpp" 169 > 170 </File> 171 <File 172 RelativePath="..\codeblocks.cpp" 173 > 174 </File> 175 <File 176 RelativePath="..\msvc.cpp" 177 > 178 </File> 179 </Filter> 180 <Filter 181 Name="Header Files" 182 Filter="h;hpp;hxx;hm;inl;inc;xsd" 183 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" 184 > 185 <File 186 RelativePath="..\create_project.h" 187 > 188 </File> 189 <File 190 RelativePath="..\codeblocks.h" 191 > 192 </File> 193 <File 194 RelativePath="..\msvc.h" 195 > 196 </File> 197 </Filter> 198 </Files> 199 <Globals> 200 </Globals> 201 </VisualStudioProject> -
new file tools/create_project/msvc9/create_project.sln
diff -r e24b1c8ca942 tools/create_project/msvc9/create_project.sln
- + 1 2 Microsoft Visual Studio Solution File, Format Version 10.00 3 # Visual Studio 2008 4 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}" 5 EndProject 6 Global 7 GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 Debug|Win32 = Debug|Win32 9 Release|Win32 = Release|Win32 10 EndGlobalSection 11 GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32 13 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32 14 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32 15 {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32 16 EndGlobalSection 17 GlobalSection(SolutionProperties) = preSolution 18 HideSolutionNode = FALSE 19 EndGlobalSection 20 EndGlobal -
new file tools/create_project/msvc9/create_project.vcproj
diff -r e24b1c8ca942 tools/create_project/msvc9/create_project.vcproj
- + 1 <?xml version="1.0" encoding="Windows-1252"?> 2 <VisualStudioProject 3 ProjectType="Visual C++" 4 Version="9.00" 5 Name="create_project" 6 ProjectGUID="{CF177559-077D-4A08-AABE-BE0FD35F6C63}" 7 RootNamespace="create_project" 8 TargetFrameworkVersion="196613" 9 > 10 <Platforms> 11 <Platform 12 Name="Win32" 13 /> 14 </Platforms> 15 <ToolFiles> 16 </ToolFiles> 17 <Configurations> 18 <Configuration7 19 Name="Debug|Win32" 20 OutputDirectory="$(SolutionDir)$(ConfigurationName)" 21 IntermediateDirectory="$(ConfigurationName)" 22 ConfigurationType="1" 23 CharacterSet="2" 24 > 25 <Tool 26 Name="VCPreBuildEventTool" 27 /> 28 <Tool 29 Name="VCCustomBuildTool" 30 /> 31 <Tool 32 Name="VCXMLDataGeneratorTool" 33 /> 34 <Tool 35 Name="VCWebServiceProxyGeneratorTool" 36 /> 37 <Tool 38 Name="VCMIDLTool" 39 /> 40 <Tool 41 Name="VCCLCompilerTool" 42 Optimization="0" 43 MinimalRebuild="true" 44 BasicRuntimeChecks="3" 45 RuntimeLibrary="3" 46 WarningLevel="4" 47 DebugInformationFormat="4" 48 DisableSpecificWarnings="4003;4512;4127" 49 /> 50 <Tool 51 Name="VCManagedResourceCompilerTool" 52 /> 53 <Tool 54 Name="VCResourceCompilerTool" 55 /> 56 <Tool 57 Name="VCPreLinkEventTool" 58 /> 59 <Tool 60 Name="VCLinkerTool" 61 AdditionalDependencies="Rpcrt4.lib" 62 GenerateDebugInformation="true" 63 TargetMachine="1" 64 /> 65 <Tool 66 Name="VCALinkTool" 67 /> 68 <Tool 69 Name="VCManifestTool" 70 /> 71 <Tool 72 Name="VCXDCMakeTool" 73 /> 74 <Tool 75 Name="VCBscMakeTool" 76 /> 77 <Tool 78 Name="VCFxCopTool" 79 /> 80 <Tool 81 Name="VCAppVerifierTool" 82 /> 83 <Tool 84 Name="VCPostBuildEventTool" 85 /> 86 </Configuration> 87 <Configuration 88 Name="Release|Win32" 89 OutputDirectory="$(SolutionDir)$(ConfigurationName)" 90 IntermediateDirectory="$(ConfigurationName)" 91 ConfigurationType="1" 92 CharacterSet="2" 93 WholeProgramOptimization="1" 94 > 95 <Tool 96 Name="VCPreBuildEventTool" 97 /> 98 <Tool 99 Name="VCCustomBuildTool" 100 /> 101 <Tool 102 Name="VCXMLDataGeneratorTool" 103 /> 104 <Tool 105 Name="VCWebServiceProxyGeneratorTool" 106 /> 107 <Tool 108 Name="VCMIDLTool" 109 /> 110 <Tool 111 Name="VCCLCompilerTool" 112 Optimization="2" 113 EnableIntrinsicFunctions="true" 114 RuntimeLibrary="2" 115 EnableFunctionLevelLinking="true" 116 WarningLevel="3" 117 DebugInformationFormat="3" 118 DisableSpecificWarnings="4003;4512;4127" 119 /> 120 <Tool 121 Name="VCManagedResourceCompilerTool" 122 /> 123 <Tool 124 Name="VCResourceCompilerTool" 125 /> 126 <Tool 127 Name="VCPreLinkEventTool" 128 /> 129 <Tool 130 Name="VCLinkerTool" 131 AdditionalDependencies="Rpcrt4.lib" 132 GenerateDebugInformation="true" 133 OptimizeReferences="2" 134 EnableCOMDATFolding="2" 135 TargetMachine="1" 136 /> 137 <Tool 138 Name="VCALinkTool" 139 /> 140 <Tool 141 Name="VCManifestTool" 142 /> 143 <Tool 144 Name="VCXDCMakeTool" 145 /> 146 <Tool 147 Name="VCBscMakeTool" 148 /> 149 <Tool 150 Name="VCFxCopTool" 151 /> 152 <Tool 153 Name="VCAppVerifierTool" 154 /> 155 <Tool 156 Name="VCPostBuildEventTool" 157 /> 158 </Configuration> 159 </Configurations> 160 <References> 161 </References> 162 <Files> 163 <Filter 164 Name="Source Files" 165 Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" 166 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" 167 > 168 <File 169 RelativePath="..\create_project.cpp" 170 > 171 </File> 172 <File 173 RelativePath="..\codeblocks.cpp" 174 > 175 </File> 176 <File 177 RelativePath="..\msvc.cpp" 178 > 179 </File> 180 </Filter> 181 <Filter 182 Name="Header Files" 183 Filter="h;hpp;hxx;hm;inl;inc;xsd" 184 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" 185 > 186 <File 187 RelativePath="..\create_project.h" 188 > 189 </File> 190 <File 191 RelativePath="..\codeblocks.h" 192 > 193 </File> 194 <File 195 RelativePath="..\msvc.h" 196 > 197 </File> 198 </Filter> 199 </Files> 200 <Globals> 201 </Globals> 202 </VisualStudioProject>