From 9d7f91d6cae0bb1c1519e5a47685ca7717edf6cc Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 1 Dec 2009 18:44:16 +0000 Subject: [PATCH] - Include support for makefile configurations. - Add a new makefile config to the global configuration called RosBuild - Use the new makefile config to process and external batch file which make use of rbuild. - Split and partially rewrite _generate_vcproj. Configurations are now written in support functions. - Remove the creation of .vcproj.user files. They're rather pointless for our needs - Start to add support for VS2010 (make msvc10), it's very incomplete at the moment so don't bother trying it. After this commit, you can now use Visual Studio to build individual reactos components. Run 'make msvc9', open up any vcproj file, select the RosBuild config and hit the build/rebuild button. Working build features are 'build', 'rebuild' and 'clean' svn path=/trunk/; revision=44343 --- reactos/tools/rbuild/backend/msvc/msvc.cpp | 11 +- reactos/tools/rbuild/backend/msvc/msvc.h | 38 +- .../tools/rbuild/backend/msvc/vcprojmaker.cpp | 963 ++++++++++-------- .../rbuild/backend/msvc/vcxprojmaker.cpp | 177 ++++ reactos/tools/rbuild/rbuild.mak | 5 + reactos/tools/rbuild/rbuild.sln | 4 +- reactos/tools/rbuild/rbuild.vcproj | 17 +- 7 files changed, 784 insertions(+), 431 deletions(-) create mode 100644 reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp diff --git a/reactos/tools/rbuild/backend/msvc/msvc.cpp b/reactos/tools/rbuild/backend/msvc/msvc.cpp index 31c638a1d72..08c0479f6b7 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.cpp +++ b/reactos/tools/rbuild/backend/msvc/msvc.cpp @@ -70,6 +70,7 @@ void MSVCBackend::Process() m_configurations.push_back ( new MSVCConfiguration( Debug )); m_configurations.push_back ( new MSVCConfiguration( Release )); m_configurations.push_back ( new MSVCConfiguration( Speed )); + m_configurations.push_back ( new MSVCConfiguration( RosBuild )); if (!only_msvc_headers) { @@ -123,6 +124,8 @@ void MSVCBackend::ProcessModules() if (configuration.VSProjectVersion == "6.00") _generate_dsp ( module ); + else if (configuration.VSProjectVersion == "10.00") + _generate_vcxproj ( module ); else _generate_vcproj ( module ); } @@ -285,10 +288,12 @@ std::string MSVCBackend::_get_vc_dir ( void ) const return "vc70"; else if ( configuration.VSProjectVersion == "7.10" ) return "vc71"; - else if ( configuration.VSProjectVersion == "9.00" ) - return "vc9"; - else /* must be VS2005 */ + else if ( configuration.VSProjectVersion == "8.00" ) return "vc8"; + else if ( configuration.VSProjectVersion == "10.00" ) + return "vc10"; + else /* default to VS2008 */ + return "vc9"; } diff --git a/reactos/tools/rbuild/backend/msvc/msvc.h b/reactos/tools/rbuild/backend/msvc/msvc.h index 19845f6a6cd..8f3f3a88ec3 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.h +++ b/reactos/tools/rbuild/backend/msvc/msvc.h @@ -25,6 +25,7 @@ #include "../backend.h" + class FileUnit { public: @@ -34,9 +35,28 @@ class FileUnit enum OptimizationType { + RosBuild, Debug, Release, - Speed + Speed, +}; + +enum ConfigurationType +{ + ConfigUnknown, + ConfigApp, + ConfigDll, + ConfigEmpty, + ConfigLib +}; + +enum BinaryType +{ + BinUnknown, + Lib, + Dll, + Exe, + Sys }; enum HeadersType @@ -123,7 +143,23 @@ class MSVCBackend : public Backend std::string _get_vc_dir ( void ) const; + // These are used in both _generate_vcproj and _generate_standard_configuration + std::vector header_files; + std::vector includes; + std::vector includes_ros; + std::vector libraries; + std::set common_defines; + std::string baseaddr; + + void _generate_standard_configuration( + FILE* OUT, + const Module& module, + const MSVCConfiguration& cfg, + BinaryType binaryType ); + void _generate_makefile_configuration( FILE* OUT, const Module& module, const MSVCConfiguration& cfg ); + void _generate_vcproj ( const Module& module ); + void _generate_vcxproj ( const Module& module ); void _generate_sln_header ( FILE* OUT ); void _generate_sln_footer ( FILE* OUT ); diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index 812e11c4b0e..2d143af44a7 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2005 Royce Mitchell III * Copyright (C) 2006 Hervé Poussineau * Copyright (C) 2006 Christoph von Wittich + * Copyright (C) 2009 Ged Murphy * * 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 @@ -71,6 +72,8 @@ MSVCConfiguration::MSVCConfiguration ( const OptimizationType optimization, cons this->name = "Release" + headers_name; else if ( optimization == Speed ) this->name = "Speed" + headers_name; + else if ( optimization == RosBuild ) + this->name = "RosBuild"; else this->name = "Unknown" + headers_name; } @@ -84,7 +87,13 @@ MSVCBackend::_generate_vcproj ( const Module& module ) string vcproj_file = VcprojFileName(module); string computername; string username; - string intermediatedir = ""; + + // make sure the containers are empty + header_files.clear(); + includes.clear(); + includes_ros.clear(); + libraries.clear(); + common_defines.clear(); if (getenv ( "USERNAME" ) != NULL) username = getenv ( "USERNAME" ); @@ -101,13 +110,6 @@ MSVCBackend::_generate_vcproj ( const Module& module ) printf ( "Creating MSVC.NET project: '%s'\n", vcproj_file.c_str() ); FILE* OUT = fopen ( vcproj_file.c_str(), "wb" ); - vector imports; - string module_type = GetExtension(*module.output); - bool lib = (module.type == ObjectLibrary) || (module.type == RpcClient) ||(module.type == RpcServer) || (module_type == ".lib") || (module_type == ".a"); - bool dll = (module_type == ".dll") || (module_type == ".cpl"); - bool exe = (module_type == ".exe") || (module_type == ".scr"); - bool sys = (module_type == ".sys"); - string path_basedir = module.GetPathToBaseDir (); string intenv = Environment::GetIntermediatePath (); string outenv = Environment::GetOutputPath (); @@ -115,7 +117,6 @@ MSVCBackend::_generate_vcproj ( const Module& module ) string intdir; string vcdir; - if ( intenv == "obj-i386" ) intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ else @@ -130,19 +131,14 @@ MSVCBackend::_generate_vcproj ( const Module& module ) { vcdir = DEF_SSEP + _get_vc_dir(); } - // TODO FIXME - need more checks here for 'sys' and possibly 'drv'? - bool console = exe && (module.type == Win32CUI); bool include_idl = false; - vector source_files, resource_files, header_files, includes, includes_ros, libraries; - StringSet common_defines; + vector source_files, resource_files; vector ifs_list; ifs_list.push_back ( &module.project.non_if_data ); ifs_list.push_back ( &module.non_if_data ); - string baseaddr; - while ( ifs_list.size() ) { const IfableData& data = *ifs_list.back(); @@ -245,417 +241,38 @@ MSVCBackend::_generate_vcproj ( const Module& module ) fprintf ( OUT, "\t\t\tName=\"Win32\"/>\r\n" ); fprintf ( OUT, "\t\r\n" ); - //fprintf ( OUT, "\t\r\n" ); - //fprintf ( OUT, "\t\t\r\n", path.c_str() ); - //fprintf ( OUT, "\t\r\n" ); - - int n = 0; - - std::string output_dir; - string importLib; - - // don't do the work m_configurations.size() times - if (module.importLibrary != NULL) - { - intermediatedir = module.output->relative_path + vcdir; - importLib = _strip_gcc_deffile(module.importLibrary->source->name, module.importLibrary->source->relative_path, intermediatedir); - importLib = Path::RelativeFromDirectory ( - importLib, - module.output->relative_path ); - } + // Set the binary type + string module_type = GetExtension(*module.output); + BinaryType binaryType; + if ((module.type == ObjectLibrary) || (module.type == RpcClient) ||(module.type == RpcServer) || (module_type == ".lib") || (module_type == ".a")) + binaryType = Lib; + else if ((module_type == ".dll") || (module_type == ".cpl")) + binaryType = Dll; + else if ((module_type == ".exe") || (module_type == ".scr")) + binaryType = Exe; + else if (module_type == ".sys") + binaryType = Sys; + else + binaryType = BinUnknown; + // Write out all the configurations fprintf ( OUT, "\t\r\n" ); for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) { const MSVCConfiguration& cfg = *m_configurations[icfg]; - bool debug = ( cfg.optimization == Debug ); - bool release = ( cfg.optimization == Release ); - bool speed = ( cfg.optimization == Speed ); - - fprintf ( OUT, "\t\trelative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); - fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); + _generate_makefile_configuration( OUT, module, cfg ); } else { - fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); - fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); + _generate_standard_configuration( OUT, module, cfg, binaryType ); } - - fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", exe ? 1 : dll ? 2 : lib ? 4 : -1 ); - fprintf ( OUT, "\t\t\tCharacterSet=\"2\">\r\n" ); - - fprintf ( OUT, "\t\t\t 0 ) - fprintf ( OUT, ";" ); - - string unescaped = *it1; - fprintf ( OUT, "%s", _replace_str(unescaped, "\"","").c_str() ); - } - fprintf ( OUT, "\"\r\n" ); - fprintf ( OUT, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h"); - fprintf ( OUT, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed ? "TRUE" : "FALSE" ); - fprintf ( OUT, "\t\t\t\tBasicRuntimeChecks=\"0\"\r\n" ); - fprintf ( OUT, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug ? 3 : 2 ); // 3=/MDd 2=/MD - fprintf ( OUT, "\t\t\t\tBufferSecurityCheck=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" ); - - if ( module.pch != NULL ) - { - fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" ); - string pch_path = Path::RelativeFromDirectory ( - module.pch->file->name, - module.output->relative_path ); - string::size_type pos = pch_path.find_last_of ("/"); - if ( pos != string::npos ) - pch_path.erase(0, pos+1); - fprintf ( OUT, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path.c_str() ); - - // Only include from the same module - pos = pch_path.find("../"); - if (pos == string::npos && std::find(header_files.begin(), header_files.end(), pch_path) == header_files.end()) - header_files.push_back(pch_path); - } - else - { - fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" ); - } - - fprintf ( OUT, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release ? "FALSE" : "FALSE"); - if ( release ) - { - fprintf ( OUT, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" ); - fprintf ( OUT, "\t\t\t\tStringPooling=\"true\"\r\n" ); - } - - fprintf ( OUT, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed ? "0" : "3" ); - fprintf ( OUT, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE"); - if ( !module.cplusplus ) - fprintf ( OUT, "\t\t\t\tCompileAs=\"1\"\r\n" ); - - if ( module.type == Win32CUI || module.type == Win32GUI ) - { - fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 ); // 0=__cdecl - } - else - { - fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 ); // 2=__stdcall - } - - fprintf ( OUT, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed ? "0" : release ? "3": "4"); // 3=/Zi 4=ZI - - fprintf ( OUT, "\t\t\t\r\n" ); - - if ( lib ) - { - fprintf ( OUT, "\t\t\t\r\n", module.name.c_str() ); - } - else - { - fprintf ( OUT, "\t\t\t 0 ) - fprintf ( OUT, " " ); - string libpath = libraries[i].c_str(); - libpath = libpath.erase (0, libpath.find_last_of ("\\") + 1 ); - if ( libpath == "msvcrt.lib" ) - { - use_msvcrt_lib = true; - } - fprintf ( OUT, "%s", libpath.c_str() ); - } - fprintf ( OUT, "\"\r\n" ); - - fprintf ( OUT, "\t\t\t\tAdditionalLibraryDirectories=\"" ); - - // Add WDK libs paths, if needed - if (getenv ( "BASEDIR" ) != NULL && - (module.type == Kernel || - module.type == KernelModeDLL || - module.type == KernelModeDriver || - module.type == KeyboardLayout)) - { - string WdkBase, CrtPath, DdkPath; - WdkBase = getenv ( "BASEDIR" ); - CrtPath = WdkBase + "\\lib\\crt\\i386"; - DdkPath = WdkBase + "\\lib\\wnet\\i386"; - - fprintf ( OUT, "%s;", CrtPath.c_str() ); - fprintf ( OUT, "%s", DdkPath.c_str() ); - - if (libraries.size () > 0) - fprintf ( OUT, ";" ); - } - - // Add conventional libraries dirs - for (i = 0; i < libraries.size (); i++) - { - if ( i > 0 ) - fprintf ( OUT, ";" ); - - string libpath = libraries[i].c_str(); - libpath.replace (libpath.find("---"), 3, cfg.name); - libpath = libpath.substr (0, libpath.find_last_of ("\\") ); - fprintf ( OUT, "%s", libpath.c_str() ); - } - - fprintf ( OUT, "\"\r\n" ); - - fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() ); - fprintf ( OUT, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 ); - fprintf ( OUT, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" ); - fprintf ( OUT, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 0 : 0); // whole program optimization - - if ( debug ) - fprintf ( OUT, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module.name.c_str() ); - - if ( sys ) - { - if (module.GetEntryPoint() == "0") - fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /noentry /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" ); - else - fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" ); - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 ); - fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 ); - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint() == "" ? "DriverEntry" : module.GetEntryPoint().c_str ()); - fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x10000" : baseaddr.c_str ()); - } - else if ( exe ) - { - if ( module.type == Kernel ) - { - fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" ); - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 ); - fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 ); - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" ); - fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ()); - } - else if ( module.type == NativeCUI ) - { - fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" ); - fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 ); - fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" ); - fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ()); - } - else if ( module.type == Win32CUI || module.type == Win32GUI || module.type == Win32SCR) - { - if ( use_msvcrt_lib ) - { - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - } - fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", console ? 1 : 2 ); - } - } - else if ( dll ) - { - if (module.GetEntryPoint() == "0") - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" ); - else - { - // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12 - // when using CRT - if (module.GetEntryPoint() == "DllMain@12") - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" ); - else - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint().c_str ()); - } - fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x40000" : baseaddr.c_str ()); - if ( use_msvcrt_lib ) - { - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - } - } - fprintf ( OUT, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 ); - } - - fprintf ( OUT, "\t\t\t\r\n " ); - - fprintf ( OUT, "\t\t\t\r\n" ); - if (configuration.VSProjectVersion == "8.00") - { - fprintf ( OUT, "\t\t\t\r\n" ); - } - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\r\n" ); - - n++; } fprintf ( OUT, "\t\r\n" ); + // Write out the project files fprintf ( OUT, "\t\r\n" ); // Source files @@ -825,6 +442,7 @@ MSVCBackend::_generate_vcproj ( const Module& module ) fprintf ( OUT, "\r\n" ); fclose ( OUT ); +#if 0 /* User configuration file */ if (vcproj_file_user != "") { @@ -881,9 +499,511 @@ MSVCBackend::_generate_vcproj ( const Module& module ) fprintf ( OUT, "\r\n" ); fclose ( OUT ); } - +#endif } +void MSVCBackend::_generate_standard_configuration( FILE* OUT, + const Module& module, + const MSVCConfiguration& cfg, + BinaryType binaryType ) +{ + string path_basedir = module.GetPathToBaseDir (); + string intenv = Environment::GetIntermediatePath (); + string outenv = Environment::GetOutputPath (); + string outdir; + string intdir; + string vcdir; + + bool debug = ( cfg.optimization == Debug ); + bool release = ( cfg.optimization == Release ); + bool speed = ( cfg.optimization == Speed ); + + bool include_idl = false; + string include_string; + + size_t i; + string intermediatedir = ""; + string importLib; + // don't do the work m_configurations.size() times + if (module.importLibrary != NULL) + { + intermediatedir = module.output->relative_path + vcdir; + importLib = _strip_gcc_deffile(module.importLibrary->source->name, module.importLibrary->source->relative_path, intermediatedir); + importLib = Path::RelativeFromDirectory ( + importLib, + module.output->relative_path ); + } + + string module_type = GetExtension(*module.output); + + // Set the configuration type for this config + ConfigurationType CfgType; + if ( binaryType == Exe ) + CfgType = ConfigApp; + else if ( binaryType == Lib ) + CfgType = ConfigLib; + else if ( binaryType == Dll || binaryType == Sys ) + CfgType = ConfigDll; + else + CfgType = ConfigUnknown; + + + if ( intenv == "obj-i386" ) + intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ + else + intdir = intenv; + + if ( outenv == "output-i386" ) + outdir = path_basedir + "output-i386"; + else + outdir = outenv; + + if ( configuration.UseVSVersionInPath ) + { + vcdir = DEF_SSEP + _get_vc_dir(); + } + + fprintf ( OUT, "\t\trelative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); + } + else + { + fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); + } + + fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", CfgType ); + fprintf ( OUT, "\t\t\tCharacterSet=\"2\"\r\n" ); + fprintf ( OUT, "\t\t\t>\r\n" ); + + fprintf ( OUT, "\t\t\t 0 ) + fprintf ( OUT, ";" ); + + string unescaped = *it1; + fprintf ( OUT, "%s", _replace_str(unescaped, "\"","").c_str() ); + } + fprintf ( OUT, "\"\r\n" ); + fprintf ( OUT, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h"); + fprintf ( OUT, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed ? "TRUE" : "FALSE" ); + fprintf ( OUT, "\t\t\t\tBasicRuntimeChecks=\"0\"\r\n" ); + fprintf ( OUT, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug ? 3 : 2 ); // 3=/MDd 2=/MD + fprintf ( OUT, "\t\t\t\tBufferSecurityCheck=\"FALSE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" ); + + if ( module.pch != NULL ) + { + fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" ); + string pch_path = Path::RelativeFromDirectory ( + module.pch->file->name, + module.output->relative_path ); + string::size_type pos = pch_path.find_last_of ("/"); + if ( pos != string::npos ) + pch_path.erase(0, pos+1); + fprintf ( OUT, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path.c_str() ); + + // Only include from the same module + pos = pch_path.find("../"); + if (pos == string::npos && std::find(header_files.begin(), header_files.end(), pch_path) == header_files.end()) + header_files.push_back(pch_path); + } + else + { + fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" ); + } + + fprintf ( OUT, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release ? "FALSE" : "FALSE"); + if ( release ) + { + fprintf ( OUT, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" ); + fprintf ( OUT, "\t\t\t\tStringPooling=\"true\"\r\n" ); + } + + fprintf ( OUT, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed ? "0" : "3" ); + fprintf ( OUT, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE"); + if ( !module.cplusplus ) + fprintf ( OUT, "\t\t\t\tCompileAs=\"1\"\r\n" ); + + if ( module.type == Win32CUI || module.type == Win32GUI ) + { + fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 ); // 0=__cdecl + } + else + { + fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 ); // 2=__stdcall + } + + fprintf ( OUT, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed ? "0" : release ? "3": "4"); // 3=/Zi 4=ZI + + fprintf ( OUT, "\t\t\t\r\n" ); + + if ( binaryType == Lib ) + { + fprintf ( OUT, "\t\t\t\r\n", module.name.c_str() ); + } + else + { + fprintf ( OUT, "\t\t\t 0 ) + fprintf ( OUT, " " ); + string libpath = libraries[i].c_str(); + libpath = libpath.erase (0, libpath.find_last_of ("\\") + 1 ); + if ( libpath == "msvcrt.lib" ) + { + use_msvcrt_lib = true; + } + fprintf ( OUT, "%s", libpath.c_str() ); + } + fprintf ( OUT, "\"\r\n" ); + + fprintf ( OUT, "\t\t\t\tAdditionalLibraryDirectories=\"" ); + + // Add WDK libs paths, if needed + if (getenv ( "BASEDIR" ) != NULL && + (module.type == Kernel || + module.type == KernelModeDLL || + module.type == KernelModeDriver || + module.type == KeyboardLayout)) + { + string WdkBase, CrtPath, DdkPath; + WdkBase = getenv ( "BASEDIR" ); + CrtPath = WdkBase + "\\lib\\crt\\i386"; + DdkPath = WdkBase + "\\lib\\wnet\\i386"; + + fprintf ( OUT, "%s;", CrtPath.c_str() ); + fprintf ( OUT, "%s", DdkPath.c_str() ); + + if (libraries.size () > 0) + fprintf ( OUT, ";" ); + } + + // Add conventional libraries dirs + for (i = 0; i < libraries.size (); i++) + { + if ( i > 0 ) + fprintf ( OUT, ";" ); + + string libpath = libraries[i].c_str(); + libpath.replace (libpath.find("---"), 3, cfg.name); + libpath = libpath.substr (0, libpath.find_last_of ("\\") ); + fprintf ( OUT, "%s", libpath.c_str() ); + } + + fprintf ( OUT, "\"\r\n" ); + + fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() ); + fprintf ( OUT, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 ); + fprintf ( OUT, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" ); + fprintf ( OUT, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 0 : 0); // whole program optimization + + if ( debug ) + fprintf ( OUT, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module.name.c_str() ); + + if ( binaryType == Sys ) + { + if (module.GetEntryPoint() == "0") + fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /noentry /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" ); + else + fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" ); + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 ); + fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 ); + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint() == "" ? "DriverEntry" : module.GetEntryPoint().c_str ()); + fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x10000" : baseaddr.c_str ()); + } + else if ( binaryType == Exe ) + { + if ( module.type == Kernel ) + { + fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" ); + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 ); + fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 ); + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" ); + fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ()); + } + else if ( module.type == NativeCUI ) + { + fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" ); + fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 ); + fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" ); + fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ()); + } + else if ( module.type == Win32CUI || module.type == Win32GUI || module.type == Win32SCR) + { + if ( use_msvcrt_lib ) + { + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + } + fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 2 ); + } + } + else if ( binaryType == Dll ) + { + if (module.GetEntryPoint() == "0") + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" ); + else + { + // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12 + // when using CRT + if (module.GetEntryPoint() == "DllMain@12") + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" ); + else + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint().c_str ()); + } + fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x40000" : baseaddr.c_str ()); + if ( use_msvcrt_lib ) + { + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + } + } + fprintf ( OUT, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 ); + } + + fprintf ( OUT, "\t\t\t\r\n " ); + + fprintf ( OUT, "\t\t\t\r\n" ); + if (configuration.VSProjectVersion == "8.00") + { + fprintf ( OUT, "\t\t\t\r\n" ); + } + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); +} + + +void +MSVCBackend::_generate_makefile_configuration( FILE* OUT, const Module& module, const MSVCConfiguration& cfg ) +{ + string path_basedir = module.GetPathToBaseDir (); + string intenv = Environment::GetIntermediatePath (); + string outenv = Environment::GetOutputPath (); + + string outdir; + string intdir; + string vcdir; + + + if ( intenv == "obj-i386" ) + intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ + else + intdir = intenv; + + if ( outenv == "output-i386" ) + outdir = path_basedir + "output-i386"; + else + outdir = outenv; + + if ( configuration.UseVSVersionInPath ) + { + vcdir = DEF_SSEP + _get_vc_dir(); + } + + fprintf ( OUT, "\t\trelative_path.c_str (), cfg.name.c_str() ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), cfg.name.c_str() ); + } + else + { + fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str () ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str () ); + } + + fprintf ( OUT, "\t\t\tConfigurationType=\"0\"\r\n"); + fprintf ( OUT, "\t\t\t>\r\n" ); + + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); +} + + std::string MSVCBackend::_strip_gcc_deffile(std::string Filename, std::string sourcedir, std::string objdir) { @@ -969,6 +1089,9 @@ MSVCBackend::_get_solution_version ( void ) else if (configuration.VSProjectVersion == "9.00") version = "10.00"; + else if (configuration.VSProjectVersion == "10.00") + version = "11.00"; + return version; } @@ -992,6 +1115,9 @@ MSVCBackend::_get_studio_version ( void ) else if (configuration.VSProjectVersion == "9.00") version = "2008"; + else if (configuration.VSProjectVersion == "10.00") + version = "2010"; + return version; } @@ -1037,11 +1163,12 @@ void MSVCBackend::_generate_sln_footer ( FILE* OUT ) { fprintf ( OUT, "Global\r\n" ); - fprintf ( OUT, "\tGlobalSection(SolutionConfiguration) = preSolution\r\n" ); + fprintf ( OUT, "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n" ); for ( size_t i = 0; i < m_configurations.size(); i++ ) fprintf ( OUT, "\t\t%s = %s\r\n", m_configurations[i]->name.c_str(), m_configurations[i]->name.c_str() ); fprintf ( OUT, "\tEndGlobalSection\r\n" ); - fprintf ( OUT, "\tGlobalSection(ProjectConfiguration) = postSolution\r\n" ); + + fprintf ( OUT, "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n" ); for( std::map::const_iterator p = ProjectNode.modules.begin(); p != ProjectNode.modules.end(); ++ p ) { Module& module = *p->second; @@ -1049,18 +1176,18 @@ MSVCBackend::_generate_sln_footer ( FILE* OUT ) _generate_sln_configurations ( OUT, guid.c_str() ); } fprintf ( OUT, "\tEndGlobalSection\r\n" ); +/* fprintf ( OUT, "\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n" ); fprintf ( OUT, "\tEndGlobalSection\r\n" ); fprintf ( OUT, "\tGlobalSection(ExtensibilityAddIns) = postSolution\r\n" ); fprintf ( OUT, "\tEndGlobalSection\r\n" ); - +*/ if (configuration.VSProjectVersion == "7.00") { fprintf ( OUT, "\tGlobalSection(ProjectDependencies) = postSolution\r\n" ); //FIXME: Add dependencies for VS 2002 fprintf ( OUT, "\tEndGlobalSection\r\n" ); } - - if (configuration.VSProjectVersion == "8.00") { + else { fprintf ( OUT, "\tGlobalSection(SolutionProperties) = preSolution\r\n" ); fprintf ( OUT, "\t\tHideSolutionNode = FALSE\r\n" ); fprintf ( OUT, "\tEndGlobalSection\r\n" ); diff --git a/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp new file mode 100644 index 00000000000..c8d9fc03eb1 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2009 Ged Murphy + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "msvc.h" + +using std::string; +using std::vector; +using std::set; + +typedef set StringSet; + +#ifdef OUT +#undef OUT +#endif//OUT + +void +MSVCBackend::_generate_vcxproj ( const Module& module ) +{ + size_t i; + + string vcproj_file = VcprojFileName(module); + string computername; + string username; + string intermediatedir = ""; + + if (getenv ( "USERNAME" ) != NULL) + username = getenv ( "USERNAME" ); + if (getenv ( "COMPUTERNAME" ) != NULL) + computername = getenv ( "COMPUTERNAME" ); + else if (getenv ( "HOSTNAME" ) != NULL) + computername = getenv ( "HOSTNAME" ); + + printf ( "Creating MSVC project: '%s'\n", vcproj_file.c_str() ); + FILE* OUT = fopen ( vcproj_file.c_str(), "wb" ); + + string path_basedir = module.GetPathToBaseDir (); + string intenv = Environment::GetIntermediatePath (); + string outenv = Environment::GetOutputPath (); + string outdir; + string intdir; + string vcdir; + + if ( intenv == "obj-i386" ) + intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ + else + intdir = intenv; + + if ( outenv == "output-i386" ) + outdir = path_basedir + "output-i386"; + else + outdir = outenv; + + if ( configuration.UseVSVersionInPath ) + { + vcdir = DEF_SSEP + _get_vc_dir(); + } + + + + bool include_idl = false; + + vector source_files, resource_files; + vector ifs_list; + ifs_list.push_back ( &module.project.non_if_data ); + ifs_list.push_back ( &module.non_if_data ); + + while ( ifs_list.size() ) + { + const IfableData& data = *ifs_list.back(); + ifs_list.pop_back(); + const vector& files = data.files; + for ( i = 0; i < files.size(); i++ ) + { + if (files[i]->file.directory != SourceDirectory) + continue; + + // We want the full path here for directory support later on + string path = Path::RelativeFromDirectory ( + files[i]->file.relative_path, + module.output->relative_path ); + string file = path + std::string("\\") + files[i]->file.name; + + if ( !stricmp ( Right(file,3).c_str(), ".rc" ) ) + resource_files.push_back ( file ); + else if ( !stricmp ( Right(file,2).c_str(), ".h" ) ) + header_files.push_back ( file ); + else + source_files.push_back ( file ); + } + const vector& incs = data.includes; + for ( i = 0; i < incs.size(); i++ ) + { + string path = Path::RelativeFromDirectory ( + incs[i]->directory->relative_path, + module.output->relative_path ); + if ( module.type != RpcServer && module.type != RpcClient ) + { + if ( path.find ("/include/reactos/idl") != string::npos) + { + include_idl = true; + continue; + } + } + // switch between general headers and ros headers + if ( !strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 ) || + !strncmp(incs[i]->directory->relative_path.c_str(), "include\\ddk", 11 ) || + !strncmp(incs[i]->directory->relative_path.c_str(), "include\\GL", 10 ) || + !strncmp(incs[i]->directory->relative_path.c_str(), "include\\psdk", 12 ) || + !strncmp(incs[i]->directory->relative_path.c_str(), "include\\reactos\\wine", 20 ) ) + { + if (strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 )) + // not crt include + includes_ros.push_back ( path ); + } + else + { + includes.push_back ( path ); + } + } + const vector& libs = data.libraries; + for ( i = 0; i < libs.size(); i++ ) + { + string libpath = outdir + "\\" + libs[i]->importedModule->output->relative_path + "\\" + _get_vc_dir() + "\\---\\" + libs[i]->name + ".lib"; + libraries.push_back ( libpath ); + } + const vector& defs = data.defines; + for ( i = 0; i < defs.size(); i++ ) + { + if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) + continue; + + if ( defs[i]->value[0] ) + common_defines.insert( defs[i]->name + "=" + defs[i]->value ); + else + common_defines.insert( defs[i]->name ); + } + for ( std::map::const_iterator p = data.properties.begin(); p != data.properties.end(); ++ p ) + { + Property& prop = *p->second; + if ( strstr ( module.baseaddress.c_str(), prop.name.c_str() ) ) + baseaddr = prop.value; + } + } + /* include intermediate path for reactos.rc */ + string version = intdir + "\\include"; + includes.push_back (version); + version += "\\reactos"; + includes.push_back (version); + + string include_string; + + fprintf ( OUT, "\r\n" ); +} diff --git a/reactos/tools/rbuild/rbuild.mak b/reactos/tools/rbuild/rbuild.mak index 1a393649964..c05e9e17ffc 100644 --- a/reactos/tools/rbuild/rbuild.mak +++ b/reactos/tools/rbuild/rbuild.mak @@ -229,6 +229,7 @@ RBUILD_BACKEND_MSVC_BASE_SOURCES = $(addprefix $(RBUILD_MSVC_BASE_), \ msvc.cpp \ msvcmaker.cpp \ vcprojmaker.cpp \ + vcxprojmaker.cpp \ ) RBUILD_BACKEND_SOURCES = \ @@ -530,6 +531,10 @@ $(RBUILD_MSVC_INT_)vcprojmaker.o: $(RBUILD_MSVC_BASE_)vcprojmaker.cpp $(RBUILD_H $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ +$(RBUILD_MSVC_INT_)vcxprojmaker.o: $(RBUILD_MSVC_BASE_)vcxprojmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) + $(ECHO_HOSTCC) + ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ + $(RBUILD_TEST_TARGET): $(RBUILD_TEST_OBJECTS) $(INFLIB_HOST_OBJECTS) $(RBUILD_HEADERS) | $(RBUILD_OUT) $(ECHO_HOSTLD) ${host_gpp} $(RBUILD_TEST_OBJECTS) $(INFLIB_HOST_OBJECTS) $(RBUILD_HOST_LFLAGS) -o $@ diff --git a/reactos/tools/rbuild/rbuild.sln b/reactos/tools/rbuild/rbuild.sln index 0f9164398e8..01a7baa7830 100644 --- a/reactos/tools/rbuild/rbuild.sln +++ b/reactos/tools/rbuild/rbuild.sln @@ -1,5 +1,5 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rbuild", "rbuild.vcproj", "{D9305AFB-499E-49F1-A865-99DD7E19E762}" EndProject Global diff --git a/reactos/tools/rbuild/rbuild.vcproj b/reactos/tools/rbuild/rbuild.vcproj index 1e800a44b9d..59f90ad1a8a 100644 --- a/reactos/tools/rbuild/rbuild.vcproj +++ b/reactos/tools/rbuild/rbuild.vcproj @@ -1,10 +1,11 @@ - @@ -166,6 +166,8 @@ GenerateDebugInformation="true" ProgramDatabaseFile=".\Debug/rbuild.pdb" SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" TargetMachine="1" /> - @@ -335,6 +334,10 @@ /> + +