diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 23 | ||||
-rw-r--r-- | Source/cmCommands.cxx | 2 | ||||
-rw-r--r-- | Source/cmEnableLanguageCommand.cxx | 30 | ||||
-rw-r--r-- | Source/cmEnableLanguageCommand.h | 84 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 82 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 15 | ||||
-rw-r--r-- | Source/cmInstallFilesCommand.cxx | 2 | ||||
-rw-r--r-- | Source/cmInstallProgramsCommand.cxx | 2 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmLocalUnixMakefileGenerator.cxx | 439 | ||||
-rw-r--r-- | Source/cmLocalUnixMakefileGenerator.h | 5 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio6Generator.cxx | 56 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio7Generator.cxx | 68 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 13 | ||||
-rw-r--r-- | Source/cmProjectCommand.cxx | 2 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 110 | ||||
-rw-r--r-- | Source/cmTarget.h | 15 | ||||
-rw-r--r-- | Source/cmTryCompileCommand.cxx | 63 | ||||
-rw-r--r-- | Source/cmTryRunCommand.cxx | 28 |
19 files changed, 636 insertions, 404 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 56f2abb..08e5c9e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -636,12 +636,13 @@ IF(BUILD_TESTING) ) ENDIF (CTEST_TEST_CTEST) + IF(CMAKE_GENERATOR MATCHES "Makefiles") # see if we can find a fortran compiler on the machine # if so, add the fortran test and see if it works. SET(CMAKE_Fortran_COMPILER_LIST ifort ifc efc f95 pgf95 - lf95 xlf95 fort gfortran f90 pgf90 xlf90 epcf90 f77 - fort77 frt pgf77 xlf fl32 af77 g77 ) + lf95 xlf95 fort gfortran f90 pgf90 xlf90 + epcf90 f77 fort77 frt pgf77 xlf fl32 af77 g77 ) FIND_PROGRAM(CMAKE_Fortran_COMPILER_FULLPATH NAMES ${CMAKE_Fortran_COMPILER_LIST} ) MARK_AS_ADVANCED(CMAKE_Fortran_COMPILER_FULLPATH) IF(CMAKE_Fortran_COMPILER_FULLPATH) @@ -650,13 +651,27 @@ IF(BUILD_TESTING) "${CMake_SOURCE_DIR}/Tests/Fortran" "${CMake_BINARY_DIR}/Tests/Fortran" --build-generator ${CMAKE_GENERATOR} - --build-project Simple + --build-project testf --build-makeprogram ${MAKEPROGRAM} --build-two-config --test-command testf) ENDIF(CMAKE_Fortran_COMPILER_FULLPATH) + + INCLUDE(FindJava) + IF(JAVA_COMPILE) + ADD_TEST(Java ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Java" + "${CMake_BINARY_DIR}/Tests/Java" + --build-generator ${CMAKE_GENERATOR} + --build-project hello + --build-makeprogram ${MAKEPROGRAM} + --build-two-config + --build-run-dir "${CMake_BINARY_DIR}/Tests/Java/" + --test-command ${JAVA_RUNTIME} -classpath hello.jar HelloWorld) + ENDIF(JAVA_COMPILE) ENDIF(CMAKE_GENERATOR MATCHES "Makefiles") - + IF (CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE OR WXWINDOWS_INCLUDE_DIR) # Will be set if the wxwindows gui is on ADD_TEST(UseWX ${CMAKE_CTEST_COMMAND} diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index ebec240..0898b0d 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -80,6 +80,7 @@ #include "cmAbstractFilesCommand.cxx" #include "cmAuxSourceDirectoryCommand.cxx" #include "cmExportLibraryDependencies.cxx" +#include "cmEnableLanguageCommand.cxx" #include "cmFLTKWrapUICommand.cxx" #include "cmGetCMakePropertyCommand.cxx" #include "cmGetDirectoryPropertyCommand.cxx" @@ -171,6 +172,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands) #if defined(CMAKE_BUILD_WITH_CMAKE) commands.push_back(new cmAbstractFilesCommand); commands.push_back(new cmAuxSourceDirectoryCommand); + commands.push_back(new cmEnableLanguageCommand); commands.push_back(new cmExportLibraryDependenciesCommand); commands.push_back(new cmFLTKWrapUICommand); commands.push_back(new cmGetCMakePropertyCommand); diff --git a/Source/cmEnableLanguageCommand.cxx b/Source/cmEnableLanguageCommand.cxx new file mode 100644 index 0000000..8e1845e --- /dev/null +++ b/Source/cmEnableLanguageCommand.cxx @@ -0,0 +1,30 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmEnableLanguageCommand.h" + +// cmEnableLanguageCommand +bool cmEnableLanguageCommand::InitialPass(std::vector<std::string> const& args) +{ + if(args.size() < 1 ) + { + this->SetError("ENABLE_LANGUAGE called with incorrect number of arguments"); + return false; + } + m_Makefile->EnableLanguage(args); + return true; +} + diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h new file mode 100644 index 0000000..2d8106c --- /dev/null +++ b/Source/cmEnableLanguageCommand.h @@ -0,0 +1,84 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmEnableLanguageCommand_h +#define cmEnableLanguageCommand_h + +#include "cmCommand.h" + +/** \class cmEnableLanguageCommand + * \brief Specify the name for this build project. + * + * cmEnableLanguageCommand is used to specify a name for this build project. + * It is defined once per set of CMakeList.txt files (including + * all subdirectories). Currently it just sets the name of the workspace + * file for Microsoft Visual C++ + */ +class cmEnableLanguageCommand : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmEnableLanguageCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector<std::string> const& args); + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() {return "ENABLE_LANGUAGE";} + + /** + * This determines if the command gets propagated down + * to makefiles located in subdirectories. + */ + virtual bool IsInherited() + { + return true; + } + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() + { + return "Set a name for the entire project."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() + { + return + " ENABLE_LANGUAGE(languageName)\n" + " This command enables support for the named language in CMake."; + } + + cmTypeMacro(cmEnableLanguageCommand, cmCommand); +}; + + + +#endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ccff33b..023bccc 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -190,10 +190,10 @@ void cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } needTestLanguage = true; // must test a language after finding it // read determine LANG compiler - std::string determinCompiler = "CMakeDetermine"; - determinCompiler += lang; - determinCompiler += "Compiler.cmake"; - std::string determineFile = mf->GetModulesFile(determinCompiler.c_str()); + std::string determineCompiler = "CMakeDetermine"; + determineCompiler += lang; + determineCompiler += "Compiler.cmake"; + std::string determineFile = mf->GetModulesFile(determineCompiler.c_str()); if(!mf->ReadListFile(0,determineFile.c_str())) { cmSystemTools::Error("Could not find cmake module file:", determineFile.c_str()); @@ -310,8 +310,31 @@ void cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } } +const char* cmGlobalGenerator::GetLanguageOutputExtensionForLanguage(const char* lang) +{ + if(m_LanguageToOutputExtension.count(lang) > 0) + { + return m_LanguageToOutputExtension[lang].c_str(); + } + return ""; +} + +const char* cmGlobalGenerator::GetLanguageOutputExtensionFromExtension(const char* ext) +{ + const char* lang = this->GetLanguageFromExtension(ext); + return this->GetLanguageOutputExtensionForLanguage(lang); +} + + const char* cmGlobalGenerator::GetLanguageFromExtension(const char* ext) { + // if there is an extension and it starts with . then + // move past the . because the extensions are not stored with a . + // in the map + if(ext && *ext == '.') + { + ++ext; + } if(m_ExtensionToLanguage.count(ext) > 0) { return m_ExtensionToLanguage[ext].c_str(); @@ -325,8 +348,28 @@ void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf) { return; } + std::string outputExtensionVar = std::string("CMAKE_") + + std::string(l) + std::string("_OUTPUT_EXTENSION"); + const char* outputExtension = mf->GetDefinition(outputExtensionVar.c_str()); + if(outputExtension) + { + m_LanguageToOutputExtension[l] = outputExtension; + } + + std::string linkerPrefVar = std::string("CMAKE_") + + std::string(l) + std::string("_LINKER_PREFERENCE"); + const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str()); + if(!linkerPref) + { + linkerPref = "None"; + } + m_LanguageToLinkerPreference[l] = linkerPref; + std::string extensionsVar = std::string("CMAKE_") + std::string(l) + std::string("_SOURCE_FILE_EXTENSIONS"); + std::string ignoreExtensionsVar = std::string("CMAKE_") + + std::string(l) + std::string("_IGNORE_EXTENSIONS"); + std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar.c_str()); std::string exts = mf->GetSafeDefinition(extensionsVar.c_str()); std::vector<std::string> extensionList; cmSystemTools::ExpandListArgument(exts, extensionList); @@ -335,10 +378,19 @@ void cmGlobalGenerator::SetLanguageEnabled(const char* l, cmMakefile* mf) { m_ExtensionToLanguage[*i] = l; } - + cmSystemTools::ExpandListArgument(ignoreExts, extensionList); + for(std::vector<std::string>::iterator i = extensionList.begin(); + i != extensionList.end(); ++i) + { + m_IgnoreExtensions[*i] = true; + } m_LanguageEnabled[l] = true; } +bool cmGlobalGenerator::IgnoreFile(const char* l) +{ + return (m_IgnoreExtensions.count(l) > 0); +} bool cmGlobalGenerator::GetLanguageEnabled(const char* l) { @@ -609,6 +661,9 @@ void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen ) // copy the enabled languages this->m_LanguageEnabled = gen->m_LanguageEnabled; this->m_ExtensionToLanguage = gen->m_ExtensionToLanguage; + this->m_IgnoreExtensions = gen->m_IgnoreExtensions; + this->m_LanguageToOutputExtension = gen->m_LanguageToOutputExtension; + this->m_LanguageToLinkerPreference = gen->m_LanguageToLinkerPreference; } //---------------------------------------------------------------------------- @@ -635,3 +690,20 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, } +void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang) +{ + for(std::map<cmStdString, bool>::iterator i = m_LanguageEnabled.begin(); + i != m_LanguageEnabled.end(); ++i) + { + lang.push_back(i->first); + } +} + +const char* cmGlobalGenerator::GetLinkerPreference(const char* lang) +{ + if(m_LanguageToLinkerPreference.count(lang)) + { + return m_LanguageToLinkerPreference[lang].c_str(); + } + return "None"; +} diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index ed31cc1..3b04620 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -72,7 +72,7 @@ public: void SetLanguageEnabled(const char*, cmMakefile* mf); bool GetLanguageEnabled(const char*); void ClearEnabledLanguages(); - + void GetEnabledLanguages(std::vector<std::string>& lang); /** * Try to determine system infomation such as shared library * extension, pthreads, byte order etc. @@ -107,6 +107,14 @@ public: bool GetForceUnixPaths() {return m_ForceUnixPaths;} ///! return the language for the given extension const char* GetLanguageFromExtension(const char* ext); + ///! is an extension to be ignored + bool IgnoreFile(const char* ext); + ///! What is the preference for linkers and this language (None or Prefered) + const char* GetLinkerPreference(const char* lang); + ///! What is the output extension for a given language. + const char* GetLanguageOutputExtensionForLanguage(const char* lang); + ///! What is the output extension for a given source file extension. + const char* GetLanguageOutputExtensionFromExtension(const char* lang); protected: bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen); void FindMakeProgram(cmMakefile*); @@ -121,8 +129,13 @@ protected: void RecursiveConfigure(cmLocalGenerator *lg, float start, float end); private: + // If you add a new map here, make sure it is copied + // in EnableLanguagesFromGenerator + std::map<cmStdString, bool> m_IgnoreExtensions; std::map<cmStdString, bool> m_LanguageEnabled; + std::map<cmStdString, cmStdString> m_LanguageToOutputExtension; std::map<cmStdString, cmStdString> m_ExtensionToLanguage; + std::map<cmStdString, cmStdString> m_LanguageToLinkerPreference; }; #endif diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index d695898..e559e54 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -31,7 +31,7 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& argsIn) m_TargetName = "INSTALL_FILES_"+args[0]; cmTarget& target = m_Makefile->GetTargets()[m_TargetName]; target.SetInAll(false); - target.SetType(cmTarget::INSTALL_FILES); + target.SetType(cmTarget::INSTALL_FILES, m_TargetName.c_str()); target.SetInstallPath(args[0].c_str()); if((args.size() > 1) && (args[1] == "FILES")) diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index 00dffd2..e1645c7 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -29,7 +29,7 @@ bool cmInstallProgramsCommand::InitialPass(std::vector<std::string> const& args) m_TargetName = "INSTALL_PROGRAMS_"+args[0]; cmTarget& target = m_Makefile->GetTargets()[m_TargetName]; target.SetInAll(false); - target.SetType(cmTarget::INSTALL_PROGRAMS); + target.SetType(cmTarget::INSTALL_PROGRAMS, m_TargetName.c_str()); target.SetInstallPath(args[0].c_str()); std::vector<std::string>::const_iterator s = args.begin(); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9b28bdb..66d172f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -519,3 +519,4 @@ std::string cmLocalGenerator::ConvertToRelativeOutputPath(const char* p) } + diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx index 5d6fc87..15d5092 100644 --- a/Source/cmLocalUnixMakefileGenerator.cxx +++ b/Source/cmLocalUnixMakefileGenerator.cxx @@ -309,32 +309,6 @@ void cmLocalUnixMakefileGenerator::OutputMakefile(const char* file, } - -std::string cmLocalUnixMakefileGenerator::GetOutputExtension(const char* s) -{ - if(m_Makefile->IsOn("WIN32") && !(m_Makefile->IsOn("CYGWIN") || m_Makefile->IsOn("MINGW"))) - { - std::string sourceExtension = s; - if(sourceExtension == "def") - { - return ""; - } - if(sourceExtension == "ico" || sourceExtension == "rc2") - { - return ""; - } - if(sourceExtension == "rc") - { - return ".res"; - } - return ".obj"; - } - else - { - return ".o"; - } -} - std::string cmLocalUnixMakefileGenerator::GetBaseTargetName(const char* n, const cmTarget& t) { @@ -380,7 +354,7 @@ std::string cmLocalUnixMakefileGenerator::GetFullTargetName(const char* n, const cmTarget& t) { const char* targetSuffix = t.GetProperty("SUFFIX"); - const char* suffixVar = 0; + std::string suffixVar; switch(t.GetType()) { case cmTarget::STATIC_LIBRARY: @@ -400,9 +374,20 @@ std::string cmLocalUnixMakefileGenerator::GetFullTargetName(const char* n, break; } // if there is no suffix on the target use the cmake definition - if(!targetSuffix && suffixVar) + if(!targetSuffix && suffixVar.size()) { - targetSuffix = m_Makefile->GetSafeDefinition(suffixVar); + // first check for a language specific suffix var + const char* ll = t.GetLinkerLanguage(this->GetGlobalGenerator()); + if(ll) + { + std::string langSuff = suffixVar + std::string("_") + ll; + targetSuffix = m_Makefile->GetDefinition(langSuff.c_str()); + } + // if there not a language specific suffix then use the general one + if(!targetSuffix) + { + targetSuffix = m_Makefile->GetSafeDefinition(suffixVar.c_str()); + } } std::string name = this->GetBaseTargetName(n, t); name += targetSuffix?targetSuffix:""; @@ -540,9 +525,10 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout) { if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") && !(*i)->GetCustomCommand()) - { - std::string outExt( - this->GetOutputExtension((*i)->GetSourceExtension().c_str())); + { + std::string outExt = + m_GlobalGenerator->GetLanguageOutputExtensionFromExtension( + (*i)->GetSourceExtension().c_str()); if(outExt.size() && !(*i)->GetPropertyAsBool("EXTERNAL_OBJECT") ) { fout << "\\\n"; @@ -560,8 +546,9 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout) if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") && !(*i)->GetCustomCommand()) { - std::string outExt( - this->GetOutputExtension((*i)->GetSourceExtension().c_str())); + std::string outExt = + m_GlobalGenerator->GetLanguageOutputExtensionFromExtension( + (*i)->GetSourceExtension().c_str()); if(outExt.size() && (*i)->GetPropertyAsBool("EXTERNAL_OBJECT") ) { fout << "\\\n"; @@ -577,7 +564,9 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout) if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") && !(*i)->GetCustomCommand()) { - std::string outExt(this->GetOutputExtension((*i)->GetSourceExtension().c_str())); + std::string outExt = + m_GlobalGenerator->GetLanguageOutputExtensionFromExtension( + (*i)->GetSourceExtension().c_str()); if(outExt.size() && !(*i)->GetPropertyAsBool("EXTERNAL_OBJECT") ) { std::string ofname = (*i)->GetSourceName() + outExt; @@ -594,7 +583,9 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout) if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") && !(*i)->GetCustomCommand()) { - std::string outExt(this->GetOutputExtension((*i)->GetSourceExtension().c_str())); + std::string outExt = + m_GlobalGenerator->GetLanguageOutputExtensionFromExtension( + (*i)->GetSourceExtension().c_str()); if(outExt.size() && (*i)->GetPropertyAsBool("EXTERNAL_OBJECT") ) { fout << "\\\n\"" << this->ConvertToMakeTarget(ConvertToRelativeOutputPath((*i)->GetFullPath().c_str()).c_str()) << "\" "; @@ -702,20 +693,13 @@ void cmLocalUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout, std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); buildType = cmSystemTools::UpperCase(buildType); - bool cxx = tgt.HasCxx(); - if(!cxx ) - { - // if linking a c executable use the C runtime flag as cc - // may not be the same program that creates shared libaries - // and may have different flags - runtimeFlag = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_RUNTIME_FLAG"); - runtimeSep = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_RUNTIME_FLAG_SEP"); - } - else - { - runtimeFlag = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG"); - runtimeSep = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP"); - } + const char* linkLanguage = tgt.GetLinkerLanguage(this->GetGlobalGenerator()); + std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_"; + runTimeFlagVar += linkLanguage; + runTimeFlagVar += "_FLAG"; + std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP"; + runtimeFlag = m_Makefile->GetSafeDefinition(runTimeFlagVar.c_str()); + runtimeSep = m_Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str()); // concatenate all paths or no? bool runtimeConcatenate = ( runtimeSep!="" ); @@ -733,16 +717,12 @@ void cmLocalUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout, std::string linkLibs; // Flags to link an executable to shared libraries. + std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_"; + linkFlagsVar += linkLanguage; + linkFlagsVar += "_FLAGS"; if( tgt.GetType() == cmTarget::EXECUTABLE ) { - if(cxx) - { - linkLibs = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS"); - } - else - { - linkLibs = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_LINK_FLAGS"); - } + linkLibs = m_Makefile->GetSafeDefinition(linkFlagsVar.c_str()); linkLibs += " "; } @@ -832,7 +812,6 @@ void cmLocalUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout, // then add the lib prefix back into the name if(m_IgnoreLibPrefix) { - std::cout << "m_IgnoreLibPrefix\n"; file = "lib" + file; } librariesLinked += file; @@ -986,35 +965,30 @@ std::string cmLocalUnixMakefileGenerator::CreatePostBuildRules( struct RuleVariables { - const char* replace; - const char* lookup; + const char* variable; }; -static RuleVariables ruleReplaceVars[] = + +// List of variables that are replaced when +// rules are expanced. These variables are +// replaced in the form <var> with GetSafeDefinition(var). +// ${LANG} is replaced in the variable first with all enabled +// languages. +static const char* ruleReplaceVars[] = { - {"<CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS>", "CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS"}, - {"<CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS>", "CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS"}, - {"<CMAKE_SHARED_MODULE_CREATE_FORTAN_FLAGS>", "CMAKE_SHARED_MODULE_CREATE_FORTAN_FLAGS"}, - {"<CMAKE_SHARED_MODULE_C_FLAGS>", "CMAKE_SHARED_MODULE_C_FLAGS"}, - {"<CMAKE_SHARED_MODULE_Fortran_FLAGS>", "CMAKE_SHARED_MODULE_Fortran_FLAGS"}, - {"<CMAKE_SHARED_MODULE_CXX_FLAGS>", "CMAKE_SHARED_MODULE_CXX_FLAGS"}, - {"<CMAKE_SHARED_LIBRARY_C_FLAGS>", "CMAKE_SHARED_LIBRARY_C_FLAGS"}, - {"<CMAKE_SHARED_LIBRARY_Fortran_FLAGS>", "CMAKE_SHARED_LIBRARY_Fortran_FLAGS"}, - {"<CMAKE_SHARED_LIBRARY_CXX_FLAGS>", "CMAKE_SHARED_LIBRARY_CXX_FLAGS"}, - {"<CMAKE_CXX_LINK_FLAGS>", "CMAKE_CXX_LINK_FLAGS"}, - - {"<CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS>", "CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS"}, - {"<CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS>", "CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS"}, - {"<CMAKE_SHARED_MODULE_CREATE_C_FLAGS>", "CMAKE_SHARED_MODULE_CREATE_C_FLAGS"}, - {"<CMAKE_SHARED_LIBRARY_SONAME_C_FLAG>", "CMAKE_SHARED_LIBRARY_SONAME_C_FLAG"}, - {"<CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG>", "CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG"}, - {"<CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG>", "CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG"}, - {"<CMAKE_C_LINK_FLAGS>", "CMAKE_C_LINK_FLAGS"}, - {"<CMAKE_Fortran_LINK_FLAGS>", "CMAKE_Fortran_LINK_FLAGS"}, - - {"<CMAKE_AR>", "CMAKE_AR"}, - {"<CMAKE_RANLIB>", "CMAKE_RANLIB"}, - {0, 0} + "CMAKE_SHARED_LIBRARY_CREATE_${LANG}_FLAGS", + "CMAKE_SHARED_MODULE_CREATE_${LANG}_FLAGS", + "CMAKE_SHARED_MODULE_${LANG}_FLAGS", + "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS", + "CMAKE_${LANG}_LINK_FLAGS", + "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG", + "CMAKE_${LANG}_ARCHIVE", + "CMAKE_${LANG}_COMPILER", + "CMAKE_AR", + "CMAKE_CURRENT_SOURCE_DIR", + "CMAKE_CURRENT_BINARY_DIR", + "CMAKE_RANLIB", + 0 }; @@ -1033,15 +1007,9 @@ cmLocalUnixMakefileGenerator::ExpandRuleVariables(std::string& s, const char* targetSOName, const char* linkFlags) { - std::string cxxcompiler = this->ConvertToOutputForExisting( - m_Makefile->GetSafeDefinition("CMAKE_CXX_COMPILER")); - std::string ccompiler = this->ConvertToOutputForExisting( - m_Makefile->GetSafeDefinition("CMAKE_C_COMPILER")); - std::string fcompiler = this->ConvertToOutputForExisting( - m_Makefile->GetSafeDefinition("CMAKE_Fortran_COMPILER")); - cmSystemTools::ReplaceString(s, "<CMAKE_Fortran_COMPILER>", fcompiler.c_str()); - cmSystemTools::ReplaceString(s, "<CMAKE_CXX_COMPILER>", cxxcompiler.c_str()); - cmSystemTools::ReplaceString(s, "<CMAKE_C_COMPILER>", ccompiler.c_str()); + std::vector<std::string> enabledLanguages; + m_GlobalGenerator->GetEnabledLanguages(enabledLanguages); + if(linkFlags) { cmSystemTools::ReplaceString(s, "<LINK_FLAGS>", linkFlags); @@ -1111,13 +1079,31 @@ cmLocalUnixMakefileGenerator::ExpandRuleVariables(std::string& s, cmSystemTools::ReplaceString(s, "<LINK_LIBRARIES>", linkLibs); } - RuleVariables* rv = ruleReplaceVars; - while(rv->replace) - { - cmSystemTools::ReplaceString(s, rv->replace, - m_Makefile->GetSafeDefinition(rv->lookup)); - rv++; - } + // loop over language specific replace variables + int pos = 0; + while(ruleReplaceVars[pos]) + { + std::string replace = "<"; + replace += ruleReplaceVars[pos]; + replace += ">"; + std::string replaceWith = ruleReplaceVars[pos]; + for(std::vector<std::string>::iterator i = enabledLanguages.begin(); + i != enabledLanguages.end(); ++i) + { + std::string actualReplace = replace; + cmSystemTools::ReplaceString(actualReplace, "${LANG}", i->c_str()); + std::string actualReplaceWith = replaceWith; + cmSystemTools::ReplaceString(actualReplaceWith, "${LANG}", i->c_str()); + std::string replace = m_Makefile->GetSafeDefinition(actualReplaceWith.c_str()); + // if the variable is not a FLAG then treat it like a path + if(actualReplaceWith.find("_FLAG") == actualReplaceWith.npos) + { + replace = this->ConvertToOutputForExisting(replace.c_str()); + } + cmSystemTools::ReplaceString(s, actualReplace.c_str(), replace.c_str()); + } + pos++; + } } @@ -1176,8 +1162,10 @@ void cmLocalUnixMakefileGenerator::OutputLibraryRule(std::ostream& fout, } // get the objects that are used to link this library - std::string objs = "$(" + this->CreateMakeVariable(name, "_SRC_OBJS") + ") $(" + this->CreateMakeVariable(name, "_EXTERNAL_OBJS") + ") "; - std::string objsQuoted = "$(" + this->CreateMakeVariable(name, "_SRC_OBJS_QUOTED") + ") $(" + this->CreateMakeVariable(name, "_EXTERNAL_OBJS_QUOTED") + ") "; + std::string objs = "$(" + this->CreateMakeVariable(name, "_SRC_OBJS") + + ") $(" + this->CreateMakeVariable(name, "_EXTERNAL_OBJS") + ") "; + std::string objsQuoted = "$(" + this->CreateMakeVariable(name, "_SRC_OBJS_QUOTED") + + ") $(" + this->CreateMakeVariable(name, "_EXTERNAL_OBJS_QUOTED") + ") "; // create a variable with the objects that this library depends on std::string depend = objs + " $(" + this->CreateMakeVariable(name, "_DEPEND_LIBS") + ")"; @@ -1289,23 +1277,10 @@ void cmLocalUnixMakefileGenerator::OutputSharedLibraryRule(std::ostream& fout, const char* name, const cmTarget &t) { - const char* createRule; - if(t.HasCxx()) - { - createRule = "CMAKE_CXX_CREATE_SHARED_LIBRARY"; - } - else - { - if(t.HasFortran()) - { - createRule = "CMAKE_Fortran_CREATE_SHARED_LIBRARY"; - } - else - { - createRule = "CMAKE_C_CREATE_SHARED_LIBRARY"; - } - } - + const char* linkLanguage = t.GetLinkerLanguage(this->GetGlobalGenerator()); + std::string createRule = "CMAKE_"; + createRule += linkLanguage; + createRule += "_CREATE_SHARED_LIBRARY"; std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); buildType = cmSystemTools::UpperCase(buildType); std::string linkFlags = m_Makefile->GetSafeDefinition("CMAKE_SHARED_LINKER_FLAGS"); @@ -1339,7 +1314,7 @@ void cmLocalUnixMakefileGenerator::OutputSharedLibraryRule(std::ostream& fout, linkFlags += " "; } this->OutputLibraryRule(fout, name, t, - createRule, + createRule.c_str(), "shared library", linkFlags.c_str()); } @@ -1348,23 +1323,10 @@ void cmLocalUnixMakefileGenerator::OutputModuleLibraryRule(std::ostream& fout, const char* name, const cmTarget &t) { - const char* createRule; - if(t.HasCxx()) - { - createRule = "CMAKE_CXX_CREATE_SHARED_MODULE"; - } - else - { - if(t.HasFortran()) - { - createRule = "CMAKE_Fortran_CREATE_SHARED_MODULE"; - } - else - { - createRule = "CMAKE_C_CREATE_SHARED_MODULE"; - } - } - + const char* linkLanguage = t.GetLinkerLanguage(this->GetGlobalGenerator()); + std::string createRule = "CMAKE_"; + createRule += linkLanguage; + createRule += "_CREATE_SHARED_MODULE"; std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); buildType = cmSystemTools::UpperCase(buildType); std::string linkFlags = m_Makefile->GetSafeDefinition("CMAKE_MODULE_LINKER_FLAGS"); @@ -1383,7 +1345,7 @@ void cmLocalUnixMakefileGenerator::OutputModuleLibraryRule(std::ostream& fout, linkFlags += " "; } this->OutputLibraryRule(fout, name, t, - createRule, + createRule.c_str(), "shared module", linkFlags.c_str()); } @@ -1393,23 +1355,10 @@ void cmLocalUnixMakefileGenerator::OutputStaticLibraryRule(std::ostream& fout, const char* name, const cmTarget &t) { - const char* createRule; - if(t.HasCxx()) - { - createRule = "CMAKE_CXX_CREATE_STATIC_LIBRARY"; - } - else - { - if(t.HasFortran()) - { - createRule = "CMAKE_Fortran_CREATE_STATIC_LIBRARY"; - } - else - { - createRule = "CMAKE_C_CREATE_STATIC_LIBRARY"; - } - } - + const char* linkLanguage = t.GetLinkerLanguage(this->GetGlobalGenerator()); + std::string createRule = "CMAKE_"; + createRule += linkLanguage; + createRule += "_CREATE_STATIC_LIBRARY"; std::string linkFlags; const char* targetLinkFlags = t.GetProperty("STATIC_LIBRARY_FLAGS"); if(targetLinkFlags) @@ -1418,7 +1367,7 @@ void cmLocalUnixMakefileGenerator::OutputStaticLibraryRule(std::ostream& fout, linkFlags += " "; } this->OutputLibraryRule(fout, name, t, - createRule, + createRule.c_str(), "static library", linkFlags.c_str()); @@ -1486,34 +1435,23 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout, linkFlags += m_Makefile->GetSafeDefinition(build.c_str()); linkFlags += " "; } + const char* linkLanguage = t.GetLinkerLanguage(this->GetGlobalGenerator()); + + std::string langVar = "CMAKE_"; + langVar += linkLanguage; + + std::string ruleVar = langVar + "_LINK_EXECUTABLE"; + std::string flagsVar = langVar + "_FLAGS"; + std::string sharedFlagsVar = "CMAKE_SHARED_LIBRARY_"; + sharedFlagsVar += langVar; + sharedFlagsVar += "_FLAGS"; + + rules.push_back(m_Makefile->GetRequiredDefinition(ruleVar.c_str())); + flags += m_Makefile->GetSafeDefinition(flagsVar.c_str()); + flags += " "; + flags += m_Makefile->GetSafeDefinition(sharedFlagsVar.c_str()); + flags += " "; - if(t.HasCxx()) - { - rules.push_back(m_Makefile->GetRequiredDefinition("CMAKE_CXX_LINK_EXECUTABLE")); - flags += m_Makefile->GetSafeDefinition("CMAKE_CXX_FLAGS"); - flags += " "; - flags += m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_CXX_FLAGS"); - flags += " "; - } - else - { - if(t.HasFortran()) - { - rules.push_back(m_Makefile->GetRequiredDefinition("CMAKE_Fortran_LINK_EXECUTABLE")); - flags += m_Makefile->GetSafeDefinition("CMAKE_Fortran_FLAGS"); - flags += " "; - flags += m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_Fortran_FLAGS"); - flags += " "; - } - else - { - rules.push_back(m_Makefile->GetRequiredDefinition("CMAKE_C_LINK_EXECUTABLE")); - flags += m_Makefile->GetSafeDefinition("CMAKE_C_FLAGS"); - flags += " "; - flags += m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_C_FLAGS"); - flags += " "; - } - } cmOStringStream linklibs; this->OutputLinkLibraries(linklibs, 0, t); std::string comment = "executable"; @@ -1538,7 +1476,9 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout, } if(cmSystemTools::IsOn(m_Makefile->GetDefinition("BUILD_SHARED_LIBS"))) { - linkFlags += m_Makefile->GetSafeDefinition("CMAKE_SHARED_BUILD_CXX_FLAGS"); + std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") + linkLanguage + + std::string("_FLAGS"); + linkFlags += m_Makefile->GetSafeDefinition(sFlagVar.c_str()); linkFlags += " "; } @@ -2325,7 +2265,10 @@ bool cmLocalUnixMakefileGenerator::OutputObjectDepends(std::ostream& fout) dep != (*source)->GetDepends().end(); ++dep) { std::string s = (*source)->GetSourceName(); - s += this->GetOutputExtension((*source)->GetSourceExtension().c_str()); + std::string outExt = + m_GlobalGenerator->GetLanguageOutputExtensionFromExtension( + (*source)->GetSourceExtension().c_str()); + s += outExt; fout << this->ConvertToRelativeOutputPath(s.c_str()) << " : " << this->ConvertToRelativeOutputPath(dep->c_str()) << "\n"; ret = true; @@ -2555,8 +2498,17 @@ void cmLocalUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout) fout << "CMAKE_BINARY_DIR = " << this->ConvertToRelativeOutputPath(m_Makefile->GetHomeOutputDirectory()) << "\n"; - // Output Include paths - fout << "INCLUDE_FLAGS = "; + fout << "\n\n"; +} + +cmStdString& cmLocalUnixMakefileGenerator::GetIncludeFlags(const char* lang) +{ + if(m_LanguageToIncludeFlags.count(lang)) + { + return m_LanguageToIncludeFlags[lang]; + } + // Output Include paths + cmOStringStream includeFlags; std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories(); std::vector<std::string>::iterator i; std::map<cmStdString, cmStdString> implicitIncludes; @@ -2592,11 +2544,31 @@ void cmLocalUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout) includeSourceDir = true; } } + std::string flagVar = "CMAKE_INCLUDE_FLAG_"; + flagVar += lang; + const char* includeFlag = m_Makefile->GetDefinition(flagVar.c_str()); + flagVar = "CMAKE_INCLUDE_FLAG_SEP_"; + flagVar += lang; + const char* sep = m_Makefile->GetDefinition(flagVar.c_str()); + + bool repeatFlag = true; // should the include flag be repeated like ie. -IA -IB + if(!sep) + { + sep = " "; + } + else + { + // if there is a separator then the flag is not repeated but is only given once + // i.e. -classpath a:b:c + repeatFlag = false; + } + bool flagUsed = false; if(includeSourceDir) { - fout << "-I" + includeFlags << includeFlag << this->ConvertToOutputForExisting(m_Makefile->GetStartDirectory()) - << " "; + << sep; + flagUsed = true; } implicitIncludes["/usr/include"] = "/usr/include"; @@ -2619,14 +2591,25 @@ void cmLocalUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout) // implementations because the wrong headers may be found first. if(implicitIncludes.find(include) == implicitIncludes.end()) { - fout << "-I" << this->ConvertToOutputForExisting(i->c_str()) << " "; + if(!flagUsed || repeatFlag) + { + includeFlags << includeFlag; + flagUsed = true; + } + includeFlags << this->ConvertToOutputForExisting(i->c_str()) << sep; } } - fout << m_Makefile->GetDefineFlags(); - fout << "\n\n"; + std::string flags = includeFlags.str(); + // remove trailing separators + if((sep[0] != ' ') && flags[flags.size()-1] == sep[0]) + { + flags[flags.size()-1] = ' '; + } + flags += m_Makefile->GetDefineFlags(); + m_LanguageToIncludeFlags[lang] = flags; + return m_LanguageToIncludeFlags[lang]; } - void cmLocalUnixMakefileGenerator::OutputMakeRules(std::ostream& fout) { this->OutputMakeRule(fout, @@ -2827,13 +2810,12 @@ OutputBuildObjectFromSource(std::ostream& fout, return; } - std::string comment = "object file"; - std::string objectFile = std::string(shortName) + - this->GetOutputExtension(source.GetSourceExtension().c_str()); + std::string outputExt = + m_GlobalGenerator->GetLanguageOutputExtensionFromExtension( + source.GetSourceExtension().c_str()); + std::string objectFile = std::string(shortName) + outputExt; objectFile = this->CreateSafeUniqueObjectFileName(objectFile.c_str()); objectFile = this->ConvertToRelativeOutputPath(objectFile.c_str()); - cmSystemTools::FileFormat format = - cmSystemTools::GetFileFormat(source.GetSourceExtension().c_str()); std::vector<std::string> rules; std::string flags; if(extraCompileFlags) @@ -2848,6 +2830,19 @@ OutputBuildObjectFromSource(std::ostream& fout, const char* lang = m_GlobalGenerator->GetLanguageFromExtension(source.GetSourceExtension().c_str()); // for now if the lang is defined add the rules and flags for it + std::string comment = outputExt; + comment += " file"; + if(lang) + { + comment += " from "; + comment += lang; + comment += ": "; + if(comment.size() < 18) + { + comment.resize(18, ' '); + } + } + if(lang) { std::string varString = "CMAKE_"; @@ -2883,44 +2878,17 @@ OutputBuildObjectFromSource(std::ostream& fout, flags += " "; } } - // the language is not defined, fall back on old stuff else - { - switch(format) + { + // if the language is not defined and should not be ignored, + // then produce an error + if(!m_GlobalGenerator->IgnoreFile(source.GetSourceExtension().c_str())) { - // these are all handled by the if(lang) step now - case cmSystemTools::C_FILE_FORMAT: - case cmSystemTools::CXX_FILE_FORMAT: - case cmSystemTools::FORTRAN_FILE_FORMAT: - break; - case cmSystemTools::HEADER_FILE_FORMAT: - return; - case cmSystemTools::DEFINITION_FILE_FORMAT: - return; - case cmSystemTools::OBJECT_FILE_FORMAT: - return; - case cmSystemTools::RESOURCE_FILE_FORMAT: - { - // use rc rule here if it is defined - const char* rule = m_Makefile->GetDefinition("CMAKE_COMPILE_RESOURCE"); - if(rule) - { - rules.push_back(rule); - } - } - break; - case cmSystemTools::NO_FILE_FORMAT: - case cmSystemTools::JAVA_FILE_FORMAT: - case cmSystemTools::STATIC_LIBRARY_FILE_FORMAT: - case cmSystemTools::SHARED_LIBRARY_FILE_FORMAT: - case cmSystemTools::MODULE_FILE_FORMAT: - case cmSystemTools::UNKNOWN_FILE_FORMAT: - cmSystemTools::Error("Unexpected file type ", - sourceFile.c_str()); - break; - } + cmSystemTools::Error("Unexpected file type ", + sourceFile.c_str()); + } } - flags += "$(INCLUDE_FLAGS) "; + flags += this->GetIncludeFlags(lang); // expand multi-command semi-colon separated lists // of commands into separate commands std::vector<std::string> commands; @@ -2964,8 +2932,7 @@ OutputBuildObjectFromSource(std::ostream& fout, void cmLocalUnixMakefileGenerator::OutputSourceObjectBuildRules(std::ostream& fout) { - fout << "# Rules to build " << this->GetOutputExtension("") - << " files from their sources:\n"; + fout << "# Rules to build source files :\n\n"; std::set<std::string> rules; diff --git a/Source/cmLocalUnixMakefileGenerator.h b/Source/cmLocalUnixMakefileGenerator.h index 756190d..832afd6 100644 --- a/Source/cmLocalUnixMakefileGenerator.h +++ b/Source/cmLocalUnixMakefileGenerator.h @@ -88,6 +88,7 @@ public: void SetPassMakeflags(bool s){m_PassMakeflags = s;} protected: + void AddDependenciesToSourceFile(cmDependInformation const*info, cmSourceFile *i, std::set<cmDependInformation const*> *visited); @@ -198,7 +199,6 @@ protected: ///! return true if the two paths are the same virtual bool SamePath(const char* path1, const char* path2); - virtual std::string GetOutputExtension(const char* sourceExtension); std::string CreatePreBuildRules(const cmTarget &target, const char* targetName); std::string CreatePreLinkRules(const cmTarget &target, @@ -239,12 +239,13 @@ protected: */ std::string& CreateSafeUniqueObjectFileName(const char* sin); - ///! final processing for a path to be put in a makefile + cmStdString& GetIncludeFlags(const char* lang); protected: int m_MakefileVariableSize; std::map<cmStdString, cmStdString> m_MakeVariableMap; std::map<cmStdString, cmStdString> m_ShortMakeVariableMap; std::map<cmStdString, cmStdString> m_UniqueObjectNamesMap; + std::map<cmStdString, cmStdString> m_LanguageToIncludeFlags; bool m_IgnoreLibPrefix; std::string m_IncludeDirective; std::string m_MakeSilentFlag; diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 0360e5a..de22436 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -340,8 +340,9 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, { compileFlags = cflags; } - if(cmSystemTools::GetFileFormat((*sf)->GetSourceExtension().c_str()) - == cmSystemTools::CXX_FILE_FORMAT) + const char* lang = + m_GlobalGenerator->GetLanguageFromExtension((*sf)->GetSourceExtension().c_str()); + if(strcmp(lang, "CXX") == 0) { // force a C++ file type compileFlags += " /TP "; @@ -1058,33 +1059,29 @@ void cmLocalVisualStudio6Generator::WriteDSPHeader(std::ostream& fout, const cha std::string flagsDebug = " "; std::string flagsDebugRel = " "; // if CXX is on and the target contains cxx code then add the cxx flags - if ( gen->GetLanguageEnabled("CXX") && target.HasCxx() ) - { - flagsRelease = m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS_RELEASE"); - flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\" "; - flagsMinSize = m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS_MINSIZEREL"); - flagsMinSize += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\" "; - flagsDebug = m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS_DEBUG"); - flagsDebug += " -DCMAKE_INTDIR=\\\"Debug\\\" "; - flagsDebugRel = m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS_RELWITHDEBINFO"); - flagsDebugRel += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" "; - flags = " "; - flags = m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS"); - } - // if C and the target is not CXX - else if(gen->GetLanguageEnabled("C") && !target.HasCxx()) - { - flagsRelease += m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS_RELEASE"); - flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\""; - flagsMinSize += m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS_MINSIZEREL"); - flagsMinSize += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\""; - flagsDebug += m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS_DEBUG"); - flagsDebug += " -DCMAKE_INTDIR=\\\"Debug\\\""; - flagsDebugRel += m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS_RELWITHDEBINFO"); - flagsDebugRel += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\""; - flags = " "; - flags = m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS"); - } + std::string baseFlagVar = "CMAKE_"; + const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator()); + baseFlagVar += "CMAKE_"; + baseFlagVar += linkLanguage; + baseFlagVar += "_FLAGS"; + flags = m_Makefile->GetRequiredDefinition(baseFlagVar.c_str()); + + std::string flagVar = baseFlagVar + "_RELEASE"; + flagsRelease = m_Makefile->GetRequiredDefinition(flagVar.c_str()); + flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\" "; + + flagVar = baseFlagVar + "_MINSIZEREL"; + flagsMinSize = m_Makefile->GetRequiredDefinition(flagVar.c_str()); + flagsMinSize += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\" "; + + flagVar = baseFlagVar + "_DEBUG"; + flagsDebug = m_Makefile->GetRequiredDefinition(flagVar.c_str()); + flagsDebug += " -DCMAKE_INTDIR=\\\"Debug\\\" "; + + flagVar = baseFlagVar + "_RELWITHDEBINFO"; + flagsDebugRel = m_Makefile->GetRequiredDefinition(flagVar.c_str()); + flagsDebugRel += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" "; + // if unicode is not found, then add -D_MBCS std::string defs = m_Makefile->GetDefineFlags(); if(flags.find("D_UNICODE") == flags.npos && @@ -1097,7 +1094,6 @@ void cmLocalVisualStudio6Generator::WriteDSPHeader(std::ostream& fout, const cha // There are not separate CXX and C template files, so we use the same // variable names. The previous code sets up flags* variables to contain // the correct C or CXX flags - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE", flagsRelease.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL", flagsMinSize.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG", flagsDebug.c_str()); cmSystemTools::ReplaceString(line,"CMAKE_CXX_FLAGS_RELWITHDEBINFO", flagsDebugRel.c_str()); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 84f10a5..e0cd55a 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -321,24 +321,27 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, std::string flagsRelease = " "; std::string flagsMinSize = " "; std::string flagsDebug = " "; - std::string flagsDebugRel = " "; - if(target.HasCxx()) + std::string flagsDebugRel = " "; + if(strcmp(configType, "10") != 0) { - flags = m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS"); - flagsRelease += m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS_RELEASE"); - flagsMinSize += m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS_MINSIZEREL"); - flagsDebug += m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS_DEBUG"); - flagsDebugRel += m_Makefile->GetRequiredDefinition("CMAKE_CXX_FLAGS_RELWITHDEBINFO"); - } - else - { - flags = m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS"); - flagsRelease += m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS_RELEASE"); - flagsMinSize += m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS_MINSIZEREL"); - flagsDebug += m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS_DEBUG"); - flagsDebugRel += m_Makefile->GetRequiredDefinition("CMAKE_C_FLAGS_RELWITHDEBINFO"); - } + const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator()); + std::string baseFlagVar = "CMAKE_"; + baseFlagVar += linkLanguage; + baseFlagVar += "_FLAGS"; + flags = m_Makefile->GetRequiredDefinition(baseFlagVar.c_str()); + + std::string flagVar = baseFlagVar + "_RELEASE"; + flagsRelease += m_Makefile->GetRequiredDefinition(flagVar.c_str()); + + flagVar = baseFlagVar + "_MINSIZEREL"; + flagsMinSize += m_Makefile->GetRequiredDefinition(flagVar.c_str()); + flagVar = baseFlagVar + "_DEBUG"; + flagsDebug += m_Makefile->GetRequiredDefinition(flagVar.c_str()); + + flagVar = baseFlagVar + "_RELWITHDEBINFO"; + flagsDebugRel += m_Makefile->GetRequiredDefinition(flagVar.c_str()); + } std::string programDatabase; const char* pre = "WIN32,_DEBUG,_WINDOWS"; @@ -574,6 +577,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: + { fout << "\t\t\t<Tool\n" << "\t\t\t\tName=\"VCLinkerTool\"\n" << "\t\t\t\tAdditionalOptions=\"/MACHINE:I386"; @@ -620,10 +624,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, { fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"; } - if(target.HasCxx()) + const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator()); + std::string stackVar = "CMAKE_"; + stackVar += linkLanguage; + stackVar += "_STACK_SIZE"; + const char* stackVal = m_Makefile->GetDefinition(stackVar.c_str()); + if(stackVal) { - fout << "\t\t\t\tStackReserveSize=\"" - << m_Makefile->GetRequiredDefinition("CMAKE_CXX_STACK_SIZE") << "\"\n"; + fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n"; } temp = m_LibraryOutputPath; temp += configName; @@ -632,9 +640,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, temp += debugPostfix; temp += ".lib"; fout << "\t\t\t\tImportLibrary=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n"; + } break; case cmTarget::EXECUTABLE: - + { + fout << "\t\t\t<Tool\n" << "\t\t\t\tName=\"VCLinkerTool\"\n" << "\t\t\t\tAdditionalOptions=\"/MACHINE:I386"; @@ -682,14 +692,19 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, else { fout << "\t\t\t\tSubSystem=\"1\"\n"; - } - if(target.HasCxx()) + } + const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator()); + std::string stackVar = "CMAKE_"; + stackVar += linkLanguage; + stackVar += "_STACK_SIZE"; + const char* stackVal = m_Makefile->GetDefinition(stackVar.c_str()); + if(stackVal) { - fout << "\t\t\t\tStackReserveSize=\"" - << m_Makefile->GetRequiredDefinition("CMAKE_CXX_STACK_SIZE") << "\""; + fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\""; } fout << "/>\n"; break; + } case cmTarget::UTILITY: break; } @@ -922,8 +937,9 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, { compileFlags = cflags; } - if(cmSystemTools::GetFileFormat((*sf)->GetSourceExtension().c_str()) - == cmSystemTools::CXX_FILE_FORMAT) + const char* lang = + m_GlobalGenerator->GetLanguageFromExtension((*sf)->GetSourceExtension().c_str()); + if(lang && strcmp(lang, "CXX") == 0) { // force a C++ file type compileFlags += " /TP "; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f4c862b..87ce942 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1028,23 +1028,22 @@ void cmMakefile::AddLibrary(const char* lname, int shared, switch (shared) { case 0: - target.SetType(cmTarget::STATIC_LIBRARY); + target.SetType(cmTarget::STATIC_LIBRARY, lname); break; case 1: - target.SetType(cmTarget::SHARED_LIBRARY); + target.SetType(cmTarget::SHARED_LIBRARY, lname); break; case 2: - target.SetType(cmTarget::MODULE_LIBRARY); + target.SetType(cmTarget::MODULE_LIBRARY, lname); break; default: - target.SetType(cmTarget::STATIC_LIBRARY); + target.SetType(cmTarget::STATIC_LIBRARY, lname); } // Clear its dependencies. Otherwise, dependencies might persist // over changes in CMakeLists.txt, making the information stale and // hence useless. target.ClearDependencyInformation( *this, lname ); - target.SetInAll(true); target.GetSourceLists() = srcs; this->AddGlobalLinkInformation(lname, target); @@ -1095,7 +1094,7 @@ cmTarget* cmMakefile::AddExecutable(const char *exeName, const std::vector<std::string> &srcs) { cmTarget target; - target.SetType(cmTarget::EXECUTABLE); + target.SetType(cmTarget::EXECUTABLE, exeName); target.SetInAll(true); target.GetSourceLists() = srcs; this->AddGlobalLinkInformation(exeName, target); @@ -1132,7 +1131,7 @@ void cmMakefile::AddUtilityCommand(const char* utilityName, const std::vector<std::string> &out) { cmTarget target; - target.SetType(cmTarget::UTILITY); + target.SetType(cmTarget::UTILITY, utilityName); target.SetInAll(all); if (out.size() > 1) { diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index f62d8bd..fc55482 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -51,6 +51,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args) std::vector<std::string> languages; if(args.size() > 1) { + bool hasCXX = false; + bool hasC = false; for(size_t i =1; i < args.size(); ++i) { languages.push_back(args[i]); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 7c3fb7a..f9ed992 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -17,15 +17,16 @@ #include "cmTarget.h" #include "cmMakefile.h" #include "cmSourceFile.h" - +#include "cmGlobalGenerator.h" #include <map> #include <set> #include <queue> #include <stdlib.h> // required for atof -void cmTarget::SetType(TargetType type) +void cmTarget::SetType(TargetType type, const char* name) { + m_Name = name; // only add dependency information for library targets m_TargetType = type; if(m_TargetType >= STATIC_LIBRARY && m_TargetType <= MODULE_LIBRARY) { @@ -419,46 +420,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, } -bool cmTarget::HasCxx() const -{ - if(this->GetProperty("HAS_CXX")) - { - return true; - } - for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin(); - i != m_SourceFiles.end(); ++i) - { - if(cmSystemTools::GetFileFormat((*i)->GetSourceExtension().c_str()) - == cmSystemTools::CXX_FILE_FORMAT) - { - return true; - } - } - return false; -} - -bool cmTarget::HasFortran() const -{ - if(this->GetProperty("HAS_FORTRAN")) - { - return true; - } - for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin(); - i != m_SourceFiles.end(); ++i) - { - if(cmSystemTools::GetFileFormat((*i)->GetSourceExtension().c_str()) - == cmSystemTools::FORTRAN_FILE_FORMAT) - { - return true; - } - } - return false; -} - - - - - void cmTarget::AnalyzeLibDependencies( const cmMakefile& mf ) { @@ -783,3 +744,68 @@ bool cmTarget::GetPropertyAsBool(const char* prop) const } return false; } + +const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg) const +{ + if(this->GetProperty("HAS_CXX")) + { + const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", "CXX"); + } + const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"); + if(linkerLang) + { + return linkerLang; + } + std::set<cmStdString> languages; + for(std::vector<cmSourceFile*>::const_iterator i = m_SourceFiles.begin(); + i != m_SourceFiles.end(); ++i) + { + const char* lang = + gg->GetLanguageFromExtension((*i)->GetSourceExtension().c_str()); + if(lang) + { + languages.insert(lang); + } + } + if(languages.size() == 0) + { + std::string m = "Error Target: "; + m += m_Name + " contains no source files with an enabled languages."; + cmSystemTools::Error(m.c_str()); + return "(NullLanguage)"; + } + if(languages.size() == 1) + { + const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", languages.begin()->c_str()); + return this->GetProperty("LINKER_LANGUAGE"); + } + const char* prefLang = 0; + for(std::set<cmStdString>::const_iterator s = languages.begin(); + s != languages.end(); ++s) + { + const char* lpref = gg->GetLinkerPreference(s->c_str()); + if(lpref[0] == 'P') + { + if(prefLang && !(*s == prefLang)) + { + std::string m = "Error Target: "; + m += m_Name + " Contains more than one Prefered language: "; + m += *s; + m += " and "; + m += prefLang; + m += "\nYou must set the LINKER_LANGUAGE property for this target."; + cmSystemTools::Error(m.c_str()); + } + else + { + prefLang = s->c_str(); + } + } + } + if(!prefLang) + { + prefLang = languages.begin()->c_str(); + } + const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", languages.begin()->c_str()); + return this->GetProperty("LINKER_LANGUAGE"); +} diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 3ba8690..8599189 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -19,6 +19,7 @@ #include "cmCustomCommand.h" class cmSourceFile; +class cmGlobalGenerator; /** \class cmTarget * \brief Represent a library or executable target loaded from a makefile. @@ -46,7 +47,10 @@ public: /** * Set the target type */ - void SetType(TargetType f); + void SetType(TargetType f, const char* name); + + ///! Set/Get the name of the target + const char* GetName() const {return m_Name.c_str();} /** * Indicate whether the target is part of the all target @@ -85,11 +89,6 @@ public: {return m_SourceFiles;} std::vector<cmSourceFile*> &GetSourceFiles() {return m_SourceFiles;} - ///! does this target have a cxx file in it - bool HasCxx() const; - - ///! does this target have a fortran file in it - bool HasFortran() const; /** * Get the list of the source files used by this target */ @@ -156,6 +155,8 @@ public: */ void TraceVSDependencies(std::string projName, cmMakefile *mf); + ///! Return the prefered linker language for this target + const char* GetLinkerLanguage(cmGlobalGenerator*) const; private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. @@ -210,7 +211,9 @@ private: void GatherDependencies( const cmMakefile& mf, const std::string& lib, DependencyMap& dep_map ); + private: + std::string m_Name; std::vector<cmCustomCommand> m_PreBuildCommands; std::vector<cmCustomCommand> m_PreLinkCommands; std::vector<cmCustomCommand> m_PostBuildCommands; diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx index 55ba900..d4a2d1a 100644 --- a/Source/cmTryCompileCommand.cxx +++ b/Source/cmTryCompileCommand.cxx @@ -17,6 +17,7 @@ #include "cmTryCompileCommand.h" #include "cmake.h" #include "cmCacheManager.h" +#include "cmGlobalGenerator.h" #include "cmListFileCache.h" #include <cmsys/Directory.hxx> @@ -146,56 +147,38 @@ int cmTryCompileCommand::CoreTryCompileCode( } std::string source = argv[2]; - cmSystemTools::FileFormat format = - cmSystemTools::GetFileFormat( - cmSystemTools::GetFilenameExtension(source).c_str()); - if ( format == cmSystemTools::C_FILE_FORMAT ) + const char* lang = mf->GetCMakeInstance()->GetGlobalGenerator()->GetLanguageFromExtension( + cmSystemTools::GetFilenameExtension(source).c_str()); + if(lang) { - fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE C)\n"); - } - else if ( format == cmSystemTools::CXX_FILE_FORMAT ) - { - fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE C CXX)\n"); - } - else if ( format == cmSystemTools::FORTRAN_FILE_FORMAT ) - { - fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE Fortran)\n"); + fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE %s)\n", lang); } else { - cmSystemTools::Error("Unknown file format for file: ", source.c_str(), - "; TRY_COMPILE only works for C, CXX, and FORTRAN files"); + std::vector<std::string> lang; + mf->GetCMakeInstance()->GetGlobalGenerator()->GetEnabledLanguages(lang); + std::string msg = "TRY_COMPILE only works for enabled languages files," + "\nCurrently enabled languages are:\n"; + for(std::vector<std::string>::iterator l = lang.begin(); + l != lang.end(); ++l) + { + msg += *l; + msg += " "; + } + cmSystemTools::Error("Unknown file format for file: ", source.c_str(), msg.c_str()); return -1; } - const char* cflags = mf->GetDefinition("CMAKE_C_FLAGS"); + std::string langFlags = "CMAKE_"; + langFlags += lang; + langFlags += "_FLAGS"; fprintf(fout, "SET(CMAKE_VERBOSE_MAKEFILE 1)\n"); - fprintf(fout, "SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}"); - if(cflags) + fprintf(fout, "SET(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}", lang, lang); + const char* flags = mf->GetDefinition(langFlags.c_str()); + if(flags) { - fprintf(fout, " %s ", cflags); + fprintf(fout, " %s ", flags); } fprintf(fout, " ${COMPILE_DEFINITIONS}\")\n"); - // CXX specific flags - if(format == cmSystemTools::CXX_FILE_FORMAT ) - { - const char* cxxflags = mf->GetDefinition("CMAKE_CXX_FLAGS"); - fprintf(fout, "SET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} "); - if(cxxflags) - { - fprintf(fout, " %s ", cxxflags); - } - fprintf(fout, " ${COMPILE_DEFINITIONS}\")\n"); - } - if(format == cmSystemTools::FORTRAN_FILE_FORMAT ) - { - const char* fflags = mf->GetDefinition("CMAKE_Fortran_FLAGS"); - fprintf(fout, "SET(CMAKE_Fortran_FLAGS \"${CMAKE_Fortran_FLAGS} "); - if(fflags) - { - fprintf(fout, " %s ", fflags); - } - fprintf(fout, " ${COMPILE_DEFINITIONS}\")\n"); - } fprintf(fout, "INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})\n"); fprintf(fout, "LINK_DIRECTORIES(${LINK_DIRECTORIES})\n"); // handle any compile flags we need to pass on diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 4a77d1a..47f1d26 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -33,6 +33,7 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv) // build an arg list for TryCompile and extract the runArgs std::vector<std::string> tryCompile; + std::string outputVariable; std::string runArgs; unsigned int i; for (i = 1; i < argv.size(); ++i) @@ -51,13 +52,22 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv) { tryCompile.push_back(argv[i]); } - } - else + } + else { tryCompile.push_back(argv[i]); + if (argv[i] == "OUTPUT_VARIABLE") + { + if ( argv.size() <= (i+1) ) + { + cmSystemTools::Error( + "OUTPUT_VARIABLE specified but there is no variable"); + return false; + } + outputVariable = argv[i+1]; + } } } - // do the try compile int res = cmTryCompileCommand::CoreTryCompileCode(m_Makefile, tryCompile, false); @@ -102,6 +112,18 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv) int timeout = 0; cmSystemTools::RunSingleCommand(finalCommand.c_str(), &output, &retVal, 0, false, timeout); + if(outputVariable.size()) + { + // if the TryCompileCore saved output in this outputVariable then + // prepend that output to this output + const char* compileOutput = m_Makefile->GetDefinition(outputVariable.c_str()); + if(compileOutput) + { + output = std::string(compileOutput) + output; + } + m_Makefile->AddDefinition(outputVariable.c_str(), output.c_str()); + } + // set the run var char retChar[1000]; sprintf(retChar,"%i",retVal); |