diff --git a/reactos/tools/rbuild/backend/msvc/msvc.cpp b/reactos/tools/rbuild/backend/msvc/msvc.cpp new file mode 100644 index 00000000000..9a87f35f623 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/msvc.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2005 Trevor McCort + * Copyright (C) 2005 Casper S. Hornstrup + * Copyright (C) 2005 Steven Edwards + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include +#include +#include + +#include "MSVC.h" + +using namespace std; + +static class MSVCFactory : public Backend::Factory +{ + public: + + MSVCFactory() : Factory("MSVC") {} + Backend *operator() (Project &project, + Configuration& configuration) + { + return new MSVCBackend(project, configuration); + } + +} factory; + + +MSVCBackend::MSVCBackend(Project &project, + Configuration& configuration) : Backend(project, configuration) +{ + m_unitCount = 0; +} + +void MSVCBackend::Process() +{ + string filename = ProjectNode.name + ".sln"; + + cout << "Creating MSVC project: " << filename << endl; + + ProcessModules(); + + m_devFile.open(filename.c_str()); + + if(!m_devFile.is_open()) + { + cout << "Could not open file." << endl; + return; + } + m_devFile << "Microsoft Visual Studio Solution File, Format Version 9.00" << endl; + m_devFile << "# Visual C++ Express 2005" << endl; + + m_devFile << "# FIXME Project listings here" << endl; + m_devFile << "EndProject" << endl; + m_devFile << "Global" << endl; + m_devFile << " GlobalSection(SolutionConfigurationPlatforms) = preSolution" << endl; + m_devFile << " Debug|Win32 = Debug|Win32" << endl; + m_devFile << " Release|Win32 = Release|Win32" << endl; + m_devFile << " EndGlobalSection" << endl; + m_devFile << " GlobalSection(ProjectConfigurationPlatforms) = postSolution" << endl; + m_devFile << " #FIXME Project Listings Here" << endl; + m_devFile << " EndGlobalSection" << endl; + m_devFile << " GlobalSection(SolutionProperties) = preSolution" << endl; + m_devFile << " HideSolutionNode = FALSE" << endl; + m_devFile << " EndGlobalSection" << endl; + m_devFile << "EndGlobal" << endl; + +#if 0 + m_devFile << "[Project]" << endl; + + m_devFile << "FileName=" << filename << endl + << "Name=" << ProjectNode.name << endl + << "UnitCount=" << m_unitCount << endl + << "Type=1" << endl + << "Ver=1" << endl + << "ObjFiles=" << endl + << "Includes=" << endl + << "Libs=" << endl + << "PrivateResource=" << endl + << "ResourceIncludes=" << endl + << "MakeIncludes=" << endl + << "Compiler=" << endl + << "CppCompiler=" << endl + << "Linker=" << endl + << "IsCpp=1" << endl + << "Icon=" << endl + << "ExeOutput=" << endl + << "ObjectOutput=" << endl + << "OverrideOutput=0" << endl + << "OverrideOutputName=" << endl + << "HostApplication=" << endl + << "CommandLine=" << endl + << "UseCustomMakefile=1" << endl + << "CustomMakefile=" << ProjectNode.makefile << endl + << "IncludeVersionInto=0" << endl + << "SupportXPThemes=0" << endl + << "CompilerSet=0" << endl + << "CompilerSettings=0000000000000000000000" << endl; +#endif + + OutputFolders(); + + m_devFile << endl << endl; + + OutputFileUnits(); + + m_devFile.close(); + + // Dev-C++ needs a makefile, so use the MinGW backend to create one. + + cout << "Creating Makefile: " << ProjectNode.makefile << endl; + + Backend *backend = Backend::Factory::Create("mingw", + ProjectNode, + configuration ); + backend->Process(); + delete backend; + + cout << "Done." << endl << endl; + + cout << "You may want to disable Class browsing (see below) before you open this project in Dev-C++, as the " + << "parsing required for large projects can take quite awhile." + << endl << endl + << "(Tools->Editor Options->Class browsing->Enable class browsing check box)" + << endl << endl; +} + +void MSVCBackend::ProcessModules() +{ + for(size_t i = 0; i < ProjectNode.modules.size(); i++) + { + Module &module = *ProjectNode.modules[i]; + + for(size_t k = 0; k < module.non_if_data.files.size(); k++) + { + File &file = *module.non_if_data.files[k]; + + ProcessFile(file.name); + } + } +} + +static bool FileExists(string &filename) +{ + ifstream file(filename.c_str()); + + if(!file.is_open()) + return false; + + file.close(); + return true; +} + +void MSVCBackend::ProcessFile(string &filepath) +{ + // Remove the .\ at the start of the filenames + filepath.erase(0, 2); + + if(!FileExists(filepath)) + return; + + // Change the \ to / + for(size_t i = 0; i < filepath.length(); i++) + { + if(filepath[i] == '\\') + filepath[i] = '/'; + } + + // Remove the filename from the path + string folder = ""; + + size_t pos = filepath.rfind(string("/"), filepath.length() - 1); + + if(pos != string::npos) + { + folder = filepath; + folder.erase(pos, folder.length() - pos); + } + + FileUnit fileUnit; + fileUnit.filename = filepath; + fileUnit.folder = folder; + + m_fileUnits.push_back(fileUnit); + + if(folder != "") + AddFolders(folder); + + m_unitCount++; +} + +bool MSVCBackend::CheckFolderAdded(string &folder) +{ + for(size_t i = 0; i < m_folders.size(); i++) + { + if(m_folders[i] == folder) + return true; + } + + return false; +} + +void MSVCBackend::AddFolders(string &folder) +{ + // Check if this folder was already added. true if it was, false otherwise. + if(CheckFolderAdded(folder)) + return; + + m_folders.push_back(folder); + + size_t pos = folder.rfind(string("/"), folder.length() - 1); + + if(pos == string::npos) + return; + + folder.erase(pos, folder.length() - pos); + AddFolders(folder); +} + +void MSVCBackend::OutputFolders() +{ + m_devFile << "Folders="; + + for(size_t i = 0; i < m_folders.size(); i++) + { + if(i > 0) + m_devFile << ","; + + m_devFile << m_folders[i]; + } +} + +void MSVCBackend::OutputFileUnits() +{ + for(size_t i = 0; i < m_fileUnits.size(); i++) + { + m_devFile << "[Unit" << i + 1 << "]" << endl; + + + m_devFile << "FileName=" << m_fileUnits[i].filename << endl; + m_devFile << "CompileCpp=1" << endl; + m_devFile << "Folder=" << m_fileUnits[i].folder << endl; + m_devFile << "Compile=1" << endl; + m_devFile << "Link=1" << endl; + m_devFile << "Priority=1000" << endl; + m_devFile << "OverrideBuildCmd=0" << endl; + m_devFile << "BuildCmd=" << endl << endl;; + } +} diff --git a/reactos/tools/rbuild/backend/msvc/msvc.h b/reactos/tools/rbuild/backend/msvc/msvc.h new file mode 100644 index 00000000000..99d4d02039c --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/msvc.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005 Trevor McCort + * Copyright (C) 2005 Casper S. Hornstrup + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __MSVC_H__ +#define __MSVC_H__ + +#include +#include +#include + +#include "../backend.h" + +class FileUnit +{ + public: + std::string filename; + std::string folder; +}; + +class MSVCBackend : public Backend +{ + public: + + MSVCBackend(Project &project, + Configuration& configuration); + virtual ~MSVCBackend() {} + + virtual void Process(); + + private: + + void ProcessModules(); + void ProcessFile(std::string &filename); + + bool CheckFolderAdded(std::string &folder); + void AddFolders(std::string &folder); + + void OutputFolders(); + void OutputFileUnits(); + + std::vector m_fileUnits; + std::vector m_folders; + + int m_unitCount; + + std::ofstream m_devFile; +}; + +#endif // __DEVCPP_H__ + diff --git a/reactos/tools/rbuild/rbuild.mak b/reactos/tools/rbuild/rbuild.mak index e7a5c2b8646..febbb5a5bdd 100644 --- a/reactos/tools/rbuild/rbuild.mak +++ b/reactos/tools/rbuild/rbuild.mak @@ -102,6 +102,23 @@ $(RBUILD_DEVCPP_OUT): | $(RBUILD_BACKEND_OUT) ${mkdir} $@ endif +RBUILD_MSVC_BASE = $(RBUILD_BACKEND_BASE_)msvc +RBUILD_MSVC_BASE_ = $(RBUILD_MSVC_BASE)$(SEP) +RBUILD_MSVC_INT = $(INTERMEDIATE_)$(RBUILD_MSVC_BASE) +RBUILD_MSVC_INT_ = $(RBUILD_MSVC_INT)$(SEP) +RBUILD_MSVC_OUT = $(OUTPUT_)$(RBUILD_MSVC_BASE) +RBUILD_MSVC_OUT_ = $(RBUILD_MSVC_OUT)$(SEP) + +$(RBUILD_MSVC_INT): | $(RBUILD_BACKEND_INT) + $(ECHO_MKDIR) + ${mkdir} $@ + +ifneq ($(INTERMEDIATE),$(OUTPUT)) +$(RBUILD_MSVC_OUT): | $(RBUILD_BACKEND_OUT) + $(ECHO_MKDIR) + ${mkdir} $@ +endif + RBUILD_TARGET = \ $(EXEPREFIX)$(RBUILD_OUT_)rbuild$(EXEPOSTFIX) @@ -119,9 +136,14 @@ RBUILD_BACKEND_DEVCPP_BASE_SOURCES = $(addprefix $(RBUILD_DEVCPP_BASE_), \ devcpp.cpp \ ) +RBUILD_BACKEND_MSVC_BASE_SOURCES = $(addprefix $(RBUILD_MSVC_BASE_), \ + msvc.cpp \ + ) + RBUILD_BACKEND_SOURCES = \ $(RBUILD_BACKEND_MINGW_BASE_SOURCES) \ $(RBUILD_BACKEND_DEVCPP_BASE_SOURCES) \ + $(RBUILD_BACKEND_MSVC_BASE_SOURCES) \ $(RBUILD_BACKEND_BASE_)backend.cpp RBUILD_COMMON_SOURCES = \ @@ -167,6 +189,9 @@ RBUILD_OBJECTS = \ RBUILD_BACKEND_DEVCPP_HEADERS = \ devcpp.h +RBUILD_BACKEND_MSVCCPP_HEADERS = \ + msvc.h + RBUILD_BACKEND_MINGW_HEADERS = \ mingw.h \ modulehandler.h @@ -174,6 +199,7 @@ RBUILD_BACKEND_MINGW_HEADERS = \ RBUILD_BACKEND_HEADERS = \ backend.h \ $(addprefix devcpp$(SEP), $(RBUILD_BACKEND_DEVCPP_HEADERS)) \ + $(addprefix msvc$(SEP), $(RBUILD_BACKEND_MSVC_HEADERS)) \ $(addprefix mingw$(SEP), $(RBUILD_BACKEND_MINGW_HEADERS)) RBUILD_HEADERS = \ @@ -322,6 +348,10 @@ $(RBUILD_DEVCPP_INT_)devcpp.o: $(RBUILD_DEVCPP_BASE_)devcpp.cpp $(RBUILD_HEADERS $(ECHO_CC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ +$(RBUILD_MSVC_INT_)msvc.o: $(RBUILD_MSVC_BASE_)msvc.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) + $(ECHO_CC) + ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ + $(RBUILD_TEST_TARGET): $(RBUILD_TEST_OBJECTS) $(RBUILD_HEADERS) | $(RBUILD_OUT) $(ECHO_LD) ${host_gpp} $(RBUILD_TEST_OBJECTS) $(RBUILD_HOST_LFLAGS) -o $@