diff options
Diffstat (limited to 'devtools/create_project')
| -rw-r--r-- | devtools/create_project/codeblocks.cpp | 6 | ||||
| -rw-r--r-- | devtools/create_project/config.h | 1 | ||||
| -rw-r--r-- | devtools/create_project/create_project.cpp | 474 | ||||
| -rw-r--r-- | devtools/create_project/create_project.h | 72 | ||||
| -rw-r--r-- | devtools/create_project/msbuild.cpp | 124 | ||||
| -rw-r--r-- | devtools/create_project/msbuild.h | 4 | ||||
| -rw-r--r-- | devtools/create_project/msvc.cpp | 30 | ||||
| -rw-r--r-- | devtools/create_project/msvc.h | 9 | ||||
| -rw-r--r-- | devtools/create_project/msvc12/create_project.sln | 20 | ||||
| -rw-r--r-- | devtools/create_project/msvc12/create_project.vcxproj | 132 | ||||
| -rw-r--r-- | devtools/create_project/msvc12/create_project.vcxproj.filters | 71 | ||||
| -rw-r--r-- | devtools/create_project/visualstudio.cpp | 67 | ||||
| -rw-r--r-- | devtools/create_project/visualstudio.h | 2 | ||||
| -rw-r--r-- | devtools/create_project/xcode.cpp | 31 |
14 files changed, 799 insertions, 244 deletions
diff --git a/devtools/create_project/codeblocks.cpp b/devtools/create_project/codeblocks.cpp index 3458ca5a19..442a2b0025 100644 --- a/devtools/create_project/codeblocks.cpp +++ b/devtools/create_project/codeblocks.cpp @@ -64,6 +64,11 @@ std::string processLibraryName(std::string name) { if (pos != std::string::npos) return name.replace(pos, 7, ""); + // Remove "-static" in lib name + pos = name.find("-static"); + if (pos != std::string::npos) + return name.replace(pos, 7, ""); + // Replace "zlib" by "libz" if (name == "zlib") return "libz"; @@ -115,6 +120,7 @@ void CodeBlocksProvider::createProjectFile(const std::string &name, const std::s "\t\t\t\t\t<Add directory=\"..\\..\\engines\" />\n" "\t\t\t\t\t<Add directory=\"..\\..\\common\" />\n" "\t\t\t\t\t<Add directory=\"..\\..\" />\n" + "\t\t\t\t\t<Add directory=\".\\\" />\n" "\t\t\t\t</Compiler>\n"; ////////////////////////////////////////////////////////////////////////// diff --git a/devtools/create_project/config.h b/devtools/create_project/config.h index 1a66edff93..9d4b101360 100644 --- a/devtools/create_project/config.h +++ b/devtools/create_project/config.h @@ -27,6 +27,7 @@ #define PROJECT_NAME "scummvm" // Used for folders, icons, resources and project/solution name #define LIBS_DEFINE "SCUMMVM_LIBS" // Name of the include environment variable #define REVISION_DEFINE "SCUMMVM_INTERNAL_REVISION" +#define FIRST_ENGINE "scumm" // Name of the engine which should be sorted as first element #define ENABLE_LANGUAGE_EXTENSIONS "" // Comma separated list of projects that need language extensions #define DISABLE_EDIT_AND_CONTINUE "tinsel,tony,scummvm" // Comma separated list of projects that need Edit&Continue to be disabled for co-routine support (the main project is automatically added) diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp index a8e09ff5eb..9d7ed532cb 100644 --- a/devtools/create_project/create_project.cpp +++ b/devtools/create_project/create_project.cpp @@ -39,10 +39,11 @@ #include <fstream> #include <iostream> - +#include <sstream> #include <stack> #include <algorithm> #include <iomanip> +#include <iterator> #include <cstring> #include <cstdlib> @@ -59,6 +60,7 @@ #include <sys/param.h> #include <sys/stat.h> #include <dirent.h> +#include <errno.h> #endif namespace { @@ -81,22 +83,6 @@ std::string unifyPath(const std::string &path); * @param exe Name of the executable. */ void displayHelp(const char *exe); - -/** - * Structure for describing an FSNode. This is a very minimalistic - * description, which includes everything we need. - * It only contains the name of the node and whether it is a directory - * or not. - */ -struct FSNode { - FSNode() : name(), isDirectory(false) {} - FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {} - - std::string name; ///< Name of the file system node - bool isDirectory; ///< Whether it is a directory or not -}; - -typedef std::list<FSNode> FileList; } // End of anonymous namespace enum ProjectType { @@ -109,7 +95,7 @@ enum ProjectType { int main(int argc, char *argv[]) { #ifndef USE_WIN32_API // Initialize random number generator for UUID creation - std::srand((uint)std::time(0)); + std::srand((unsigned int)std::time(0)); #endif if (argc < 2) { @@ -128,7 +114,7 @@ int main(int argc, char *argv[]) { setup.filePrefix = setup.srcDir; setup.outputDir = '.'; - setup.engines = parseConfigure(setup.srcDir); + setup.engines = parseEngines(setup.srcDir); if (setup.engines.empty()) { std::cout << "WARNING: No engines found in configure file or configure file missing in \"" << setup.srcDir << "\"\n"; @@ -189,7 +175,7 @@ int main(int argc, char *argv[]) { msvcVersion = atoi(argv[++i]); - if (msvcVersion != 8 && msvcVersion != 9 && msvcVersion != 10 && msvcVersion != 11) { + if (msvcVersion != 8 && msvcVersion != 9 && msvcVersion != 10 && msvcVersion != 11 && msvcVersion != 12) { std::cerr << "ERROR: Unsupported version: \"" << msvcVersion << "\" passed to \"--msvc-version\"!\n"; return -1; } @@ -264,7 +250,7 @@ int main(int argc, char *argv[]) { setup.filePrefix.erase(setup.filePrefix.size() - 1); } else if (!std::strcmp(argv[i], "--output-dir")) { if (i + 1 >= argc) { - std::cerr << "ERROR: Missing \"path\" parameter for \"--output-dirx\"!\n"; + std::cerr << "ERROR: Missing \"path\" parameter for \"--output-dir\"!\n"; return -1; } @@ -279,12 +265,23 @@ int main(int argc, char *argv[]) { setup.createInstaller = true; } else if (!std::strcmp(argv[i], "--tools")) { setup.devTools = true; + } else if (!std::strcmp(argv[i], "--tests")) { + setup.tests = true; } else { std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n"; return -1; } } + // When building tests, disable some features + if (setup.tests) { + setFeatureBuildState("mt32emu", setup.features, false); + setFeatureBuildState("eventrecorder", setup.features, false); + + for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j) + j->enable = false; + } + // Print status cout << "Enabled engines:\n\n"; for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) { @@ -310,6 +307,23 @@ int main(int argc, char *argv[]) { cout << " " << i->description << '\n'; } + // Check if the keymapper and the event recorder are enabled simultaneously + bool keymapperEnabled = false; + for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) { + if (i->enable && !strcmp(i->name, "keymapper")) + keymapperEnabled = true; + if (i->enable && !strcmp(i->name, "eventrecorder") && keymapperEnabled) { + std::cerr << "ERROR: The keymapper and the event recorder cannot be enabled simultaneously currently, please disable one of the two\n"; + return -1; + } + } + + // Check if tools and tests are enabled simultaneously + if (setup.devTools && setup.tests) { + std::cerr << "ERROR: The tools and tests projects cannot be created simultaneously\n"; + return -1; + } + // Setup defines and libraries setup.defines = getEngineDefines(setup.engines); setup.libraries = getFeatureLibraries(setup.features); @@ -347,8 +361,8 @@ int main(int argc, char *argv[]) { return -1; case kProjectCodeBlocks: - if (setup.devTools) { - std::cerr << "ERROR: Building tools is not supported for the CodeBlocks project type!\n"; + if (setup.devTools || setup.tests) { + std::cerr << "ERROR: Building tools or tests is not supported for the CodeBlocks project type!\n"; return -1; } @@ -520,8 +534,8 @@ int main(int argc, char *argv[]) { break; case kProjectXcode: - if (setup.devTools) { - std::cerr << "ERROR: Building tools is not supported for the XCode project type!\n"; + if (setup.devTools || setup.tests) { + std::cerr << "ERROR: Building tools or tests is not supported for the XCode project type!\n"; return -1; } @@ -562,6 +576,11 @@ int main(int argc, char *argv[]) { setup.projectDescription += "Tools"; } + if (setup.tests) { + setup.projectName += "-tests"; + setup.projectDescription += "Tests"; + } + provider->createProject(setup); delete provider; @@ -588,7 +607,7 @@ void displayHelp(const char *exe) { " Additionally there are the following switches for changing various settings:\n" "\n" "Project specific settings:\n" - " --codeblock build Code::Blocks project files\n" + " --codeblocks build Code::Blocks project files\n" " --msvc build Visual Studio project files\n" " --xcode build XCode project files\n" " --file-prefix prefix allow overwriting of relative file prefix in the\n" @@ -609,9 +628,12 @@ void displayHelp(const char *exe) { " (default: false)\n" " --installer Create NSIS installer after the build (implies --build-events)\n" " (default: false)\n" - " --tools Create project files for the devtools\n" - " (ignores --build-events and --installer, as well as engine settings)\n" - " (default: false)\n" + " --tools Create project files for the devtools\n" + " (ignores --build-events and --installer, as well as engine settings)\n" + " (default: false)\n" + " --tests Create project files for the tests\n" + " (ignores --build-events and --installer, as well as engine settings)\n" + " (default: false)\n" "\n" "Engines settings:\n" " --list-engines list all available engines and their default state\n" @@ -636,47 +658,70 @@ void displayHelp(const char *exe) { } /** - * Try to parse a given line and create an engine definition - * out of the result. + * Parse the configure.engine file of a given engine directory and return a + * list of all defined engines. * - * This may take *any* input line, when the line is not used - * to define an engine the result of the function will be "false". + * @param engineDir The directory of the engine. + * @return The list of all defined engines. + */ +EngineDescList parseEngineConfigure(const std::string &engineDir); + +/** + * Compares two FSNode entries in a strict-weak fashion based on the name. * - * Note that the contents of "engine" are undefined, when this - * function returns "false". + * @param left The first operand. + * @param right The second operand. + * @return "true" when the name of the left operand is strictly smaller than + * the name of the second operand. "false" otherwise. + */ +bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right); + +#ifdef FIRST_ENGINE +/** + * Compares two FSNode entries in a strict-weak fashion based on engine name + * order. * - * @param line Text input line. - * @param engine Reference to an object, where the engine information - * is to be stored in. - * @return "true", when parsing succeeded, "false" otherwise. + * @param left The first operand. + * @param right The second operand. + * @return "true" when the name of the left operand is strictly smaller than + * the name of the second operand. "false" otherwise. */ -bool parseEngine(const std::string &line, EngineDesc &engine); +bool compareEngineNames(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right); +#endif } // End of anonymous namespace -EngineDescList parseConfigure(const std::string &srcDir) { - std::string configureFile = srcDir + "/engines/configure.engines"; +EngineDescList parseEngines(const std::string &srcDir) { + using CreateProjectTool::FileList; + using CreateProjectTool::listDirectory; - std::ifstream configure(configureFile.c_str()); - if (!configure) - return EngineDescList(); + EngineDescList engineList; - std::string line; - EngineDescList engines; + FileList engineFiles = listDirectory(srcDir + "/engines/"); - for (;;) { - std::getline(configure, line); - if (configure.eof()) - break; +#ifdef FIRST_ENGINE + // In case we want to sort an engine to the front of the list we will + // use some manual sorting predicate which assures that. + engineFiles.sort(&compareEngineNames); +#else + // Otherwise, we simply sort the file list alphabetically this allows + // for a nicer order in --list-engines output, for example. + engineFiles.sort(&compareFSNode); +#endif - if (configure.fail()) - error("Failed while reading from " + configureFile); + for (FileList::const_iterator i = engineFiles.begin(), end = engineFiles.end(); i != end; ++i) { + // Each engine requires its own sub directory thus we will skip all + // non directory file nodes here. + if (!i->isDirectory) { + continue; + } - EngineDesc desc; - if (parseEngine(line, desc)) - engines.push_back(desc); + // Retrieve all engines defined in this sub directory and add them to + // the list of all engines. + EngineDescList list = parseEngineConfigure(srcDir + "/engines/" + i->name); + engineList.splice(engineList.end(), list); } - return engines; + return engineList; } bool isSubEngine(const std::string &name, const EngineDescList &engines) { @@ -741,6 +786,21 @@ StringList getEngineDefines(const EngineDescList &engines) { } namespace { +/** + * Try to parse a given line and create an engine definition + * out of the result. + * + * This may take *any* input line, when the line is not used + * to define an engine the result of the function will be "false". + * + * Note that the contents of "engine" are undefined, when this + * function returns "false". + * + * @param line Text input line. + * @param engine Reference to an object, where the engine information + * is to be stored in. + * @return "true", when parsing succeeded, "false" otherwise. + */ bool parseEngine(const std::string &line, EngineDesc &engine) { // Format: // add_engine engine_name "Readable Description" enable_default ["SubEngineList"] @@ -763,6 +823,48 @@ bool parseEngine(const std::string &line, EngineDesc &engine) { return true; } + +EngineDescList parseEngineConfigure(const std::string &engineDir) { + std::string configureFile = engineDir + "/configure.engine"; + + std::ifstream configure(configureFile.c_str()); + if (!configure) + return EngineDescList(); + + std::string line; + EngineDescList engines; + + for (;;) { + std::getline(configure, line); + if (configure.eof()) + break; + + if (configure.fail()) + error("Failed while reading from " + configureFile); + + EngineDesc desc; + if (parseEngine(line, desc)) + engines.push_back(desc); + } + + return engines; +} + +bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right) { + return left.name < right.name; +} + +#ifdef FIRST_ENGINE +bool compareEngineNames(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right) { + if (left.name == FIRST_ENGINE) { + return right.name != FIRST_ENGINE; + } else if (right.name == FIRST_ENGINE) { + return false; + } else { + return compareFSNode(left, right); + } +} +#endif } // End of anonymous namespace TokenList tokenize(const std::string &input, char separator) { @@ -805,23 +907,27 @@ const Feature s_features[] = { { "vorbis", "USE_VORBIS", "libvorbisfile_static libvorbis_static libogg_static", true, "Ogg Vorbis support" }, { "flac", "USE_FLAC", "libFLAC_static", true, "FLAC support" }, { "png", "USE_PNG", "libpng", true, "libpng support" }, + { "faad", "USE_FAAD", "libfaad", false, "AAC support" }, + { "mpeg2", "USE_MPEG2", "libmpeg2", false, "MPEG-2 support" }, { "theora", "USE_THEORADEC", "libtheora_static", true, "Theora decoding support" }, {"freetype", "USE_FREETYPE2", "freetype", true, "FreeType support" }, + { "jpeg", "USE_JPEG", "jpeg-static", true, "libjpeg support" }, // Feature flags - { "bink", "USE_BINK", "", true, "Bink video support" }, - { "scalers", "USE_SCALERS", "", true, "Scalers" }, - { "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" }, - { "16bit", "USE_RGB_COLOR", "", true, "16bit color support" }, - { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, - { "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling. - { "opengl", "USE_OPENGL", "opengl32", true, "OpenGL support" }, - { "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" }, - { "translation", "USE_TRANSLATION", "", true, "Translation support" }, - { "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"}, - { "keymapper","ENABLE_KEYMAPPER", "", false, "Keymapper support"}, - { "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there - // is just no current way of properly detecting this... + { "bink", "USE_BINK", "", true, "Bink video support" }, + { "scalers", "USE_SCALERS", "", true, "Scalers" }, + { "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" }, + { "16bit", "USE_RGB_COLOR", "", true, "16bit color support" }, + { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, + { "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling. + { "opengl", "USE_OPENGL", "opengl32", true, "OpenGL support" }, + { "taskbar", "USE_TASKBAR", "", true, "Taskbar integration support" }, + { "translation", "USE_TRANSLATION", "", true, "Translation support" }, + { "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"}, + { "keymapper", "ENABLE_KEYMAPPER", "", false, "Keymapper support"}, + { "eventrecorder", "ENABLE_EVENTRECORDER", "", false, "Event recorder support"}, + { "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there + // is just no current way of properly detecting this... }; const Tool s_tools[] = { @@ -829,7 +935,9 @@ const Tool s_tools[] = { { "create_hugo", true}, { "create_kyradat", true}, { "create_lure", true}, + { "create_neverhood", true}, { "create_teenagent", true}, + { "create_tony", true}, { "create_toon", true}, { "create_translations", true}, { "qtable", true} @@ -925,6 +1033,10 @@ bool producesObjectFile(const std::string &fileName) { return false; } +std::string toString(int num) { + return static_cast<std::ostringstream*>(&(std::ostringstream() << num))->str(); +} + /** * Checks whether the give file in the specified directory is present in the given * file list. @@ -1002,13 +1114,6 @@ bool compareNodes(const FileNode *l, const FileNode *r) { } } -/** - * Returns a list of all files and directories in the specified - * path. - * - * @param dir Directory which should be listed. - * @return List of all children. - */ FileList listDirectory(const std::string &dir) { FileList result; #ifdef USE_WIN32_API @@ -1049,6 +1154,32 @@ FileList listDirectory(const std::string &dir) { return result; } +void createDirectory(const std::string &dir) { +#if defined(_WIN32) || defined(WIN32) + if (!CreateDirectory(dir.c_str(), NULL)) { + if (GetLastError() != ERROR_ALREADY_EXISTS) { + error("Could not create folder \"" + dir + "\""); + } + } +#else + if (mkdir(dir.c_str(), 0777) == -1) { + if (errno == EEXIST) { + // Try to open as a folder (might be a file / symbolic link) + DIR *dirp = opendir(dir.c_str()); + if (dirp == NULL) { + error("Could not create folder \"" + dir + "\""); + } else { + // The folder exists, just close the stream and return + closedir(dirp); + } + } else { + error("Could not create folder \"" + dir + "\""); + } + } +#endif + +} + /** * Scans the specified directory against files, which should be included * in the project files. It will not include files present in the exclude list. @@ -1114,69 +1245,66 @@ ProjectProvider::ProjectProvider(StringList &global_warnings, std::map<std::stri : _version(version), _globalWarnings(global_warnings), _projectWarnings(project_warnings) { } -void ProjectProvider::createProject(const BuildSetup &setup) { +void ProjectProvider::createProject(BuildSetup &setup) { + std::string targetFolder; + if (setup.devTools) { _uuidMap = createToolsUUIDMap(); + targetFolder = "/devtools/"; + } else if (!setup.tests) { + _uuidMap = createUUIDMap(setup); + targetFolder = "/engines/"; + } - // We also need to add the UUID of the main project file. - const std::string svmUUID = _uuidMap[setup.projectName] = createUUID(); - - createWorkspace(setup); - - StringList in, ex; - - // Create tools project files - for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { - if (i->first == setup.projectName) - continue; - - in.clear(); ex.clear(); - const std::string moduleDir = setup.srcDir + "/devtools/" + i->first; - - createModuleList(moduleDir, setup.defines, in, ex); - createProjectFile(i->first, i->second, setup, moduleDir, in, ex); - } + // We also need to add the UUID of the main project file. + const std::string svmUUID = _uuidMap[setup.projectName] = createUUID(); - // Create other misc. build files - createOtherBuildFiles(setup); + createWorkspace(setup); - } else { - _uuidMap = createUUIDMap(setup); + StringList in, ex; - // We also need to add the UUID of the main project file. - const std::string svmUUID = _uuidMap[setup.projectName] = createUUID(); - - // Create Solution/Workspace file - createWorkspace(setup); + // Create project files + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + if (i->first == setup.projectName) + continue; - StringList in, ex; + in.clear(); ex.clear(); + const std::string moduleDir = setup.srcDir + targetFolder + i->first; - // Create engine project files - for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { - if (i->first == setup.projectName) - continue; + createModuleList(moduleDir, setup.defines, setup.testDirs, in, ex); + createProjectFile(i->first, i->second, setup, moduleDir, in, ex); + } - in.clear(); ex.clear(); - const std::string moduleDir = setup.srcDir + "/engines/" + i->first; + if (setup.tests) { + // Create the main project file. + in.clear(); ex.clear(); - createModuleList(moduleDir, setup.defines, in, ex); - createProjectFile(i->first, i->second, setup, moduleDir, in, ex); - } + createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/base", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/common", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/engines", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/graphics", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/gui", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/audio", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/test", setup.defines, setup.testDirs, in, ex); + createProjectFile(setup.projectName, svmUUID, setup, setup.srcDir, in, ex); + } else if (!setup.devTools) { // Last but not least create the main project file. in.clear(); ex.clear(); // File list for the Project file - createModuleList(setup.srcDir + "/backends", setup.defines, in, ex); - createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, in, ex); - createModuleList(setup.srcDir + "/base", setup.defines, in, ex); - createModuleList(setup.srcDir + "/common", setup.defines, in, ex); - createModuleList(setup.srcDir + "/engines", setup.defines, in, ex); - createModuleList(setup.srcDir + "/graphics", setup.defines, in, ex); - createModuleList(setup.srcDir + "/gui", setup.defines, in, ex); - createModuleList(setup.srcDir + "/audio", setup.defines, in, ex); - createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, in, ex); - createModuleList(setup.srcDir + "/video", setup.defines, in, ex); + createModuleList(setup.srcDir + "/backends", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/base", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/common", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/engines", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/graphics", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/gui", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/audio", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, setup.testDirs, in, ex); + createModuleList(setup.srcDir + "/video", setup.defines, setup.testDirs, in, ex); // Resource files in.push_back(setup.srcDir + "/icons/" + setup.projectName + ".ico"); @@ -1195,9 +1323,15 @@ void ProjectProvider::createProject(const BuildSetup &setup) { // Create the main project file. createProjectFile(setup.projectName, svmUUID, setup, setup.srcDir, in, ex); + } + + // Create other misc. build files + createOtherBuildFiles(setup); - // Create other misc. build files - createOtherBuildFiles(setup); + // In case we create the main ScummVM project files we will need to + // generate engines/plugins_table.h too. + if (!setup.tests && !setup.devTools) { + createEnginePluginsTable(setup); } } @@ -1306,7 +1440,7 @@ void ProjectProvider::addFilesToProject(const std::string &dir, std::ofstream &p delete files; } -void ProjectProvider::createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const { +void ProjectProvider::createModuleList(const std::string &moduleDir, const StringList &defines, StringList &testDirs, StringList &includeList, StringList &excludeList) const { const std::string moduleMkFile = moduleDir + "/module.mk"; std::ifstream moduleMk(moduleMkFile.c_str()); if (!moduleMk) @@ -1437,6 +1571,59 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin ++i; } } + } else if (*i == "TESTS") { + if (tokens.size() < 3) + error("Malformed TESTS definition in " + moduleMkFile); + ++i; + + if (*i != ":=" && *i != "+=" && *i != "=") + error("Malformed TESTS definition in " + moduleMkFile); + ++i; + + while (i != tokens.end()) { + // Read input + std::string folder = unifyPath(*i); + + // Get include folder + const std::string source_dir = "$(srcdir)/"; + const std::string selector = getLastPathComponent(folder); + const std::string module = getLastPathComponent(moduleDir); + + folder.replace(folder.find(source_dir), source_dir.length(), ""); + folder.replace(folder.find(selector), selector.length(), ""); + folder.replace(folder.find(module), module.length(), moduleDir); + + // Scan all files in the include folder + FileList files = listDirectory(folder); + + if (files.empty()) + continue; + + // Add to list of test folders + testDirs.push_back(folder); + + for (FileList::const_iterator f = files.begin(); f != files.end(); ++f) { + if (f->isDirectory) + continue; + + std::string filename = folder + f->name; + + if (shouldInclude.top()) { + // In case we should include a file, we need to make + // sure it is not in the exclude list already. If it + // is we just drop it from the exclude list. + excludeList.remove(filename); + + includeList.push_back(filename); + } else if (std::find(includeList.begin(), includeList.end(), filename) == includeList.end()) { + // We only add the file to the exclude list in case it + // has not yet been added to the include list. + excludeList.push_back(filename); + } + } + + ++i; + } } else if (*i == "ifdef") { if (tokens.size() < 2) error("Malformed ifdef in " + moduleMkFile); @@ -1473,6 +1660,37 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin error("Malformed file " + moduleMkFile); } +void ProjectProvider::createEnginePluginsTable(const BuildSetup &setup) { + // First we need to create the "engines" directory. + createDirectory(setup.outputDir + "/engines"); + + // Then, we can generate the actual "plugins_table.h" file. + const std::string enginePluginsTableFile = setup.outputDir + "/engines/plugins_table.h"; + std::ofstream enginePluginsTable(enginePluginsTableFile.c_str()); + if (!enginePluginsTable) { + error("Could not open \"" + enginePluginsTableFile + "\" for writing"); + } + + enginePluginsTable << "/* This file is automatically generated by create_project */\n" + << "/* DO NOT EDIT MANUALLY */\n" + << "// This file is being included by \"base/plugins.cpp\"\n"; + + for (EngineDescList::const_iterator i = setup.engines.begin(), end = setup.engines.end(); i != end; ++i) { + // We ignore all sub engines here because they require no special + // handling. + if (isSubEngine(i->name, setup.engines)) { + continue; + } + + // Make the engine name all uppercase. + std::string engineName; + std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper); + + enginePluginsTable << "#if PLUGIN_ENABLED_STATIC(" << engineName << ")\n" + << "LINK_PLUGIN(" << engineName << ")\n" + << "#endif\n"; + } +} } // End of anonymous namespace void error(const std::string &message) { diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h index de77793ee7..459342a67d 100644 --- a/devtools/create_project/create_project.h +++ b/devtools/create_project/create_project.h @@ -23,6 +23,10 @@ #ifndef TOOLS_CREATE_PROJECT_H #define TOOLS_CREATE_PROJECT_H +#ifndef __has_feature // Optional of course. + #define __has_feature(x) 0 // Compatibility with non-clang compilers. +#endif + #include <map> #include <list> #include <string> @@ -98,16 +102,17 @@ struct EngineDesc { typedef std::list<EngineDesc> EngineDescList; /** - * This function parses the project configure file and creates a list - * of available engines. + * This function parses the project directory and creates a list of + * available engines. * * It will also automatically setup the default build state (enabled - * or disabled) to the state specified in the "configure" file. + * or disabled) to the state specified in the individual configure.engine + * files. * * @param srcDir Path to the root of the project source. * @return List of available engines. */ -EngineDescList parseConfigure(const std::string &srcDir); +EngineDescList parseEngines(const std::string &srcDir); /** * Checks whether the specified engine is a sub engine. To determine this @@ -221,13 +226,16 @@ struct BuildSetup { StringList defines; ///< List of all defines for the build. StringList libraries; ///< List of all external libraries required for the build. + StringList testDirs; ///< List of all folders containing tests bool devTools; ///< Generate project files for the tools + bool tests; ///< Generate project files for the tests bool runBuildEvents; ///< Run build events as part of the build (generate revision number and copy engine/theme data & needed files to the build folder bool createInstaller; ///< Create NSIS installer after the build BuildSetup() { devTools = false; + tests = false; runBuildEvents = false; createInstaller = false; } @@ -256,6 +264,22 @@ void NORETURN_PRE error(const std::string &message) NORETURN_POST; namespace CreateProjectTool { /** + * Structure for describing an FSNode. This is a very minimalistic + * description, which includes everything we need. + * It only contains the name of the node and whether it is a directory + * or not. + */ +struct FSNode { + FSNode() : name(), isDirectory(false) {} + FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {} + + std::string name; ///< Name of the file system node + bool isDirectory; ///< Whether it is a directory or not +}; + +typedef std::list<FSNode> FileList; + +/** * Gets a proper sequence of \t characters for the given * indentation level. * @@ -300,6 +324,30 @@ void splitFilename(const std::string &fileName, std::string &name, std::string & bool producesObjectFile(const std::string &fileName); /** +* Convert an integer to string +* +* @param num the integer to convert +* @return string representation of the number +*/ +std::string toString(int num); + +/** + * Returns a list of all files and directories in the specified + * path. + * + * @param dir Directory which should be listed. + * @return List of all children. + */ +FileList listDirectory(const std::string &dir); + +/** + * Create a directory at the given path. + * + * @param dir The path to create. + */ +void createDirectory(const std::string &dir); + +/** * Structure representing a file tree. This contains two * members: name and children. "name" holds the name of * the node. "children" does contain all the node's children. @@ -339,7 +387,7 @@ public: * * @param setup Description of the desired build setup. */ - void createProject(const BuildSetup &setup); + void createProject(BuildSetup &setup); /** * Returns the last path component. @@ -430,10 +478,11 @@ protected: * * @param moduleDir Path to the module. * @param defines List of set defines. + * @param testDirs List of folders containing tests. * @param includeList Reference to a list, where included files should be added. * @param excludeList Reference to a list, where excluded files should be added. */ - void createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const; + void createModuleList(const std::string &moduleDir, const StringList &defines, StringList &testDirs, StringList &includeList, StringList &excludeList) const; /** * Creates an UUID for every enabled engine of the @@ -448,7 +497,7 @@ protected: * Creates an UUID for every enabled tool of the * passed build description. * - * @return A map, which includes UUIDs for all enabled engines. + * @return A map, which includes UUIDs for all enabled tools. */ UUIDMap createToolsUUIDMap() const; @@ -458,6 +507,15 @@ protected: * @return A new UUID as string. */ std::string createUUID() const; + +private: + /** + * This creates the engines/plugins_table.h file required for building + * ScummVM. + * + * @param setup Description of the desired build. + */ + void createEnginePluginsTable(const BuildSetup &setup); }; } // End of CreateProjectTool namespace diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp index 0f77d91852..07ae20e7dc 100644 --- a/devtools/create_project/msbuild.cpp +++ b/devtools/create_project/msbuild.cpp @@ -52,6 +52,9 @@ int MSBuildProvider::getVisualStudioVersion() { if (_version == 11) return 2012; + if (_version == 12) + return 2013; + error("Unsupported version passed to getVisualStudioVersion"); } @@ -64,10 +67,10 @@ inline void outputConfiguration(std::ostream &project, const std::string &config "\t\t</ProjectConfiguration>\n"; } -inline void outputConfigurationType(const BuildSetup &setup, std::ostream &project, const std::string &name, const std::string &config, int version) { +inline void outputConfigurationType(const BuildSetup &setup, std::ostream &project, const std::string &name, const std::string &config, std::string toolset) { project << "\t<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='" << config << "'\" Label=\"Configuration\">\n" - "\t\t<ConfigurationType>" << ((name == setup.projectName || setup.devTools) ? "Application" : "StaticLibrary") << "</ConfigurationType>\n" - "\t\t<PlatformToolset>v" << version << "0</PlatformToolset>\n" + "\t\t<ConfigurationType>" << ((name == setup.projectName || setup.devTools || setup.tests) ? "Application" : "StaticLibrary") << "</ConfigurationType>\n" + "\t\t<PlatformToolset>" << toolset << "</PlatformToolset>\n" "\t</PropertyGroup>\n"; } @@ -88,13 +91,15 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri error("Could not open \"" + projectFile + "\" for writing"); project << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" + "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" "\t<ItemGroup Label=\"ProjectConfigurations\">\n"; outputConfiguration(project, "Debug", "Win32"); outputConfiguration(project, "Debug", "x64"); outputConfiguration(project, "Analysis", "Win32"); outputConfiguration(project, "Analysis", "x64"); + outputConfiguration(project, "LLVM", "Win32"); + outputConfiguration(project, "LLVM", "x64"); outputConfiguration(project, "Release", "Win32"); outputConfiguration(project, "Release", "x64"); @@ -105,18 +110,23 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri "\t\t<ProjectGuid>{" << uuid << "}</ProjectGuid>\n" "\t\t<RootNamespace>" << name << "</RootNamespace>\n" "\t\t<Keyword>Win32Proj</Keyword>\n" - "\t\t<VCTargetsPath Condition=\"'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''\">$(VCTargetsPath11)</VCTargetsPath>\n" + "\t\t<VCTargetsPath Condition=\"'$(VCTargetsPath" << _version << ")' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''\">$(VCTargetsPath" << _version << ")</VCTargetsPath>\n" "\t</PropertyGroup>\n"; // Shared configuration project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n"; - outputConfigurationType(setup, project, name, "Release|Win32", _version); - outputConfigurationType(setup, project, name, "Analysis|Win32", _version); - outputConfigurationType(setup, project, name, "Debug|Win32", _version); - outputConfigurationType(setup, project, name, "Release|x64", _version); - outputConfigurationType(setup, project, name, "Analysis|x64", _version); - outputConfigurationType(setup, project, name, "Debug|x64", _version); + std::string version = "v" + toString(_version) + "0"; + std::string llvm = "LLVM-vs" + toString(getVisualStudioVersion()); + + outputConfigurationType(setup, project, name, "Release|Win32", version); + outputConfigurationType(setup, project, name, "Analysis|Win32", version); + outputConfigurationType(setup, project, name, "LLVM|Win32", llvm); + outputConfigurationType(setup, project, name, "Debug|Win32", version); + outputConfigurationType(setup, project, name, "Release|x64", version); + outputConfigurationType(setup, project, name, "LLVM|x64", llvm); + outputConfigurationType(setup, project, name, "Analysis|x64", version); + outputConfigurationType(setup, project, name, "Debug|x64", version); project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n" "\t<ImportGroup Label=\"ExtensionSettings\">\n" @@ -124,20 +134,24 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri outputProperties(project, "Release|Win32", setup.projectDescription + "_Release.props"); outputProperties(project, "Analysis|Win32", setup.projectDescription + "_Analysis.props"); + outputProperties(project, "LLVM|Win32", setup.projectDescription + "_LLVM.props"); outputProperties(project, "Debug|Win32", setup.projectDescription + "_Debug.props"); outputProperties(project, "Release|x64", setup.projectDescription + "_Release64.props"); outputProperties(project, "Analysis|x64", setup.projectDescription + "_Analysis64.props"); + outputProperties(project, "LLVM|x64", setup.projectDescription + "_LLVM64.props"); outputProperties(project, "Debug|x64", setup.projectDescription + "_Debug64.props"); project << "\t<PropertyGroup Label=\"UserMacros\" />\n"; // Project-specific settings (analysis uses debug properties) - outputProjectSettings(project, name, setup, false, true, false); - outputProjectSettings(project, name, setup, false, true, true); - outputProjectSettings(project, name, setup, true, true, false); - outputProjectSettings(project, name, setup, false, false, false); - outputProjectSettings(project, name, setup, false, false, true); - outputProjectSettings(project, name, setup, true, false, false); + outputProjectSettings(project, name, setup, false, true, "Debug"); + outputProjectSettings(project, name, setup, false, true, "Analysis"); + outputProjectSettings(project, name, setup, false, true, "LLVM"); + outputProjectSettings(project, name, setup, true, true, "Release"); + outputProjectSettings(project, name, setup, false, false, "Debug"); + outputProjectSettings(project, name, setup, false, false, "Analysis"); + outputProjectSettings(project, name, setup, false, false, "LLVM"); + outputProjectSettings(project, name, setup, true, false, "Release"); // Files std::string modulePath; @@ -156,10 +170,26 @@ void MSBuildProvider::createProjectFile(const std::string &name, const std::stri if (name == setup.projectName) writeReferences(setup, project); + // Output auto-generated test runner + if (setup.tests) { + project << "\t<ItemGroup>\n"; + project << "\t\t<ClCompile Include=\"test_runner.cpp\" />\n"; + project << "\t</ItemGroup>\n"; + } + project << "\t<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n" "\t<ImportGroup Label=\"ExtensionTargets\">\n" - "\t</ImportGroup>\n" - "</Project>\n"; + "\t</ImportGroup>\n"; + + if (setup.tests) { + // We override the normal target to ignore the exit code (this allows us to have a clean output and not message about the command exit code) + project << "\t\t<Target Name=\"PostBuildEvent\">\n" + << "\t\t\t<Message Text=\"Description: Run tests\" />\n" + << "\t\t\t<Exec Command=\"$(TargetPath)\" IgnoreExitCode=\"true\" />\n" + << "\t\t</Target>\n"; + } + + project << "</Project>\n"; // Output filter file if necessary createFiltersFile(setup, name); @@ -184,7 +214,7 @@ void MSBuildProvider::createFiltersFile(const BuildSetup &setup, const std::stri error("Could not open \"" + filtersFile + "\" for writing"); filters << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"; + "<Project ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"; // Output the list of filters filters << "\t<ItemGroup>\n"; @@ -236,16 +266,14 @@ void MSBuildProvider::writeReferences(const BuildSetup &setup, std::ofstream &ou output << "\t</ItemGroup>\n"; } -void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) { - const std::string configuration = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug")); - +void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) { // Check for project-specific warnings: std::map<std::string, StringList>::iterator warningsIterator = _projectWarnings.find(name); bool enableLanguageExtensions = find(_enableLanguageExtensions.begin(), _enableLanguageExtensions.end(), name) != _enableLanguageExtensions.end(); bool disableEditAndContinue = find(_disableEditAndContinue.begin(), _disableEditAndContinue.end(), name) != _disableEditAndContinue.end(); // Nothing to add here, move along! - if (!setup.devTools && name != setup.projectName && !enableLanguageExtensions && !disableEditAndContinue && warningsIterator == _projectWarnings.end()) + if ((!setup.devTools || !setup.tests) && name != setup.projectName && !enableLanguageExtensions && !disableEditAndContinue && warningsIterator == _projectWarnings.end()) return; std::string warnings = ""; @@ -257,7 +285,7 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s "\t\t<ClCompile>\n"; // Language Extensions - if (setup.devTools || name == setup.projectName || enableLanguageExtensions) + if (setup.devTools || setup.tests || name == setup.projectName || enableLanguageExtensions) project << "\t\t\t<DisableLanguageExtensions>false</DisableLanguageExtensions>\n"; // Edit and Continue @@ -271,18 +299,18 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s project << "\t\t</ClCompile>\n"; // Link configuration for main project - if (name == setup.projectName || setup.devTools) { + if (name == setup.projectName || setup.devTools || setup.tests) { std::string libraries; for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) libraries += *i + ".lib;"; project << "\t\t<Link>\n" - "\t\t\t<OutputFile>$(OutDir)" << (setup.devTools ? name : setup.projectName) << ".exe</OutputFile>\n" + "\t\t\t<OutputFile>$(OutDir)" << ((setup.devTools || setup.tests) ? name : setup.projectName) << ".exe</OutputFile>\n" "\t\t\t<AdditionalDependencies>" << libraries << "%(AdditionalDependencies)</AdditionalDependencies>\n" "\t\t</Link>\n"; - if (!setup.devTools && setup.runBuildEvents) { + if (!setup.devTools && !setup.tests && setup.runBuildEvents) { project << "\t\t<PreBuildEvent>\n" "\t\t\t<Message>Generate revision</Message>\n" "\t\t\t<Command>" << getPreBuildEvent() << "</Command>\n" @@ -293,6 +321,11 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s "\t\t\t<Message>Copy data files to the build folder</Message>\n" "\t\t\t<Command>" << getPostBuildEvent(isWin32, setup.createInstaller) << "</Command>\n" "\t\t</PostBuildEvent>\n"; + } else if (setup.tests) { + project << "\t\t<PreBuildEvent>\n" + "\t\t\t<Message>Generate runner.cpp</Message>\n" + "\t\t\t<Command>" << getTestPreBuildEvent(setup) << "</Command>\n" + "\t\t</PreBuildEvent>\n"; } } @@ -314,9 +347,8 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea definesList += REVISION_DEFINE ";"; properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" + "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" "\t<PropertyGroup>\n" - "\t\t<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n" "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_Global</_PropertySheetDisplayName>\n" "\t\t<ExecutablePath>$(" << LIBS_DEFINE << ")\\bin;$(ExecutablePath)</ExecutablePath>\n" "\t\t<LibraryPath>$(" << LIBS_DEFINE << ")\\lib\\" << (bits == 32 ? "x86" : "x64") << ";$(LibraryPath)</LibraryPath>\n" @@ -328,9 +360,9 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea "\t\t<ClCompile>\n" "\t\t\t<DisableLanguageExtensions>true</DisableLanguageExtensions>\n" "\t\t\t<DisableSpecificWarnings>" << warnings << ";%(DisableSpecificWarnings)</DisableSpecificWarnings>\n" - "\t\t\t<AdditionalIncludeDirectories>$(" << LIBS_DEFINE << ")\\include;" << prefix << ";" << prefix << "\\engines;$(TargetDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" + "\t\t\t<AdditionalIncludeDirectories>$(" << LIBS_DEFINE << ")\\include;.\\;" << prefix << ";" << prefix << "\\engines;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n" "\t\t\t<PreprocessorDefinitions>" << definesList << "%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" - "\t\t\t<ExceptionHandling>" << (setup.devTools ? "Sync" : "") << "</ExceptionHandling>\n"; + "\t\t\t<ExceptionHandling>" << ((setup.devTools || setup.tests) ? "Sync" : "") << "</ExceptionHandling>\n"; #if NEEDS_RTTI properties << "\t\t\t<RuntimeTypeInfo>true</RuntimeTypeInfo>\n"; @@ -346,7 +378,7 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea "\t\t\t<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n" "\t\t\t<SubSystem>Console</SubSystem>\n"; - if (!setup.devTools) + if (!setup.devTools && !setup.tests) properties << "\t\t\t<EntryPointSymbol>WinMainCRTStartup</EntryPointSymbol>\n"; properties << "\t\t</Link>\n" @@ -359,22 +391,20 @@ void MSBuildProvider::outputGlobalPropFile(const BuildSetup &setup, std::ofstrea properties.flush(); } -void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) { - const std::string outputType = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug")); +void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) { const std::string outputBitness = (isWin32 ? "32" : "64"); - std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); + std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); if (!properties) - error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); + error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); properties << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" - "<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" + "<Project DefaultTargets=\"Build\" ToolsVersion=\"" << (_version >= 12 ? _version : 4) << ".0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n" "\t<ImportGroup Label=\"PropertySheets\">\n" "\t\t<Import Project=\"" << setup.projectDescription << "_Global" << (isWin32 ? "" : "64") << ".props\" />\n" "\t</ImportGroup>\n" "\t<PropertyGroup>\n" - "\t\t<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n" - "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << outputType << outputBitness << "</_PropertySheetDisplayName>\n" + "\t\t<_PropertySheetDisplayName>" << setup.projectDescription << "_" << configuration << outputBitness << "</_PropertySheetDisplayName>\n" "\t\t<LinkIncremental>" << (isRelease ? "false" : "true") << "</LinkIncremental>\n" "\t</PropertyGroup>\n" "\t<ItemDefinitionGroup>\n" @@ -388,22 +418,26 @@ void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, b "\t\t\t<BufferSecurityCheck>false</BufferSecurityCheck>\n" "\t\t\t<DebugInformationFormat></DebugInformationFormat>\n" "\t\t\t<RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n" - "\t\t\t<EnablePREfast>" << (enableAnalysis ? "true" : "false") << "</EnablePREfast>\n" + "\t\t\t<EnablePREfast>" << (configuration == "Analysis" ? "true" : "false") << "</EnablePREfast>\n" "\t\t</ClCompile>\n" "\t\t<Link>\n" "\t\t\t<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>\n" "\t\t\t<SetChecksum>true</SetChecksum>\n"; } else { properties << "\t\t\t<Optimization>Disabled</Optimization>\n" - "\t\t\t<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" + "\t\t\t<PreprocessorDefinitions>WIN32;" << (configuration == "LLVM" ? "_CRT_SECURE_NO_WARNINGS;" : "") << "%(PreprocessorDefinitions)</PreprocessorDefinitions>\n" "\t\t\t<MinimalRebuild>true</MinimalRebuild>\n" "\t\t\t<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n" "\t\t\t<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\n" "\t\t\t<FunctionLevelLinking>true</FunctionLevelLinking>\n" "\t\t\t<TreatWarningAsError>false</TreatWarningAsError>\n" "\t\t\t<DebugInformationFormat>" << (isWin32 ? "EditAndContinue" : "ProgramDatabase") << "</DebugInformationFormat>\n" // For x64 format Edit and continue is not supported, thus we default to Program Database - "\t\t\t<EnablePREfast>" << (enableAnalysis ? "true" : "false") << "</EnablePREfast>\n" - "\t\t</ClCompile>\n" + "\t\t\t<EnablePREfast>" << (configuration == "Analysis" ? "true" : "false") << "</EnablePREfast>\n"; + + if (configuration == "LLVM") + properties << "\t\t\t<AdditionalOptions>-Wno-microsoft -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -Wpointer-arith -Wcast-qual -Wshadow -Wnon-virtual-dtor -Wwrite-strings -Wno-conversion -Wno-shorten-64-to-32 -Wno-sign-compare -Wno-four-char-constants -Wno-nested-anon-types %(AdditionalOptions)</AdditionalOptions>\n"; + + properties << "\t\t</ClCompile>\n" "\t\t<Link>\n" "\t\t\t<GenerateDebugInformation>true</GenerateDebugInformation>\n" "\t\t\t<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>\n" @@ -459,7 +493,7 @@ void MSBuildProvider::writeFileListToProject(const FileNode &dir, std::ofstream // Deal with duplicated file names if (isDuplicate) { projectFile << "\t\t<ClCompile Include=\"" << (*entry).path << "\">\n" - "\t\t\t<ObjectFileName>$(IntDir)" << (*entry).prefix << "%(Filename).obj</ObjectFileName>\n"; + "\t\t\t<ObjectFileName>$(IntDir)" << (*entry).prefix << "%(Filename).obj</ObjectFileName>\n"; projectFile << "\t\t</ClCompile>\n"; } else { diff --git a/devtools/create_project/msbuild.h b/devtools/create_project/msbuild.h index fa6667741a..829657beff 100644 --- a/devtools/create_project/msbuild.h +++ b/devtools/create_project/msbuild.h @@ -35,7 +35,7 @@ protected: void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, const StringList &includeList, const StringList &excludeList); - void outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis); + void outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration); void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); @@ -44,7 +44,7 @@ protected: void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents); - void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis); + void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration); const char *getProjectExtension(); const char *getPropertiesExtension(); diff --git a/devtools/create_project/msvc.cpp b/devtools/create_project/msvc.cpp index b8d2401af9..cdd2d8a7c1 100644 --- a/devtools/create_project/msvc.cpp +++ b/devtools/create_project/msvc.cpp @@ -79,9 +79,11 @@ void MSVCProvider::createWorkspace(const BuildSetup &setup) { "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" "\t\tDebug|Win32 = Debug|Win32\n" "\t\tAnalysis|Win32 = Analysis|Win32\n" + "\t\tLLVM|Win32 = LLVM|Win32\n" "\t\tRelease|Win32 = Release|Win32\n" "\t\tDebug|x64 = Debug|x64\n" "\t\tAnalysis|x64 = Analysis|x64\n" + "\t\tLLVM|x64 = LLVM|x64\n" "\t\tRelease|x64 = Release|x64\n" "\tEndGlobalSection\n" "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"; @@ -91,12 +93,16 @@ void MSVCProvider::createWorkspace(const BuildSetup &setup) { "\t\t{" << i->second << "}.Debug|Win32.Build.0 = Debug|Win32\n" "\t\t{" << i->second << "}.Analysis|Win32.ActiveCfg = Analysis|Win32\n" "\t\t{" << i->second << "}.Analysis|Win32.Build.0 = Analysis|Win32\n" + "\t\t{" << i->second << "}.LLVM|Win32.ActiveCfg = LLVM|Win32\n" + "\t\t{" << i->second << "}.LLVM|Win32.Build.0 = LLVM|Win32\n" "\t\t{" << i->second << "}.Release|Win32.ActiveCfg = Release|Win32\n" "\t\t{" << i->second << "}.Release|Win32.Build.0 = Release|Win32\n" "\t\t{" << i->second << "}.Debug|x64.ActiveCfg = Debug|x64\n" "\t\t{" << i->second << "}.Debug|x64.Build.0 = Debug|x64\n" "\t\t{" << i->second << "}.Analysis|x64.ActiveCfg = Analysis|x64\n" "\t\t{" << i->second << "}.Analysis|x64.Build.0 = Analysis|x64\n" + "\t\t{" << i->second << "}.LLVM|x64.ActiveCfg = LLVM|x64\n" + "\t\t{" << i->second << "}.LLVM|x64.Build.0 = LLVM|x64\n" "\t\t{" << i->second << "}.Release|x64.ActiveCfg = Release|x64\n" "\t\t{" << i->second << "}.Release|x64.Build.0 = Release|x64\n"; } @@ -114,12 +120,14 @@ void MSVCProvider::createOtherBuildFiles(const BuildSetup &setup) { // Create the configuration property files (for Debug and Release with 32 and 64bits versions) // Note: we use the debug properties for the analysis configuration - createBuildProp(setup, true, false, false); - createBuildProp(setup, true, true, false); - createBuildProp(setup, false, false, false); - createBuildProp(setup, false, false, true); - createBuildProp(setup, false, true, false); - createBuildProp(setup, false, true, true); + createBuildProp(setup, true, false, "Release"); + createBuildProp(setup, true, true, "Release"); + createBuildProp(setup, false, false, "Debug"); + createBuildProp(setup, false, true, "Debug"); + createBuildProp(setup, false, false, "Analysis"); + createBuildProp(setup, false, true, "Analysis"); + createBuildProp(setup, false, false, "LLVM"); + createBuildProp(setup, false, true, "LLVM"); } void MSVCProvider::createGlobalProp(const BuildSetup &setup) { @@ -161,6 +169,16 @@ std::string MSVCProvider::getPreBuildEvent() const { return cmdLine; } +std::string MSVCProvider::getTestPreBuildEvent(const BuildSetup &setup) const { + // Build list of folders containing tests + std::string target = ""; + + for (StringList::const_iterator it = setup.testDirs.begin(); it != setup.testDirs.end(); ++it) + target += " $(SolutionDir)" + *it + "*.h"; + + return ""$(SolutionDir)../../test/cxxtest/cxxtestgen.py" --runner=ParenPrinter --no-std --no-eh -o $(SolutionDir)test_runner.cpp" + target; +} + std::string MSVCProvider::getPostBuildEvent(bool isWin32, bool createInstaller) const { std::string cmdLine = ""; diff --git a/devtools/create_project/msvc.h b/devtools/create_project/msvc.h index 5a854b596a..3a3eb98034 100644 --- a/devtools/create_project/msvc.h +++ b/devtools/create_project/msvc.h @@ -70,7 +70,7 @@ protected: * @param isWin32 Bitness of property file * @param enableAnalysis PREfast support */ - virtual void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) = 0; + virtual void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) = 0; /** * Get the file extension for property files @@ -88,6 +88,13 @@ protected: std::string getPreBuildEvent() const; /** + * Get the command line for the test generator + * + * @param setup Description of the desired build setup. + */ + std::string getTestPreBuildEvent(const BuildSetup &setup) const; + + /** * Get the command line for copying data files to the build directory. * * @param isWin32 Bitness of property file. diff --git a/devtools/create_project/msvc12/create_project.sln b/devtools/create_project/msvc12/create_project.sln new file mode 100644 index 0000000000..759d5430f5 --- /dev/null +++ b/devtools/create_project/msvc12/create_project.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcxproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/devtools/create_project/msvc12/create_project.vcxproj b/devtools/create_project/msvc12/create_project.vcxproj new file mode 100644 index 0000000000..c26b1e5f45 --- /dev/null +++ b/devtools/create_project/msvc12/create_project.vcxproj @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CF177559-077D-4A08-AABE-BE0FD35F6C63}</ProjectGuid> + <RootNamespace>create_project</RootNamespace> + <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''">$(VCTargetsPath11)</VCTargetsPath> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level4</WarningLevel> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <DisableLanguageExtensions>false</DisableLanguageExtensions> + <DisableSpecificWarnings>4003;4512;4127</DisableSpecificWarnings> + </ClCompile> + <Link> + <AdditionalDependencies>Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + </Link> + <PostBuildEvent> + <Command>@echo off +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc12\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc11\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc10\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc9\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc8\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\codeblocks\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4003;4512;4127</DisableSpecificWarnings> + </ClCompile> + <Link> + <AdditionalDependencies>Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <GenerateDebugInformation>true</GenerateDebugInformation> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <TargetMachine>MachineX86</TargetMachine> + </Link> + <PostBuildEvent> + <Command>@echo off +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc12\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc11\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc10\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc9\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\msvc8\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\codeblocks\" +xcopy /Y "$(TargetPath)" "$(SolutionDir)\..\..\..\dists\iphone\"</Command> + </PostBuildEvent> + <PreBuildEvent> + <Command> + </Command> + </PreBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\codeblocks.cpp" /> + <ClCompile Include="..\create_project.cpp" /> + <ClCompile Include="..\msbuild.cpp" /> + <ClCompile Include="..\msvc.cpp" /> + <ClCompile Include="..\visualstudio.cpp" /> + <ClCompile Include="..\xcode.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\codeblocks.h" /> + <ClInclude Include="..\config.h" /> + <ClInclude Include="..\create_project.h" /> + <ClInclude Include="..\msbuild.h" /> + <ClInclude Include="..\msvc.h" /> + <ClInclude Include="..\visualstudio.h" /> + <ClInclude Include="..\xcode.h" /> + </ItemGroup> + <ItemGroup> + <None Include="..\scripts\installer.vbs" /> + <None Include="..\scripts\postbuild.cmd" /> + <None Include="..\scripts\prebuild.cmd" /> + <None Include="..\scripts\revision.vbs" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/devtools/create_project/msvc12/create_project.vcxproj.filters b/devtools/create_project/msvc12/create_project.vcxproj.filters new file mode 100644 index 0000000000..436d1d3436 --- /dev/null +++ b/devtools/create_project/msvc12/create_project.vcxproj.filters @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{2e3580c8-ec3a-4c81-8351-b668c668db2a}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{31aaf58c-d3cb-4ed6-8eca-163b4a9b31a6}</UniqueIdentifier> + </Filter> + <Filter Include="scripts"> + <UniqueIdentifier>{f980f6fb-41b6-4161-b035-58b200c85cad}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\codeblocks.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\create_project.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\msvc.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\msbuild.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\visualstudio.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\xcode.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\codeblocks.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\create_project.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\msvc.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\msbuild.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\visualstudio.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\xcode.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\scripts\prebuild.cmd"> + <Filter>scripts</Filter> + </None> + <None Include="..\scripts\revision.vbs"> + <Filter>scripts</Filter> + </None> + <None Include="..\scripts\postbuild.cmd"> + <Filter>scripts</Filter> + </None> + <None Include="..\scripts\installer.vbs"> + <Filter>scripts</Filter> + </None> + </ItemGroup> +</Project> diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp index de2df96d78..84bc674f9a 100644 --- a/devtools/create_project/visualstudio.cpp +++ b/devtools/create_project/visualstudio.cpp @@ -83,7 +83,7 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: // Check for project-specific warnings: std::map< std::string, std::list<std::string> >::iterator warningsIterator = _projectWarnings.find(name); - if (setup.devTools || name == setup.projectName) { + if (setup.devTools || setup.tests || name == setup.projectName) { std::string libraries; for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) @@ -92,6 +92,7 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: // Win32 outputConfiguration(project, setup, libraries, "Debug", "Win32", "", true); outputConfiguration(project, setup, libraries, "Analysis", "Win32", "", true); + outputConfiguration(project, setup, libraries, "LLVM", "Win32", "", true); outputConfiguration(project, setup, libraries, "Release", "Win32", "", true); // x64 @@ -100,6 +101,7 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: // libraries list created for IA-32. If that changes in the future, we need to adjust this part! outputConfiguration(project, setup, libraries, "Debug", "x64", "64", false); outputConfiguration(project, setup, libraries, "Analysis", "x64", "64", false); + outputConfiguration(project, setup, libraries, "LLVM", "Win32", "64", false); outputConfiguration(project, setup, libraries, "Release", "x64", "64", false); } else { @@ -119,9 +121,11 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: // Win32 outputConfiguration(setup, project, toolConfig, "Debug", "Win32", ""); outputConfiguration(setup, project, toolConfig, "Analysis", "Win32", ""); + outputConfiguration(setup, project, toolConfig, "LLVM", "Win32", ""); outputConfiguration(setup, project, toolConfig, "Release", "Win32", ""); outputConfiguration(setup, project, toolConfig, "Debug", "x64", "64"); outputConfiguration(setup, project, toolConfig, "Analysis", "x64", "64"); + outputConfiguration(setup, project, toolConfig, "LLVM", "x64", "64"); outputConfiguration(setup, project, toolConfig, "Release", "x64", "64"); } @@ -140,6 +144,11 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: else addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix); + // Output auto-generated test runner + if (setup.tests) { + project << "\t\t<File RelativePath=\"test_runner.cpp\" />\n"; + } + project << "\t</Files>\n" "</VisualStudioProject>\n"; } @@ -161,7 +170,7 @@ void VisualStudioProvider::outputConfiguration(const BuildSetup &setup, std::ost } void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildSetup &setup, const bool isWin32) { - if (!setup.devTools && setup.runBuildEvents) { + if (!setup.devTools && !setup.tests && setup.runBuildEvents) { project << "\t\t\t<Tool\tName=\"VCPreBuildEventTool\"\n" "\t\t\t\tCommandLine=\"" << getPreBuildEvent() << "\"\n" "\t\t\t/>\n" @@ -169,6 +178,17 @@ void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildS "\t\t\t\tCommandLine=\"" << getPostBuildEvent(isWin32, setup.createInstaller) << "\"\n" "\t\t\t/>\n"; } + + // Generate runner file before build for tests + if (setup.tests) { + project << "\t\t\t<Tool\tName=\"VCPreBuildEventTool\"\n" + "\t\t\t\tCommandLine=\"" << getTestPreBuildEvent(setup) << "\"\n" + "\t\t\t/>\n"; + + project << "\t\t\t<Tool\tName=\"VCPostBuildEventTool\"\n" + "\t\t\t\tCommandLine=\"$(TargetPath)\" IgnoreExitCode=\"true\"\n" + "\t\t\t/>\n"; + } } void VisualStudioProvider::writeReferences(const BuildSetup &setup, std::ofstream &output) { @@ -212,9 +232,9 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of "\t\tName=\"VCCLCompilerTool\"\n" "\t\tDisableLanguageExtensions=\"" << (setup.devTools ? "false" : "true") << "\"\n" "\t\tDisableSpecificWarnings=\"" << warnings << "\"\n" - "\t\tAdditionalIncludeDirectories=\"" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;$(TargetDir)\"\n" + "\t\tAdditionalIncludeDirectories=\".\\;" << prefix << ";" << prefix << "\\engines;$(" << LIBS_DEFINE << ")\\include;" << (setup.tests ? prefix + "\\test\\cxxtest;" : "") << "$(TargetDir)\"\n" "\t\tPreprocessorDefinitions=\"" << definesList << "\"\n" - "\t\tExceptionHandling=\"" << (setup.devTools ? "1" : "0") << "\"\n"; + "\t\tExceptionHandling=\"" << ((setup.devTools || setup.tests) ? "1" : "0") << "\"\n"; #if NEEDS_RTTI properties << "\t\tRuntimeTypeInfo=\"true\"\n"; @@ -235,7 +255,7 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of "\t\tIgnoreDefaultLibraryNames=\"\"\n" "\t\tSubSystem=\"1\"\n"; - if (!setup.devTools) + if (!setup.devTools && !setup.tests) properties << "\t\tEntryPointSymbol=\"WinMainCRTStartup\"\n"; properties << "\t\tAdditionalLibraryDirectories=\"$(" << LIBS_DEFINE << ")\\lib\\" << ((bits == 32) ? "x86" : "x64") << "\"\n" @@ -249,19 +269,18 @@ void VisualStudioProvider::outputGlobalPropFile(const BuildSetup &setup, std::of properties.flush(); } -void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) { - const std::string outputType = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug")); +void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration) { const std::string outputBitness = (isWin32 ? "32" : "64"); - std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); + std::ofstream properties((setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); if (!properties) - error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); + error("Could not open \"" + setup.outputDir + '/' + setup.projectDescription + "_" + configuration + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); properties << "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n" "<VisualStudioPropertySheet\n" "\tProjectType=\"Visual C++\"\n" "\tVersion=\"8.00\"\n" - "\tName=\"" << setup.projectDescription << "_" << outputType << outputBitness << "\"\n" + "\tName=\"" << setup.projectDescription << "_" << configuration << outputBitness << "\"\n" "\tInheritedPropertySheets=\".\\" << setup.projectDescription << "_Global" << (isWin32 ? "" : "64") << ".vsprops\"\n" "\t>\n" "\t<Tool\n" @@ -275,7 +294,7 @@ void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelea "\t\tBufferSecurityCheck=\"false\"\n" "\t\tDebugInformationFormat=\"0\"\n" "\t\tRuntimeLibrary=\"0\"\n" - "\t\tAdditionalOption=\"" << (enableAnalysis ? "/analyze" : "") << "\"\n" + "\t\tAdditionalOption=\"" << (configuration == "Analysis" ? "/analyze" : "") << "\"\n" "\t/>\n" "\t<Tool\n" "\t\tName=\"VCLinkerTool\"\n" @@ -291,7 +310,7 @@ void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelea "\t\tEnableFunctionLevelLinking=\"true\"\n" "\t\tWarnAsError=\"false\"\n" "\t\tDebugInformationFormat=\"" << (isWin32 ? "4" : "3") << "\"\n" // For x64 format "4" (Edit and continue) is not supported, thus we default to "3" - "\t\tAdditionalOption=\"" << (enableAnalysis ? "/analyze" : "") << "\"\n" + "\t\tAdditionalOption=\"" << (configuration == "Analysis" ? "/analyze" : "") << "\"\n" "\t/>\n" "\t<Tool\n" "\t\tName=\"VCLinkerTool\"\n" @@ -338,9 +357,9 @@ void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofst << indentString << "\t<FileConfiguration Name=\"Debug|Win32\">\n" << toolLine << indentString << "\t</FileConfiguration>\n" - << indentString << "\t<FileConfiguration Name=\"Analysis|Win32\">\n" - << toolLine - << indentString << "\t</FileConfiguration>\n" + << indentString << "\t<FileConfiguration Name=\"Analysis|Win32\">\n" + << toolLine + << indentString << "\t</FileConfiguration>\n" << indentString << "\t<FileConfiguration Name=\"Release|Win32\">\n" << toolLine << indentString << "\t</FileConfiguration>\n" @@ -353,18 +372,18 @@ void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofst << indentString << "\t<FileConfiguration Name=\"Debug|Win32\">\n" << toolLine << indentString << "\t</FileConfiguration>\n" - << indentString << "\t<FileConfiguration Name=\"Analysis|Win32\">\n" - << toolLine - << indentString << "\t</FileConfiguration>\n" + << indentString << "\t<FileConfiguration Name=\"Analysis|Win32\">\n" + << toolLine + << indentString << "\t</FileConfiguration>\n" << indentString << "\t<FileConfiguration Name=\"Release|Win32\">\n" << toolLine << indentString << "\t</FileConfiguration>\n" - << indentString << "\t<FileConfiguration Name=\"Debug|x64\">\n" - << toolLine - << indentString << "\t</FileConfiguration>\n" - << indentString << "\t<FileConfiguration Name=\"Analysis|x64\">\n" - << toolLine - << indentString << "\t</FileConfiguration>\n" + << indentString << "\t<FileConfiguration Name=\"Debug|x64\">\n" + << toolLine + << indentString << "\t</FileConfiguration>\n" + << indentString << "\t<FileConfiguration Name=\"Analysis|x64\">\n" + << toolLine + << indentString << "\t</FileConfiguration>\n" << indentString << "\t<FileConfiguration Name=\"Release|x64\">\n" << toolLine << indentString << "\t</FileConfiguration>\n" diff --git a/devtools/create_project/visualstudio.h b/devtools/create_project/visualstudio.h index 845550139c..7eb66c4f2d 100644 --- a/devtools/create_project/visualstudio.h +++ b/devtools/create_project/visualstudio.h @@ -42,7 +42,7 @@ protected: void outputGlobalPropFile(const BuildSetup &setup, std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix, bool runBuildEvents); - void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis); + void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, std::string configuration); const char *getProjectExtension(); const char *getPropertiesExtension(); diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp index a9b8e7a752..d95bf3e9ee 100644 --- a/devtools/create_project/xcode.cpp +++ b/devtools/create_project/xcode.cpp @@ -26,15 +26,6 @@ #include <fstream> #include <algorithm> -#if defined(_WIN32) || defined(WIN32) -#include <windows.h> -#else -#include <sys/param.h> -#include <sys/stat.h> -#include <dirent.h> -#include <errno.h> -#endif - namespace CreateProjectTool { #define DEBUG_XCODE_HASH 0 @@ -88,27 +79,7 @@ XCodeProvider::XCodeProvider(StringList &global_warnings, std::map<std::string, void XCodeProvider::createWorkspace(const BuildSetup &setup) { // Create project folder std::string workspace = setup.outputDir + '/' + PROJECT_NAME ".xcodeproj"; - -#if defined(_WIN32) || defined(WIN32) - if (!CreateDirectory(workspace.c_str(), NULL)) - if (GetLastError() != ERROR_ALREADY_EXISTS) - error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\""); -#else - if (mkdir(workspace.c_str(), 0777) == -1) { - if (errno == EEXIST) { - // Try to open as a folder (might be a file / symbolic link) - DIR *dirp = opendir(workspace.c_str()); - if (dirp == NULL) { - error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\""); - } else { - // The folder exists, just close the stream and return - closedir(dirp); - } - } else { - error("Could not create folder \"" + setup.outputDir + '/' + PROJECT_NAME ".xcodeproj\""); - } - } -#endif + createDirectory(workspace); // Setup global objects setupDefines(setup); |
