diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2004-10-21 18:34:02 (GMT) |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2004-10-21 18:34:02 (GMT) |
commit | 7cef36c628a8ef07a0c53ea08691e4e6b949a695 (patch) | |
tree | 6dddd32ad310a5a069b66462cc79ca3fea15f024 /Source/cmLocalUnixMakefileGenerator.cxx | |
parent | 8ff4c079159a8c5a53017ff1b02c8ac591eb2727 (diff) | |
download | CMake-7cef36c628a8ef07a0c53ea08691e4e6b949a695.zip CMake-7cef36c628a8ef07a0c53ea08691e4e6b949a695.tar.gz CMake-7cef36c628a8ef07a0c53ea08691e4e6b949a695.tar.bz2 |
ENH: add the ability to generate custom commands for a language that is not supported by an IDE
Diffstat (limited to 'Source/cmLocalUnixMakefileGenerator.cxx')
-rw-r--r-- | Source/cmLocalUnixMakefileGenerator.cxx | 565 |
1 files changed, 1 insertions, 564 deletions
diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx index 53ab425..80fee93 100644 --- a/Source/cmLocalUnixMakefileGenerator.cxx +++ b/Source/cmLocalUnixMakefileGenerator.cxx @@ -322,24 +322,7 @@ std::string cmLocalUnixMakefileGenerator::GetBaseTargetName(const char* n, #endif const char* targetPrefix = t.GetProperty("PREFIX"); - const char* prefixVar = 0; - switch(t.GetType()) - { - case cmTarget::STATIC_LIBRARY: - prefixVar = "CMAKE_STATIC_LIBRARY_PREFIX"; - break; - case cmTarget::SHARED_LIBRARY: - prefixVar = "CMAKE_SHARED_LIBRARY_PREFIX"; - break; - case cmTarget::MODULE_LIBRARY: - prefixVar = "CMAKE_SHARED_MODULE_PREFIX"; - break; - case cmTarget::EXECUTABLE: - case cmTarget::UTILITY: - case cmTarget::INSTALL_FILES: - case cmTarget::INSTALL_PROGRAMS: - break; - } + const char* prefixVar = t.GetPrefixVariable(); // if there is no prefix on the target use the cmake definition if(!targetPrefix && prefixVar) { @@ -361,49 +344,6 @@ std::string cmLocalUnixMakefileGenerator::GetBaseTargetName(const char* n, return name; } -std::string cmLocalUnixMakefileGenerator::GetFullTargetName(const char* n, - const cmTarget& t) -{ - const char* targetSuffix = t.GetProperty("SUFFIX"); - std::string suffixVar; - switch(t.GetType()) - { - case cmTarget::STATIC_LIBRARY: - suffixVar = "CMAKE_STATIC_LIBRARY_SUFFIX"; - break; - case cmTarget::SHARED_LIBRARY: - suffixVar = "CMAKE_SHARED_LIBRARY_SUFFIX"; - break; - case cmTarget::MODULE_LIBRARY: - suffixVar = "CMAKE_SHARED_MODULE_SUFFIX"; - break; - case cmTarget::EXECUTABLE: - targetSuffix = cmSystemTools::GetExecutableExtension(); - case cmTarget::UTILITY: - case cmTarget::INSTALL_FILES: - case cmTarget::INSTALL_PROGRAMS: - break; - } - // if there is no suffix on the target use the cmake definition - if(!targetSuffix && suffixVar.size()) - { - // 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:""; - return name; -} // Output the rules for any targets void cmLocalUnixMakefileGenerator::OutputEcho(std::ostream& fout, @@ -683,221 +623,6 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout) } -/** - * Output the linking rules on a command line. For executables, - * targetLibrary should be a NULL pointer. For libraries, it should point - * to the name of the library. This will not link a library against itself. - */ -void cmLocalUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout, - const char* targetLibrary, - const cmTarget &tgt) -{ - // Try to emit each search path once - std::set<cmStdString> emitted; - - // Embed runtime search paths if possible and if required. - bool outputRuntime = true; - std::string runtimeFlag; - std::string runtimeSep; - std::vector<std::string> runtimeDirs; - - std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - buildType = cmSystemTools::UpperCase(buildType); - - 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!="" ); - if(runtimeFlag == "" || m_Makefile->IsOn("CMAKE_SKIP_RPATH") ) - { - outputRuntime = false; - } - - // Some search paths should never be emitted - emitted.insert(""); - emitted.insert("/usr/lib"); - std::string libPathFlag = m_Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG"); - std::string libLinkFlag = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG"); - // collect all the flags needed for linking libraries - 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 ) - { - linkLibs = m_Makefile->GetSafeDefinition(linkFlagsVar.c_str()); - linkLibs += " "; - } - - const std::vector<std::string>& libdirs = tgt.GetLinkDirectories(); - for(std::vector<std::string>::const_iterator libDir = libdirs.begin(); - libDir != libdirs.end(); ++libDir) - { - std::string libpath = this->ConvertToOutputForExisting(libDir->c_str()); - if(emitted.insert(libpath).second) - { - std::string fullLibPath; - if(!m_WindowsShell && m_UseRelativePaths) - { - fullLibPath = "\"`cd "; - } - fullLibPath += libpath; - if(!m_WindowsShell && m_UseRelativePaths) - { - fullLibPath += ";pwd`\""; - } - std::string::size_type pos = libDir->find(libPathFlag.c_str()); - if((pos == std::string::npos || pos > 0) - && libDir->find("${") == std::string::npos) - { - linkLibs += libPathFlag; - if(outputRuntime) - { - runtimeDirs.push_back( fullLibPath ); - } - } - linkLibs += fullLibPath; - linkLibs += " "; - } - } - - std::string linkSuffix = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"); - std::string regexp = ".*\\"; - regexp += linkSuffix; - regexp += "$"; - cmsys::RegularExpression hasSuffix(regexp.c_str()); - std::string librariesLinked; - const cmTarget::LinkLibraries& libs = tgt.GetLinkLibraries(); - for(cmTarget::LinkLibraries::const_iterator lib = libs.begin(); - lib != libs.end(); ++lib) - { - // Don't link the library against itself! - if(targetLibrary && (lib->first == targetLibrary)) continue; - // use the correct lib for the current configuration - if (lib->second == cmTarget::DEBUG && buildType != "DEBUG") - { - continue; - } - if (lib->second == cmTarget::OPTIMIZED && buildType == "DEBUG") - { - continue; - } - // skip zero size library entries, this may happen - // if a variable expands to nothing. - if (lib->first.size() == 0) continue; - // if it is a full path break it into -L and -l - cmsys::RegularExpression reg("^([ \t]*\\-[lWRB])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)"); - if(lib->first.find('/') != std::string::npos - && !reg.find(lib->first)) - { - std::string dir, file; - cmSystemTools::SplitProgramPath(lib->first.c_str(), - dir, file); - std::string libpath = this->ConvertToOutputForExisting(dir.c_str()); - if(emitted.insert(libpath).second) - { - linkLibs += libPathFlag; - linkLibs += libpath; - linkLibs += " "; - if(outputRuntime) - { - runtimeDirs.push_back( libpath ); - } - } - cmsys::RegularExpression libname("^lib([^/]*)(\\.so|\\.lib|\\.dll|\\.sl|\\.a|\\.dylib).*"); - cmsys::RegularExpression libname_noprefix("([^/]*)(\\.so|\\.lib|\\.dll|\\.sl|\\.a|\\.dylib).*"); - if(libname.find(file)) - { - // Library had "lib" prefix. - librariesLinked += libLinkFlag; - file = libname.match(1); - // if ignore libprefix is on, - // then add the lib prefix back into the name - if(m_IgnoreLibPrefix) - { - file = "lib" + file; - } - librariesLinked += file; - if(linkSuffix.size() && !hasSuffix.find(file)) - { - librariesLinked += linkSuffix; - } - librariesLinked += " "; - } - else if(libname_noprefix.find(file)) - { - // Library had no "lib" prefix. - librariesLinked += libLinkFlag; - file = libname_noprefix.match(1); - librariesLinked += file; - if(linkSuffix.size() && !hasSuffix.find(file)) - { - librariesLinked += linkSuffix; - } - librariesLinked += " "; - } - else - { - // Error parsing the library name. Just use the full path. - // The linker will give an error if it is invalid. - librariesLinked += lib->first; - librariesLinked += " "; - } - } - // not a full path, so add -l name - else - { - if(!reg.find(lib->first)) - { - librariesLinked += libLinkFlag; - } - librariesLinked += lib->first; - if(linkSuffix.size() && !hasSuffix.find(lib->first)) - { - librariesLinked += linkSuffix; - } - librariesLinked += " "; - } - } - - linkLibs += librariesLinked; - - fout << linkLibs; - - if(outputRuntime && runtimeDirs.size()>0) - { - // For the runtime search directories, do a "-Wl,-rpath,a:b:c" or - // a "-R a -R b -R c" type link line - fout << runtimeFlag; - std::vector<std::string>::iterator itr = runtimeDirs.begin(); - fout << *itr; - ++itr; - for( ; itr != runtimeDirs.end(); ++itr ) - { - if(runtimeConcatenate) - { - fout << runtimeSep << *itr; - } - else - { - fout << " " << runtimeFlag << *itr; - } - } - fout << " "; - } - if(m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES")) - { - fout << m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES") << " "; - } -} std::string cmLocalUnixMakefileGenerator::CreatePreBuildRules( const cmTarget &target, const char* /* targetName */) @@ -974,163 +699,6 @@ std::string cmLocalUnixMakefileGenerator::CreatePostBuildRules( return customRuleCode; } -struct RuleVariables -{ - const char* variable; -}; - - -// 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_${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 -}; - - - - -void -cmLocalUnixMakefileGenerator::ExpandRuleVariables(std::string& s, - const char* lang, - const char* objects, - const char* target, - const char* linkLibs, - const char* source, - const char* object, - const char* flags, - const char* objectsquoted, - const char* targetBase, - const char* targetSOName, - const char* linkFlags) -{ - std::vector<std::string> enabledLanguages; - m_GlobalGenerator->GetEnabledLanguages(enabledLanguages); - - if(linkFlags) - { - cmSystemTools::ReplaceString(s, "<LINK_FLAGS>", linkFlags); - } - if(flags) - { - cmSystemTools::ReplaceString(s, "<FLAGS>", flags); - } - - if(source) - { - cmSystemTools::ReplaceString(s, "<SOURCE>", source); - } - if(object) - { - cmSystemTools::ReplaceString(s, "<OBJECT>", object); - } - if(objects) - { - cmSystemTools::ReplaceString(s, "<OBJECTS>", objects); - } - if(objectsquoted) - { - cmSystemTools::ReplaceString(s, "<OBJECTS_QUOTED>", objectsquoted); - } - if(target) - { - std::string targetQuoted = target; - if(targetQuoted.size() && targetQuoted[0] != '\"') - { - targetQuoted = '\"'; - targetQuoted += target; - targetQuoted += '\"'; - } - cmSystemTools::ReplaceString(s, "<TARGET_QUOTED>", targetQuoted.c_str()); - cmSystemTools::ReplaceString(s, "<TARGET>", target); - } - if(targetBase) - { - // special case for quoted paths with spaces - // if you see <TARGET_BASE>.lib then put the .lib inside - // the quotes, same for .dll - if((strlen(targetBase) > 1) && targetBase[0] == '\"') - { - std::string base = targetBase; - base[base.size()-1] = '.'; - std::string baseLib = base + "lib\""; - std::string baseDll = base + "dll\""; - cmSystemTools::ReplaceString(s, "<TARGET_BASE>.lib", baseLib.c_str()); - cmSystemTools::ReplaceString(s, "<TARGET_BASE>.dll", baseDll.c_str()); - } - cmSystemTools::ReplaceString(s, "<TARGET_BASE>", targetBase); - } - if(targetSOName) - { - bool replaced = false; - if(lang) - { - std::string name = "CMAKE_SHARED_LIBRARY_SONAME_"; - name += lang; - name += "_FLAG"; - if(m_Makefile->GetDefinition(name.c_str())) - { - replaced = true; - cmSystemTools::ReplaceString(s, "<TARGET_SONAME>", targetSOName); - } - } - if(!replaced) - { - cmSystemTools::ReplaceString(s, "<TARGET_SONAME>", ""); - } - } - if(linkLibs) - { - cmSystemTools::ReplaceString(s, "<LINK_LIBRARIES>", linkLibs); - } - - // loop over language specific replace variables - int pos = 0; - while(ruleReplaceVars[pos]) - { - for(std::vector<std::string>::iterator i = enabledLanguages.begin(); - i != enabledLanguages.end(); ++i) - { - lang = i->c_str(); - std::string replace = "<"; - replace += ruleReplaceVars[pos]; - replace += ">"; - std::string replaceWith = ruleReplaceVars[pos]; - std::string actualReplace = replace; - cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang); - std::string actualReplaceWith = replaceWith; - cmSystemTools::ReplaceString(actualReplaceWith, "${LANG}", lang); - 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()); - } - if(actualReplace.size()) - { - cmSystemTools::ReplaceString(s, actualReplace.c_str(), replace.c_str()); - } - } - pos++; - } -} - - void cmLocalUnixMakefileGenerator::OutputLibraryRule(std::ostream& fout, const char* name, @@ -2459,25 +2027,6 @@ void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout) } } -std::string -cmLocalUnixMakefileGenerator::ConvertToOutputForExisting(const char* p) -{ - std::string ret = this->ConvertToRelativeOutputPath(p); - // if there are spaces in the path, then get the short path version - // if there is one - if(ret.find(' ') != std::string::npos) - { - if(cmSystemTools::FileExists(p)) - { - if(!cmSystemTools::GetShortPath(ret.c_str(), ret)) - { - ret = this->ConvertToRelativeOutputPath(p); - } - } - } - return ret; -} - void cmLocalUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout) { @@ -2532,118 +2081,6 @@ void cmLocalUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout) fout << "\n\n"; } -const char* cmLocalUnixMakefileGenerator::GetIncludeFlags(const char* lang) -{ - if(!lang) - { - return ""; - } - if(m_LanguageToIncludeFlags.count(lang)) - { - return m_LanguageToIncludeFlags[lang].c_str(); - } - // Output Include paths - cmOStringStream includeFlags; - std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories(); - std::vector<std::string>::iterator i; - std::map<cmStdString, cmStdString> implicitIncludes; - - // CMake versions below 2.0 would add the source tree to the -I path - // automatically. Preserve compatibility. - bool includeSourceDir = false; - const char* versionValue = - m_Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY"); - if(versionValue) - { - int major = 0; - int minor = 0; - if(sscanf(versionValue, "%d.%d", &major, &minor) == 2 && major < 2) - { - includeSourceDir = true; - } - } - const char* vtkSourceDir = - m_Makefile->GetDefinition("VTK_SOURCE_DIR"); - if(vtkSourceDir) - { - // Special hack for VTK 4.0 - 4.4. - const char* vtk_major = m_Makefile->GetDefinition("VTK_MAJOR_VERSION"); - const char* vtk_minor = m_Makefile->GetDefinition("VTK_MINOR_VERSION"); - vtk_major = vtk_major? vtk_major : "4"; - vtk_minor = vtk_minor? vtk_minor : "4"; - int major = 0; - int minor = 0; - if(sscanf(vtk_major, "%d", &major) && sscanf(vtk_minor, "%d", &minor) && - major == 4 && minor <= 4) - { - 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) - { - includeFlags << includeFlag - << this->ConvertToOutputForExisting(m_Makefile->GetStartDirectory()) - << sep; - flagUsed = true; - } - - implicitIncludes["/usr/include"] = "/usr/include"; - if(m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES")) - { - std::string arg = m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES"); - std::vector<std::string> implicitIncludeVec; - cmSystemTools::ExpandListArgument(arg, implicitIncludeVec); - for(unsigned int k =0; k < implicitIncludeVec.size(); k++) - { - implicitIncludes[implicitIncludeVec[k]] = implicitIncludeVec[k]; - } - } - - for(i = includes.begin(); i != includes.end(); ++i) - { - std::string include = *i; - // Don't output a -I for the standard include path "/usr/include". - // This can cause problems with certain standard library - // implementations because the wrong headers may be found first. - if(implicitIncludes.find(include) == implicitIncludes.end()) - { - if(!flagUsed || repeatFlag) - { - includeFlags << includeFlag; - flagUsed = true; - } - includeFlags << this->ConvertToOutputForExisting(i->c_str()) << sep; - } - } - 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].c_str(); -} void cmLocalUnixMakefileGenerator::OutputMakeRules(std::ostream& fout) { |