From de233c67ef52bdc3d08d4ab18c2b4f325fa9f453 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Wed, 10 Feb 2010 21:55:51 +0000 Subject: [PATCH] [rbuild] - Major improvements in the msvc backend - Create a .vsprops file for every configuration in the root folder. This lets us make vcproj files a lot smaller - When building with our headers actually use all of our headers and not a mix of our sdks and the headers of the crt that comes with msvc - Add a rule to build .s files based on the idea by jcatena - Add a rule for .spec and .pspec files. pspec doesn't work well yet - Various fixes - Please note the the above are aplied only to the vcproj files and not to the vcxrpoj files The above let us compile large parts of trunk with the generated visual studio projects svn path=/trunk/; revision=45564 --- .../rbuild/backend/mingw/modulehandler.cpp | 23 +- .../rbuild/backend/mingw/modulehandler.h | 7 - reactos/tools/rbuild/backend/msvc/msvc.cpp | 23 +- reactos/tools/rbuild/backend/msvc/msvc.h | 31 ++ .../rbuild/backend/msvc/s_as_mscpp.rules | 44 ++ reactos/tools/rbuild/backend/msvc/spec.rules | 57 +++ .../tools/rbuild/backend/msvc/vcprojmaker.cpp | 433 ++++++------------ .../rbuild/backend/msvc/vspropsmaker.cpp | 274 +++++++++++ reactos/tools/rbuild/module.cpp | 18 + reactos/tools/rbuild/project.cpp | 8 + reactos/tools/rbuild/rbuild.cpp | 5 + reactos/tools/rbuild/rbuild.h | 9 + reactos/tools/rbuild/rbuild.mak | 7 +- reactos/tools/rbuild/rbuild.vcproj | 6 +- 14 files changed, 624 insertions(+), 321 deletions(-) create mode 100644 reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules create mode 100644 reactos/tools/rbuild/backend/msvc/spec.rules create mode 100644 reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp index a372a71b24e..8bff6ea0b16 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp @@ -1021,7 +1021,7 @@ MingwModuleHandler::GenerateObjectMacros ( } CleanupCompilationUnitVector ( sourceCompilationUnits ); - if ( IsSpecDefinitionFile() ) + if ( module.IsSpecDefinitionFile() ) { const FileLocation *stubs_file = new FileLocation( IntermediateDirectory, @@ -1820,7 +1820,7 @@ MingwModuleHandler::GenerateRules () } - spec = IsSpecDefinitionFile(); + spec = module.IsSpecDefinitionFile(); if(spec) { @@ -1979,23 +1979,6 @@ MingwModuleHandler::GeneratePreconditionDependencies () fprintf ( fMakefile, "\n" ); } -SpecFileType -MingwModuleHandler::IsSpecDefinitionFile () const -{ - if(!module.importLibrary) - return None; - - std::string ext = GetExtension ( *module.importLibrary->source ); - - if ( ext == ".spec" ) - return Spec; - - if ( ext == ".pspec" ) - return PSpec; - - return None; -} - /* caller needs to delete the returned object */ const FileLocation* MingwModuleHandler::GetDefinitionFilename () const @@ -2003,7 +1986,7 @@ MingwModuleHandler::GetDefinitionFilename () const if ( module.importLibrary == NULL ) return NULL; - if ( IsSpecDefinitionFile () ) + if ( module.IsSpecDefinitionFile () ) { return new FileLocation ( IntermediateDirectory, module.importLibrary->source->relative_path, diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.h b/reactos/tools/rbuild/backend/mingw/modulehandler.h index b0687177d9a..797f075812a 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.h +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.h @@ -32,13 +32,6 @@ PrefixFilename ( const std::string& filename, const std::string& prefix ); -enum SpecFileType -{ - None, - Spec = 1, - PSpec = 2 -}; - class MingwModuleHandler { public: diff --git a/reactos/tools/rbuild/backend/msvc/msvc.cpp b/reactos/tools/rbuild/backend/msvc/msvc.cpp index 90aa37c0ddc..8991147a61a 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.cpp +++ b/reactos/tools/rbuild/backend/msvc/msvc.cpp @@ -83,7 +83,6 @@ MSVCBackend::MSVCBackend(Project &project, void MSVCBackend::Process() { - // TODO FIXME wine hack? bool only_msvc_headers = false; while ( m_configurations.size () > 0 ) @@ -95,14 +94,14 @@ 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( Speed )); m_configurations.push_back ( new MSVCConfiguration( RosBuild )); if (!only_msvc_headers) { m_configurations.push_back ( new MSVCConfiguration( Debug, ReactOSHeaders )); m_configurations.push_back ( new MSVCConfiguration( Release, ReactOSHeaders )); - m_configurations.push_back ( new MSVCConfiguration( Speed, ReactOSHeaders )); +// m_configurations.push_back ( new MSVCConfiguration( Speed, ReactOSHeaders )); } if ( configuration.CleanAsYouGo ) { @@ -118,6 +117,22 @@ void MSVCBackend::Process() filename_sln += "_auto.sln"; printf ( "Creating MSVC workspace: %s\n", filename_sln.c_str() ); + //Write a property page for each configuration + for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) + { + MSVCConfiguration* cfg = m_configurations[icfg]; + + //RosBuild doesn't need a property page + if(cfg->optimization == RosBuild) + continue; + + string filename_props( cfg->name ); + filename_props += ".vsprops"; + //Write the propery pages files + PropsMaker propsMaker( configuration, &ProjectNode, filename_props, cfg ); + propsMaker._generate_props( _get_solution_version(), _get_studio_version() ); + } + // Write out the project files ProcessModules(); @@ -376,7 +391,7 @@ MSVCBackend::_get_object_files ( const Module& module, vector& out) cons void MSVCBackend::_get_def_files ( const Module& module, vector& out) const { - if (module.HasImportLibrary ()) + if (module.HasImportLibrary()) { #if 0 string modulename = module.GetBasePath (); diff --git a/reactos/tools/rbuild/backend/msvc/msvc.h b/reactos/tools/rbuild/backend/msvc/msvc.h index fde4b81657e..4be80c64c99 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.h +++ b/reactos/tools/rbuild/backend/msvc/msvc.h @@ -179,6 +179,7 @@ class VCProjMaker : public ProjMaker private: void _generate_standard_configuration( const Module& module, const MSVCConfiguration& cfg, BinaryType binaryType ); void _generate_makefile_configuration( const Module& module, const MSVCConfiguration& cfg ); + std::string _get_file_path( FileLocation* file, std::string relative_path); }; class VCXProjMaker : public ProjMaker @@ -222,4 +223,34 @@ class SlnMaker void _generate_sln_configurations ( std::string vcproj_guid ); }; +class PropsMaker +{ + public: + PropsMaker ( Configuration& buildConfig, + Project* ProjectNode, + std::string filename_props, + MSVCConfiguration* msvc_configs); + + ~PropsMaker (); + + void _generate_props ( std::string solution_version, std::string studio_version ); + + private: + Configuration m_configuration; + Project* m_ProjectNode; + FILE* OUT; + MSVCConfiguration* m_msvc_config; + bool debug; + bool release; + bool speed; + bool use_ros_headers; + + void _generate_header(); + void _generate_tools_defaults(); + void _generate_macro(std::string Name, std::string Value, bool EvairomentVariable); + void _generate_global_includes(); + void _generate_global_definitions(); + void _generate_footer(); + +}; #endif // __MSVC_H__ diff --git a/reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules b/reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules new file mode 100644 index 00000000000..d61a5247496 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules @@ -0,0 +1,44 @@ + + + + + + + + + + + + + diff --git a/reactos/tools/rbuild/backend/msvc/spec.rules b/reactos/tools/rbuild/backend/msvc/spec.rules new file mode 100644 index 00000000000..7aa12cb2598 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/spec.rules @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index 36a37380265..582601b3a77 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -80,6 +80,28 @@ VCProjMaker::~VCProjMaker() fclose ( OUT ); } +std::string +VCProjMaker::_get_file_path( FileLocation* file, std::string relative_path) +{ + if (file->directory == SourceDirectory) + { + // We want the full path here for directory support later on + return Path::RelativeFromDirectory (file->relative_path, relative_path ); + } + else if(file->directory == IntermediateDirectory) + { + return std::string("$(obj)\\") + file->relative_path; + } + else if(file->directory == OutputDirectory) + { + return std::string("$(out)\\") + file->relative_path; + } + + return std::string(""); +} + + + void VCProjMaker::_generate_proj_file ( const Module& module ) { @@ -91,7 +113,6 @@ VCProjMaker::_generate_proj_file ( const Module& module ) // make sure the containers are empty header_files.clear(); includes.clear(); - includes_ros.clear(); libraries.clear(); common_defines.clear(); @@ -110,21 +131,8 @@ VCProjMaker::_generate_proj_file ( const Module& module ) printf ( "Creating MSVC project: '%s'\n", vcproj_file.c_str() ); 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 ) { @@ -135,93 +143,65 @@ VCProjMaker::_generate_proj_file ( const Module& module ) 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 = module.non_if_data/**ifs_list.back()*/; + const vector& files = data.files; + for ( i = 0; i < files.size(); i++ ) { - 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; + string path = _get_file_path(&files[i]->file, module.output->relative_path); + string file = path + std::string("\\") + files[i]->file.name; - // 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; - } + 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 ); } - /* include intermediate path for reactos.rc */ - string version = intdir + "\\include"; - includes.push_back (version); - version += "\\reactos"; - includes.push_back (version); + const vector& incs = data.includes; + for ( i = 0; i < incs.size(); i++ ) + { + string path = _get_file_path(incs[i]->directory, module.output->relative_path); - string include_string; + if ( module.type != RpcServer && module.type != RpcClient ) + { + if ( path.find ("/include/reactos/idl") != string::npos) + { + include_idl = true; + continue; + } + } + includes.push_back ( path ); + } + const vector& libs = data.libraries; + for ( i = 0; i < libs.size(); i++ ) + { + string libpath = "$(out)\\" + libs[i]->importedModule->output->relative_path + "\\" + _get_vc_dir() + "\\$(ConfigurationName)\\" + 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; + } + + if(module.IsSpecDefinitionFile()) + { + std::string path = _get_file_path(module.importLibrary->source, module.output->relative_path); + source_files.push_back ( path + std::string("\\") + module.importLibrary->source->name ); + } fprintf ( OUT, "\r\n" ); fprintf ( OUT, "\r\n" ); fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); + fprintf ( OUT, "\t\r\n" ); + // Set the binary type string module_type = GetExtension(*module.output); BinaryType binaryType; @@ -335,21 +324,8 @@ VCProjMaker::_generate_proj_file ( const Module& module ) { const MSVCConfiguration& config = *m_configurations[iconfig]; - if (( isrcfile == 0 ) && ( module.pch != NULL )) - { - /* little hack to speed up PCH */ - fprintf ( OUT, "%s\t\r\n" ); - fprintf ( OUT, "%s\t\t\r\n", indent_tab.c_str() ); - fprintf ( OUT, "%s\t\r\n", indent_tab.c_str() ); - } - //if (configuration.VSProjectVersion < "8.00") { - if ((source_file.find(".idl") != string::npos) || ((source_file.find(".asm") != string::npos || tolower(source_file.at(source_file.size() - 1)) == 's'))) + if ((source_file.find(".idl") != string::npos) || ((source_file.find(".asm") != string::npos))) { fprintf ( OUT, "%s\t\r\n", indent_tab.c_str() ); } - else if ((tolower(source_file.at(source_file.size() - 1)) == 's')) - { - fprintf ( OUT, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab.c_str() ); - fprintf ( OUT, "%s\t\t\tCommandLine=\"cl /E "$(InputPath)" %s /D__ASM__ | as -o "$(OutDir)\\$(InputName).obj"\"\r\n", indent_tab.c_str(), include_string.c_str() ); - fprintf ( OUT, "%s\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n", indent_tab.c_str() ); - } fprintf ( OUT, "%s\t\r\n", indent_tab.c_str() ); } //} @@ -452,24 +422,19 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, 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) + + if(module.IsSpecDefinitionFile()) + { + importLib = "$(IntDir)\\$(ProjectName).def"; + } + else if (module.importLibrary != NULL) { intermediatedir = module.output->relative_path + vcdir; importLib = _strip_gcc_deffile(module.importLibrary->source->name, module.importLibrary->source->relative_path, intermediatedir); @@ -491,17 +456,6 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, 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(); @@ -512,23 +466,58 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, if ( configuration.UseConfigurationInPath ) { - fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\\%s\"\r\n", outdir.c_str (), module.output->relative_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() ); + fprintf ( OUT, "\t\t\tOutputDirectory=\"$(out)\\%s%s\\$(ConfigurationName)\"\r\n", module.output->relative_path.c_str (), vcdir.c_str () ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"$(obj)\\%s%s\\$(ConfigurationName)\"\r\n", module.output->relative_path.c_str (), vcdir.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\tOutputDirectory=\"$(out)\\%s%s\"\r\n", module.output->relative_path.c_str (), vcdir.c_str () ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"$(obj)\\%s%s\"\r\n", module.output->relative_path.c_str (), vcdir.c_str () ); } fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", CfgType ); + + fprintf ( OUT, "\t\t\tInheritedPropertySheets=\"%s%s.vsprops\"\r\n", path_basedir.c_str (), cfg.name.c_str ()); fprintf ( OUT, "\t\t\tCharacterSet=\"2\"\r\n" ); fprintf ( OUT, "\t\t\t>\r\n" ); fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\tOptimization=\"%d\"\r\n", release ? 2 : 0 ); + 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, "%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" ); + //disable precompiled headers for now +#if 0 if ( module.pch != NULL ) { fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" ); @@ -657,44 +588,17 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, 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" ); - } +#endif - 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" ); - } + if ( module.cplusplus ) + fprintf ( OUT, "\t\t\t\tCompileAs=\"2\"\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"); fprintf ( OUT, "\t\t\t\r\n" ); - if ( binaryType == Lib ) - { - fprintf ( OUT, "\t\t\t\r\n", module.name.c_str() ); - } - else + if ( binaryType != Lib ) { fprintf ( OUT, "\t\t\t 0) - fprintf ( OUT, ";" ); - } - // Add conventional libraries dirs for (i = 0; i < libraries.size (); i++) { @@ -754,7 +639,6 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, 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() ); } @@ -762,13 +646,6 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, 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") @@ -831,7 +708,7 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, 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 " ); 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" ); } diff --git a/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp b/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp new file mode 100644 index 00000000000..bd0733919df --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp @@ -0,0 +1,274 @@ +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#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 + +PropsMaker::PropsMaker ( Configuration& buildConfig, + Project* ProjectNode, + std::string filename_props, + MSVCConfiguration* msvc_configs) +{ + m_configuration = buildConfig; + m_ProjectNode = ProjectNode; + + m_msvc_config = msvc_configs; + + debug = ( m_msvc_config->optimization == Debug ); + release = ( m_msvc_config->optimization == Release ); + speed = ( m_msvc_config->optimization == Speed ); + use_ros_headers = (m_msvc_config->headers == ReactOSHeaders); + + OUT = fopen ( filename_props.c_str(), "wb" ); + + if ( !OUT ) + { + printf ( "Could not create file '%s'.\n", filename_props.c_str() ); + } +} + +PropsMaker::~PropsMaker ( ) +{ + fclose ( OUT ); +} + +void +PropsMaker::_generate_header() +{ + fprintf ( OUT, "\r\n" ); + fprintf ( OUT, "\r\n", m_msvc_config->name.c_str() ); +} + +void +PropsMaker::_generate_tools_defaults() +{ + fprintf ( OUT, "\t\r\n"); + + //Linker + fprintf ( OUT, "\t\r\n"); + + //Librarian + fprintf ( OUT, "\t\r\n"); + + //Resource compiler + fprintf ( OUT, "\t\t\t\r\n"); +} + +void +PropsMaker::_generate_macro(std::string Name, + std::string Value, + bool EvairomentVariable) +{ + fprintf ( OUT, "\t\r\n"); +} + +void +PropsMaker::_generate_global_includes() +{ + //Generate global includes + //they will be used by the c compiler, the resource compiler + //and the preprocessor for .s and .pspec files + + fprintf ( OUT, "\tnon_if_data; + //const vector& files = data.files; + size_t i; + const vector& incs = data.includes; + for ( i = 0; i < incs.size(); i++ ) + { + 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 )) && + ! use_ros_headers) + { + continue; + } + + if(incs[i]->directory->directory == SourceDirectory) + fprintf ( OUT, ""$(src)\\"); + else if (incs[i]->directory->directory == IntermediateDirectory) + fprintf ( OUT, ""$(obj)\\"); + else if (incs[i]->directory->directory == OutputDirectory) + fprintf ( OUT, ""$(out)\\"); + else + continue; + + fprintf ( OUT, incs[i]->directory->relative_path.c_str()); + fprintf ( OUT, "" ; "); + } + + fprintf ( OUT, ""$(obj)\\include" ; "); + fprintf ( OUT, ""$(obj)\\include\\reactos" ; "); + + if ( !use_ros_headers ) + { + // Add WDK or PSDK paths, if user provides them + if (getenv ( "BASEDIR" ) != NULL) + { + string WdkBase = getenv ( "BASEDIR" ); + fprintf ( OUT, ""%s\\inc\\api" ; ", WdkBase.c_str()); + fprintf ( OUT, ""%s\\inc\\crt" ; ", WdkBase.c_str()); + fprintf ( OUT, ""%s\\inc\\ddk" ; ", WdkBase.c_str()); + } + } + fprintf ( OUT, "\"\r\n"); + fprintf ( OUT, "\t\tPerformEnvironmentSet=\"true\"\r\n"); + fprintf( OUT, "\t/>\r\n"); +} + +void +PropsMaker::_generate_global_definitions() +{ + + string global_defines = ""; + + fprintf ( OUT, "\tnon_if_data; + const vector& defs = data.defines; + size_t i; + + for ( i = 0; i < defs.size(); i++ ) + { + if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) + continue; + + if ( defs[i]->value[0] ) + fprintf ( OUT, "%s=%s",defs[i]->name.c_str(), defs[i]->value.c_str()); + else + fprintf ( OUT, defs[i]->name.c_str()); + fprintf ( OUT, " ; "); + } + + fprintf ( OUT, "\"\r\n"); + fprintf ( OUT, "\t\tPerformEnvironmentSet=\"true\"\r\n"); + fprintf( OUT, "\t/>\r\n"); +} + +void +PropsMaker::_generate_footer() +{ + fprintf ( OUT, "\r\n"); +} + + +void +PropsMaker::_generate_props ( std::string solution_version, + std::string studio_version ) +{ + _generate_header(); + _generate_tools_defaults(); + + string srcdir = Environment::GetSourcePath(); + string intdir = Environment::GetIntermediatePath (); + string outdir = Environment::GetOutputPath (); + string rosbedir = Environment::GetVariable("_ROSBE_BASEDIR"); + + if ( intdir == "obj-i386" ) + intdir = srcdir + "\\obj-i386"; /* append relative dir from project dir */ + + if ( outdir == "output-i386" ) + outdir = srcdir + "\\output-i386"; + + //Generate global macros + _generate_macro("src", srcdir, true); + _generate_macro("out", outdir, true); + _generate_macro("obj", intdir, true); + _generate_macro("Tools", "$(out)\\tools", true); + _generate_macro("RosBE", rosbedir, true); + + _generate_global_includes(); + _generate_global_definitions(); + _generate_footer(); +} diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index df83ee2bb6c..1fdc5d64964 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -1430,6 +1430,24 @@ Module::GetDllName () const throw new InvalidOperationException ( __FILE__, __LINE__, "Module %s has no dllname." ); } +SpecFileType +Module::IsSpecDefinitionFile () const +{ + if(!importLibrary) + return None; + + std::string ext = GetExtension ( *importLibrary->source ); + + if ( ext == ".spec" ) + return Spec; + + if ( ext == ".pspec" ) + return PSpec; + + return None; +} + + File::File ( DirectoryLocation directory, const string& relative_path, const string& name, diff --git a/reactos/tools/rbuild/project.cpp b/reactos/tools/rbuild/project.cpp index 9378e16b22e..894c8dca515 100644 --- a/reactos/tools/rbuild/project.cpp +++ b/reactos/tools/rbuild/project.cpp @@ -63,6 +63,14 @@ Environment::GetIntermediatePath () } /* static */ string +Environment::GetSourcePath () +{ + char temp[_MAX_PATH]; + getcwd(temp, _MAX_PATH); + return string(temp); +} + +string Environment::GetOutputPath () { string defaultOutput = diff --git a/reactos/tools/rbuild/rbuild.cpp b/reactos/tools/rbuild/rbuild.cpp index 1119f22ca0f..dc098a819c4 100644 --- a/reactos/tools/rbuild/rbuild.cpp +++ b/reactos/tools/rbuild/rbuild.cpp @@ -134,6 +134,11 @@ ParseVCProjectSwitch ( if (configuration.VSProjectVersion.length() == 3) //7.1 configuration.VSProjectVersion.append("0"); + //We should set this here because in the end we will use + //msc sompiler so we need to parse msc specidic + //definitions and includes + configuration.Compiler = MicrosoftC; + break; case 'c': configuration.VSConfigurationType = string (&switchStart[3]); diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h index 510203b068f..3635cea4d43 100644 --- a/reactos/tools/rbuild/rbuild.h +++ b/reactos/tools/rbuild/rbuild.h @@ -167,6 +167,13 @@ enum LinkerSet MicrosoftLink }; +enum SpecFileType +{ + None, + Spec = 1, + PSpec = 2 +}; + class Configuration { public: @@ -197,6 +204,7 @@ public: static std::string GetArch (); static std::string GetIntermediatePath (); static std::string GetOutputPath (); + static std::string GetSourcePath (); static std::string GetCdOutputPath (); static std::string GetInstallPath (); static std::string GetAutomakeFile ( const std::string& defaultFile ); @@ -425,6 +433,7 @@ public: void InvokeModule () const; void ProcessXML (); std::string GetDllName() const; + SpecFileType IsSpecDefinitionFile () const; private: void SetImportLibrary ( ImportLibrary* importLibrary ); void SetDelayImportLibrary ( ImportLibrary* importLibrary ); diff --git a/reactos/tools/rbuild/rbuild.mak b/reactos/tools/rbuild/rbuild.mak index f64e21d2335..1a3138f7d14 100644 --- a/reactos/tools/rbuild/rbuild.mak +++ b/reactos/tools/rbuild/rbuild.mak @@ -209,6 +209,7 @@ RBUILD_BACKEND_MSVC_BASE_SOURCES = $(addprefix $(RBUILD_MSVC_BASE_), \ slnmaker.cpp \ vcprojmaker.cpp \ vcxprojmaker.cpp \ + vspropsmaker.cpp \ ) RBUILD_BACKEND_SOURCES = \ @@ -496,7 +497,11 @@ $(RBUILD_MSVC_INT_)msvc.o: $(RBUILD_MSVC_BASE_)msvc.cpp $(RBUILD_HEADERS) | $(RB $(RBUILD_MSVC_INT_)projmaker.o: $(RBUILD_MSVC_BASE_)projmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ - + +$(RBUILD_MSVC_INT_)vspropsmaker.o: $(RBUILD_MSVC_BASE_)vspropsmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) + $(ECHO_HOSTCC) + ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ + $(RBUILD_MSVC_INT_)slnmaker.o: $(RBUILD_MSVC_BASE_)slnmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ diff --git a/reactos/tools/rbuild/rbuild.vcproj b/reactos/tools/rbuild/rbuild.vcproj index 0d91687b4c3..763850a1804 100644 --- a/reactos/tools/rbuild/rbuild.vcproj +++ b/reactos/tools/rbuild/rbuild.vcproj @@ -1,7 +1,7 @@ + +