ENH: mark some vars as advanced (and resort the list)
[cmake.git] / Source / cmLocalUnixMakefileGenerator.cxx
blob73674e0418a284fb83144c7ed1cee63f5ee0a027
1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: cmLocalUnixMakefileGenerator.cxx,v $
5 Language: C++
6 Date: $Date: 2002-10-10 14:43:59 $
7 Version: $Revision: 1.17 $
9 Copyright (c) 2002 Insight Consortium. All rights reserved.
10 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmGlobalGenerator.h"
18 #include "cmLocalUnixMakefileGenerator.h"
19 #include "cmMakefile.h"
20 #include "cmSystemTools.h"
21 #include "cmSourceFile.h"
22 #include "cmMakeDepend.h"
23 #include "cmCacheManager.h"
24 #include "cmGeneratedFileStream.h"
26 cmLocalUnixMakefileGenerator::cmLocalUnixMakefileGenerator()
27 :m_SharedLibraryExtension("$(SHLIB_SUFFIX)"),
28 m_ObjectFileExtension(".o"),
29 m_ExecutableExtension(cmSystemTools::GetExecutableExtension()),
30 m_StaticLibraryExtension(".a"),
31 m_LibraryPrefix("lib")
35 cmLocalUnixMakefileGenerator::~cmLocalUnixMakefileGenerator()
40 void cmLocalUnixMakefileGenerator::Generate(bool fromTheTop)
42 // for backwards compatibility if niether c or cxx is
43 // enabled, the enable cxx
44 if(! (m_GlobalGenerator->GetLanguageEnabled("C") ||
45 m_GlobalGenerator->GetLanguageEnabled("CXX")))
47 m_GlobalGenerator->EnableLanguage("CXX",m_Makefile);
51 // suppoirt override in output directories
52 if (m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
54 m_LibraryOutputPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
55 if(m_LibraryOutputPath.size())
57 if(m_LibraryOutputPath[m_LibraryOutputPath.size() -1] != '/')
59 m_LibraryOutputPath += "/";
61 if(!cmSystemTools::MakeDirectory(m_LibraryOutputPath.c_str()))
63 cmSystemTools::Error("Error failed create "
64 "LIBRARY_OUTPUT_PATH directory:",
65 m_LibraryOutputPath.c_str());
67 m_Makefile->AddLinkDirectory(m_LibraryOutputPath.c_str());
70 if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
72 m_ExecutableOutputPath =
73 m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
74 if(m_ExecutableOutputPath.size())
76 if(m_ExecutableOutputPath[m_ExecutableOutputPath.size() -1] != '/')
78 m_ExecutableOutputPath += "/";
80 if(!cmSystemTools::MakeDirectory(m_ExecutableOutputPath.c_str()))
82 cmSystemTools::Error("Error failed to create "
83 "EXECUTABLE_OUTPUT_PATH directory:",
84 m_ExecutableOutputPath.c_str());
86 m_Makefile->AddLinkDirectory(m_ExecutableOutputPath.c_str());
90 if (!fromTheTop)
92 // Generate depends
93 cmMakeDepend md;
94 md.SetMakefile(m_Makefile);
95 md.GenerateMakefileDependencies();
96 this->ProcessDepends(md);
98 // output the makefile fragment
99 std::string dest = m_Makefile->GetStartOutputDirectory();
100 dest += "/Makefile";
101 this->OutputMakefile(dest.c_str(), !fromTheTop);
104 void cmLocalUnixMakefileGenerator::ProcessDepends(const cmMakeDepend &md)
106 // Now create cmDependInformation objects for files in the directory
107 cmTargets &tgts = m_Makefile->GetTargets();
108 for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
110 std::vector<cmSourceFile*> &classes = l->second.GetSourceFiles();
111 for(std::vector<cmSourceFile*>::iterator i = classes.begin();
112 i != classes.end(); ++i)
114 if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY"))
116 // get the depends
117 const cmDependInformation *info =
118 md.GetDependInformationForSourceFile(*(*i));
120 // Delete any hints from the source file's dependencies.
121 (*i)->GetDepends().erase((*i)->GetDepends().begin(), (*i)->GetDepends().end());
123 // Now add the real dependencies for the file.
124 if (info)
126 for(cmDependInformation::DependencySet::const_iterator d =
127 info->m_DependencySet.begin();
128 d != info->m_DependencySet.end(); ++d)
130 // Make sure the full path is given. If not, the dependency was
131 // not found.
132 if((*d)->m_FullPath != "")
134 (*i)->GetDepends().push_back((*d)->m_FullPath);
144 // This is where CMakeTargets.make is generated
145 void cmLocalUnixMakefileGenerator::OutputMakefile(const char* file,
146 bool withDepends)
148 // Create sub directories fro aux source directories
149 std::vector<std::string>& auxSourceDirs =
150 m_Makefile->GetAuxSourceDirectories();
151 if( auxSourceDirs.size() )
153 // For the case when this is running as a remote build
154 // on unix, make the directory
155 for(std::vector<std::string>::iterator i = auxSourceDirs.begin();
156 i != auxSourceDirs.end(); ++i)
158 if(i->c_str()[0] != '/')
160 std::string dir = m_Makefile->GetCurrentOutputDirectory();
161 if(dir.size() && dir[dir.size()-1] != '/')
163 dir += "/";
165 dir += *i;
166 cmSystemTools::MakeDirectory(dir.c_str());
168 else
170 cmSystemTools::MakeDirectory(i->c_str());
174 // Create a stream that writes to a temporary file
175 // then does a copy at the end. This is to allow users
176 // to hit control-c during the make of the makefile
177 cmGeneratedFileStream tempFile(file);
178 tempFile.SetAlwaysCopy(true);
179 std::ostream& fout = tempFile.GetStream();
180 if(!fout)
182 cmSystemTools::Error("Error can not open for write: ", file);
183 return;
185 fout << "# CMAKE generated Makefile, DO NOT EDIT!\n"
186 << "# Generated by \"" << m_GlobalGenerator->GetName() << "\""
187 << " Generator, CMake Version "
188 << cmMakefile::GetMajorVersion() << "."
189 << cmMakefile::GetMinorVersion() << "\n"
190 << "# Generated from the following files:\n# "
191 << m_Makefile->GetHomeOutputDirectory() << "/CMakeCache.txt\n";
192 std::vector<std::string> lfiles = m_Makefile->GetListFiles();
193 // sort the array
194 std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
195 // remove duplicates
196 std::vector<std::string>::iterator new_end =
197 std::unique(lfiles.begin(), lfiles.end());
198 lfiles.erase(new_end, lfiles.end());
200 for(std::vector<std::string>::const_iterator i = lfiles.begin();
201 i != lfiles.end(); ++i)
203 fout << "# " << i->c_str() << "\n";
205 fout << "\n\n";
206 fout << "# Suppresses display of executed commands\n";
207 fout << ".SILENT:\n";
208 fout << "# disable some common implicit rules to speed things up\n";
209 fout << ".SUFFIXES:\n";
210 fout << ".SUFFIXES:.hpuxmakemusthaverule\n";
211 // create a make variable with all of the sources for this Makefile
212 // for depend purposes.
213 fout << "CMAKE_MAKEFILE_SOURCES = ";
214 for(std::vector<std::string>::const_iterator i = lfiles.begin();
215 i != lfiles.end(); ++i)
217 fout << " " << cmSystemTools::ConvertToOutputPath(i->c_str());
219 // Add the cache to the list
220 std::string cacheFile = m_Makefile->GetHomeOutputDirectory();
221 cacheFile += "/CMakeCache.txt";
222 fout << " " << cmSystemTools::ConvertToOutputPath(cacheFile.c_str());
223 fout << "\n\n\n";
224 this->OutputMakeVariables(fout);
225 // Set up the default target as the VERY first target, so that make with no arguments will run it
226 this->
227 OutputMakeRule(fout,
228 "Default target executed when no arguments are given to make, first make sure cmake.depends exists, cmake.check_depends is up-to-date, check the sources, then build the all target",
229 "default_target",
231 "$(MAKE) $(MAKESILENT) cmake.depends",
232 "$(MAKE) $(MAKESILENT) cmake.check_depends",
233 "$(MAKE) $(MAKESILENT) -f cmake.check_depends",
234 "$(MAKE) $(MAKESILENT) all");
236 this->OutputTargetRules(fout);
237 this->OutputDependLibs(fout);
238 this->OutputTargets(fout);
239 this->OutputSubDirectoryRules(fout);
240 std::string dependName = m_Makefile->GetStartOutputDirectory();
241 dependName += "/cmake.depends";
242 if(withDepends)
244 std::ofstream dependout(dependName.c_str());
245 if(!dependout)
247 cmSystemTools::Error("Error can not open for write: ", dependName.c_str());
248 return;
250 dependout << "# .o dependencies in this directory." << std::endl;
252 std::string checkDepend = m_Makefile->GetStartOutputDirectory();
253 checkDepend += "/cmake.check_depends";
254 std::ofstream checkdependout(checkDepend.c_str());
255 if(!checkdependout)
257 cmSystemTools::Error("Error can not open for write: ", checkDepend.c_str());
258 return;
260 checkdependout << "# This file is used as a tag file, that all sources depend on. If a source changes, then the rule to rebuild this file will cause cmake.depends to be rebuilt." << std::endl;
261 // if there were any depends output, then output the check depends
262 // information inot checkdependout
263 if(this->OutputObjectDepends(dependout))
265 this->OutputCheckDepends(checkdependout);
267 else
269 checkdependout << "all:\n\t@echo cmake.depends is up-to-date\n";
272 this->OutputCustomRules(fout);
273 this->OutputMakeRules(fout);
274 this->OutputInstallRules(fout);
275 // only add the depend include if the depend file exists
276 if(cmSystemTools::FileExists(dependName.c_str()))
278 this->OutputIncludeMakefile(fout, "cmake.depends");
282 void cmLocalUnixMakefileGenerator::OutputIncludeMakefile(std::ostream& fout,
283 const char* file)
285 fout << "include " << file << "\n";
289 std::string
290 cmLocalUnixMakefileGenerator::GetOutputExtension(const char*)
292 return m_ObjectFileExtension;
297 // Output the rules for any targets
298 void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
300 // for each target add to the list of targets
301 fout << "TARGETS = ";
302 const cmTargets &tgts = m_Makefile->GetTargets();
303 // list libraries first
304 for(cmTargets::const_iterator l = tgts.begin();
305 l != tgts.end(); l++)
307 if (l->second.IsInAll())
309 std::string path = m_LibraryOutputPath + m_LibraryPrefix;
310 if(l->second.GetType() == cmTarget::STATIC_LIBRARY)
312 path = path + l->first + m_StaticLibraryExtension;
313 fout << " \\\n"
314 << cmSystemTools::ConvertToOutputPath(path.c_str());
316 else if(l->second.GetType() == cmTarget::SHARED_LIBRARY)
318 path = path + l->first +
319 m_Makefile->GetDefinition("CMAKE_SHLIB_SUFFIX");
320 fout << " \\\n"
321 << cmSystemTools::ConvertToOutputPath(path.c_str());
323 else if(l->second.GetType() == cmTarget::MODULE_LIBRARY)
325 path = path + l->first +
326 m_Makefile->GetDefinition("CMAKE_MODULE_SUFFIX");
327 fout << " \\\n"
328 << cmSystemTools::ConvertToOutputPath(path.c_str());
332 // executables
333 for(cmTargets::const_iterator l = tgts.begin();
334 l != tgts.end(); l++)
336 if ((l->second.GetType() == cmTarget::EXECUTABLE ||
337 l->second.GetType() == cmTarget::WIN32_EXECUTABLE) &&
338 l->second.IsInAll())
340 std::string path = m_ExecutableOutputPath + l->first +
341 m_ExecutableExtension;
342 fout << " \\\n" << cmSystemTools::ConvertToOutputPath(path.c_str());
345 // list utilities last
346 for(cmTargets::const_iterator l = tgts.begin();
347 l != tgts.end(); l++)
349 if (l->second.GetType() == cmTarget::UTILITY &&
350 l->second.IsInAll())
352 fout << " \\\n" << l->first.c_str();
355 fout << "\n\n";
356 // get the classes from the source lists then add them to the groups
357 for(cmTargets::const_iterator l = tgts.begin();
358 l != tgts.end(); l++)
360 std::vector<cmSourceFile*> classes = l->second.GetSourceFiles();
361 if (classes.begin() != classes.end())
363 fout << this->CreateMakeVariable(l->first.c_str(), "_SRC_OBJS") << " = ";
364 for(std::vector<cmSourceFile*>::iterator i = classes.begin();
365 i != classes.end(); i++)
367 if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY"))
369 std::string outExt(this->GetOutputExtension((*i)->GetSourceExtension().c_str()));
370 if(outExt.size())
372 fout << "\\\n" << cmSystemTools::ConvertToOutputPath((*i)->GetSourceName().c_str())
373 << outExt.c_str() << " ";
377 fout << "\n\n";
378 fout << this->CreateMakeVariable(l->first.c_str(), "_SRC_OBJS_QUOTED") << " = ";
379 for(std::vector<cmSourceFile*>::iterator i = classes.begin();
380 i != classes.end(); i++)
382 if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY"))
384 std::string outExt(this->GetOutputExtension((*i)->GetSourceExtension().c_str()));
385 if(outExt.size())
387 fout << "\\\n\"" << cmSystemTools::ConvertToOutputPath((*i)->GetSourceName().c_str())
388 << outExt.c_str() << "\" ";
392 fout << "\n\n";
395 fout << "CLEAN_OBJECT_FILES = ";
396 for(cmTargets::const_iterator l = tgts.begin();
397 l != tgts.end(); l++)
399 std::vector<cmSourceFile*> classes = l->second.GetSourceFiles();
400 if (classes.begin() != classes.end())
402 fout << "$(" << this->CreateMakeVariable(l->first.c_str(), "_SRC_OBJS")
403 << ") ";
406 fout << "\n\n";
407 const char * qt_files = m_Makefile->GetDefinition("GENERATED_QT_FILES");
408 if (qt_files != NULL &&
409 strlen(m_Makefile->GetDefinition("GENERATED_QT_FILES"))>0)
411 fout << "GENERATED_QT_FILES = ";
412 fout << qt_files;
413 fout << "\n\n";
419 * Output the linking rules on a command line. For executables,
420 * targetLibrary should be a NULL pointer. For libraries, it should point
421 * to the name of the library. This will not link a library against itself.
423 void cmLocalUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout,
424 const char* targetLibrary,
425 const cmTarget &tgt)
427 // Try to emit each search path once
428 std::set<std::string> emitted;
430 // Embed runtime search paths if possible and if required.
431 bool outputRuntime = true;
432 std::string runtimeFlag;
433 std::string runtimeSep;
434 std::vector<std::string> runtimeDirs;
436 bool cxx = tgt.HasCxx();
437 if(!cxx )
439 // if linking a c executable use the C runtime flag as cc
440 // may not be the same program that creates shared libaries
441 // and may have different flags
442 if( tgt.GetType() == cmTarget::EXECUTABLE)
444 if(m_Makefile->GetDefinition("CMAKE_C_SHLIB_RUNTIME_FLAG"))
446 runtimeFlag = m_Makefile->GetDefinition("CMAKE_C_SHLIB_RUNTIME_FLAG");
449 else
451 if(m_Makefile->GetDefinition("CMAKE_SHLIB_RUNTIME_FLAG"))
453 runtimeFlag = m_Makefile->GetDefinition("CMAKE_SHLIB_RUNTIME_FLAG");
456 if(m_Makefile->GetDefinition("CMAKE_SHLIB_RUNTIME_SEP"))
458 runtimeSep = m_Makefile->GetDefinition("CMAKE_SHLIB_RUNTIME_SEP");
461 else
463 if(m_Makefile->GetDefinition("CMAKE_CXX_SHLIB_RUNTIME_FLAG"))
465 runtimeFlag = m_Makefile->GetDefinition("CMAKE_CXX_SHLIB_RUNTIME_FLAG");
468 if(m_Makefile->GetDefinition("CMAKE_CXX_SHLIB_RUNTIME_SEP"))
470 runtimeSep = m_Makefile->GetDefinition("CMAKE_CXX_SHLIB_RUNTIME_SEP");
476 // concatenate all paths or no?
477 bool runtimeConcatenate = ( runtimeSep!="" );
478 if(runtimeFlag == "" || m_Makefile->IsOn("CMAKE_SKIP_RPATH") )
480 outputRuntime = false;
483 // Some search paths should never be emitted
484 emitted.insert("");
485 emitted.insert("/usr/lib");
487 // collect all the flags needed for linking libraries
488 std::string linkLibs;
489 const std::vector<std::string>& libdirs = tgt.GetLinkDirectories();
490 for(std::vector<std::string>::const_iterator libDir = libdirs.begin();
491 libDir != libdirs.end(); ++libDir)
493 std::string libpath = cmSystemTools::ConvertToOutputPath(libDir->c_str());
494 if(emitted.insert(libpath).second)
496 std::string::size_type pos = libDir->find("-L");
497 if((pos == std::string::npos || pos > 0)
498 && libDir->find("${") == std::string::npos)
500 linkLibs += "-L";
501 if(outputRuntime)
503 runtimeDirs.push_back( libpath );
506 linkLibs += libpath;
507 linkLibs += " ";
511 std::string librariesLinked;
512 const cmTarget::LinkLibraries& libs = tgt.GetLinkLibraries();
513 for(cmTarget::LinkLibraries::const_iterator lib = libs.begin();
514 lib != libs.end(); ++lib)
516 // Don't link the library against itself!
517 if(targetLibrary && (lib->first == targetLibrary)) continue;
518 // don't look at debug libraries
519 if (lib->second == cmTarget::DEBUG) continue;
520 // skip zero size library entries, this may happen
521 // if a variable expands to nothing.
522 if (lib->first.size() == 0) continue;
523 // if it is a full path break it into -L and -l
524 cmRegularExpression reg("([ \t]*\\-l)|([ \t]*\\-framework)|(\\${)");
525 if(lib->first.find('/') != std::string::npos
526 && !reg.find(lib->first))
528 std::string dir, file;
529 cmSystemTools::SplitProgramPath(lib->first.c_str(),
530 dir, file);
531 std::string libpath = cmSystemTools::ConvertToOutputPath(dir.c_str());
532 if(emitted.insert(libpath).second)
534 linkLibs += "-L";
535 linkLibs += libpath;
536 linkLibs += " ";
537 if(outputRuntime)
539 runtimeDirs.push_back( libpath );
542 cmRegularExpression libname("lib(.*)(\\.so|\\.sl|\\.a|\\.dylib).*");
543 cmRegularExpression libname_noprefix("(.*)(\\.so|\\.sl|\\.a|\\.dylib).*");
544 if(libname.find(file))
546 librariesLinked += "-l";
547 file = libname.match(1);
548 librariesLinked += file;
549 librariesLinked += " ";
551 else if(libname_noprefix.find(file))
553 librariesLinked += "-l";
554 file = libname_noprefix.match(1);
555 librariesLinked += file;
556 librariesLinked += " ";
559 // not a full path, so add -l name
560 else
562 if(!reg.find(lib->first))
564 librariesLinked += "-l";
566 librariesLinked += lib->first;
567 librariesLinked += " ";
571 linkLibs += librariesLinked;
573 fout << linkLibs;
575 if(outputRuntime && runtimeDirs.size()>0)
577 // For the runtime search directories, do a "-Wl,-rpath,a:b:c" or
578 // a "-R a -R b -R c" type link line
579 fout << runtimeFlag;
580 std::vector<std::string>::iterator itr = runtimeDirs.begin();
581 fout << *itr;
582 ++itr;
583 for( ; itr != runtimeDirs.end(); ++itr )
585 if(runtimeConcatenate)
587 fout << runtimeSep << *itr;
589 else
591 fout << " " << runtimeFlag << *itr;
594 fout << " ";
599 std::string cmLocalUnixMakefileGenerator::CreateTargetRules(const cmTarget &target,
600 const char* targetName)
602 std::string customRuleCode = "";
603 bool initNext = false;
604 for (std::vector<cmCustomCommand>::const_iterator cr =
605 target.GetCustomCommands().begin();
606 cr != target.GetCustomCommands().end(); ++cr)
608 cmCustomCommand cc(*cr);
609 cc.ExpandVariables(*m_Makefile);
610 if (cc.GetSourceName() == targetName)
612 if(initNext)
614 customRuleCode += "\n\t";
616 else
618 initNext = true;
620 std::string command = cmSystemTools::ConvertToOutputPath(cc.GetCommand().c_str());
621 customRuleCode += command + " " + cc.GetArguments();
624 return customRuleCode;
628 void cmLocalUnixMakefileGenerator::OutputSharedLibraryRule(std::ostream& fout,
629 const char* name,
630 const cmTarget &t)
632 std::string target = m_LibraryOutputPath + "lib" + name + "$(SHLIB_SUFFIX)";
633 std::string depend = "$(";
634 depend += this->CreateMakeVariable(name, "_SRC_OBJS");
635 depend += ") $(" + this->CreateMakeVariable(name, "_DEPEND_LIBS") + ")";
636 std::string command = "$(RM) lib";
637 command += name;
638 command += "$(SHLIB_SUFFIX)";
639 std::string command2;
640 if(t.HasCxx())
642 command2 = "$(CMAKE_CXX_LINK_SHARED) $(CMAKE_CXX_SHLIB_LINK_FLAGS) "
643 "$(CMAKE_CXX_SHLIB_BUILD_FLAGS) $(CMAKE_CXX_FLAGS) -o \\\n";
645 else
647 command2 = "$(CMAKE_C_LINK_SHARED) $(CMAKE_SHLIB_LINK_FLAGS) "
648 "$(CMAKE_SHLIB_BUILD_FLAGS) -o \\\n";
650 command2 += "\t ";
651 std::string libName = m_LibraryOutputPath + "lib" + std::string(name) + "$(SHLIB_SUFFIX)";
652 libName = cmSystemTools::ConvertToOutputPath(libName.c_str());
653 command2 += libName + " \\\n";
654 command2 += "\t $(" + this->CreateMakeVariable(name, "_SRC_OBJS") + ") ";
655 cmOStringStream linklibs;
656 this->OutputLinkLibraries(linklibs, name, t);
657 command2 += linklibs.str();
658 std::string customCommands = this->CreateTargetRules(t, name);
659 const char* cc = 0;
660 if(customCommands.size() > 0)
662 cc = customCommands.c_str();
664 this->OutputMakeRule(fout, "rules for a shared library",
665 target.c_str(),
666 depend.c_str(),
667 command.c_str(),
668 command2.c_str(),
669 cc);
672 void cmLocalUnixMakefileGenerator::OutputModuleLibraryRule(std::ostream& fout,
673 const char* name,
674 const cmTarget &t)
676 std::string target = m_LibraryOutputPath + "lib" + std::string(name) + "$(MODULE_SUFFIX)";
677 std::string depend = "$(";
678 depend += this->CreateMakeVariable(name, "_SRC_OBJS")
679 + ") $(" + this->CreateMakeVariable(name, "_DEPEND_LIBS") + ")";
680 std::string command = "$(RM) lib" + std::string(name) + "$(MODULE_SUFFIX)";
681 std::string command2;
682 if(t.HasCxx())
684 command2 = "$(CMAKE_CXX_LINK_SHARED) $(CMAKE_CXX_MODULE_LINK_FLAGS) "
685 "$(CMAKE_CXX_MODULE_BUILD_FLAGS) $(CMAKE_CXX_FLAGS) -o \\\n";
687 else
689 command2 = "$(CMAKE_C_LINK_SHARED) $(CMAKE_SHLIB_LINK_FLAGS) "
690 "$(CMAKE_MODULE_BUILD_FLAGS) -o \\\n";
692 command2 += "\t ";
693 std::string libName = m_LibraryOutputPath + "lib" + std::string(name) + "$(MODULE_SUFFIX)";
694 libName = cmSystemTools::ConvertToOutputPath(libName.c_str());
695 command2 += libName + " \\\n";
696 command2 += "\t $(" + this->CreateMakeVariable(name, "_SRC_OBJS") + ") ";
697 cmOStringStream linklibs;
698 this->OutputLinkLibraries(linklibs, std::string(name).c_str(), t);
699 command2 += linklibs.str();
700 std::string customCommands = this->CreateTargetRules(t, name);
701 const char* cc = 0;
702 if(customCommands.size() > 0)
704 cc = customCommands.c_str();
706 this->OutputMakeRule(fout, "rules for a shared module library",
707 target.c_str(),
708 depend.c_str(),
709 command.c_str(),
710 command2.c_str(),
711 cc);
715 void cmLocalUnixMakefileGenerator::OutputStaticLibraryRule(std::ostream& fout,
716 const char* name,
717 const cmTarget &t)
719 std::string target = m_LibraryOutputPath + "lib" + std::string(name) + ".a";
720 target = cmSystemTools::ConvertToOutputPath(target.c_str());
721 std::string depend = "$(";
722 depend += this->CreateMakeVariable(name, "_SRC_OBJS") + ")";
723 std::string command;
724 if(t.HasCxx())
726 command = "$(CMAKE_CXX_AR) $(CMAKE_CXX_AR_ARGS) ";
728 else
730 command = "$(CMAKE_AR) $(CMAKE_AR_ARGS) ";
732 command += target;
733 command += " $(";
734 command += this->CreateMakeVariable(name, "_SRC_OBJS") + ")";
735 std::string command2 = "$(CMAKE_RANLIB) ";
736 command2 += target;
737 std::string comment = "rule to build static library: ";
738 comment += name;
739 std::string customCommands = this->CreateTargetRules(t, name);
740 const char* cc = 0;
741 if(customCommands.size() > 0)
743 cc = customCommands.c_str();
745 this->OutputMakeRule(fout,
746 comment.c_str(),
747 target.c_str(),
748 depend.c_str(),
749 command.c_str(),
750 command2.c_str(),
751 cc);
754 void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout,
755 const char* name,
756 const cmTarget &t)
758 std::string target = m_ExecutableOutputPath + name + m_ExecutableExtension;
759 std::string depend = "$(";
760 depend += this->CreateMakeVariable(name, "_SRC_OBJS")
761 + ") $(" + this->CreateMakeVariable(name, "_DEPEND_LIBS") + ")";
762 std::string command;
763 if(t.HasCxx())
765 command =
766 "$(CMAKE_CXX_COMPILER) $(CMAKE_CXX_SHLIB_LINK_FLAGS) $(CMAKE_CXX_FLAGS) ";
768 else
770 command =
771 "$(CMAKE_C_COMPILER) $(CMAKE_C_SHLIB_LINK_FLAGS) $(CMAKE_C_FLAGS) ";
773 command += "$(" + this->CreateMakeVariable(name, "_SRC_OBJS") + ") ";
774 cmOStringStream linklibs;
775 this->OutputLinkLibraries(linklibs, 0, t);
776 command += linklibs.str();
777 std::string outputFile = m_ExecutableOutputPath + name;
778 command += " -o " + cmSystemTools::ConvertToOutputPath(outputFile.c_str());
779 std::string comment = "rule to build executable: ";
780 comment += name;
782 std::string customCommands = this->CreateTargetRules(t, name);
783 const char* cc = 0;
784 if(customCommands.size() > 0)
786 cc = customCommands.c_str();
788 this->OutputMakeRule(fout,
789 comment.c_str(),
790 target.c_str(),
791 depend.c_str(),
792 command.c_str(),
793 cc);
798 void cmLocalUnixMakefileGenerator::OutputUtilityRule(std::ostream& fout,
799 const char* name,
800 const cmTarget &t)
802 std::string customCommands = this->CreateTargetRules(t, name);
803 const char* cc = 0;
804 if(customCommands.size() > 0)
806 cc = customCommands.c_str();
808 std::string comment = "Rule to build Utility ";
809 comment += name;
810 std::string depends;
811 std::string replaceVars;
812 const std::vector<cmCustomCommand> &ccs = t.GetCustomCommands();
813 for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
814 i != ccs.end(); ++i)
816 const std::vector<std::string> & dep = i->GetDepends();
817 for(std::vector<std::string>::const_iterator d = dep.begin();
818 d != dep.end(); ++d)
820 depends += " \\\n";
821 replaceVars = *d;
822 m_Makefile->ExpandVariablesInString(replaceVars);
823 depends += cmSystemTools::ConvertToOutputPath(replaceVars.c_str());
826 this->OutputMakeRule(fout, comment.c_str(), name,
827 depends.c_str(), cc);
832 void cmLocalUnixMakefileGenerator::OutputTargets(std::ostream& fout)
834 // for each target
835 const cmTargets &tgts = m_Makefile->GetTargets();
836 for(cmTargets::const_iterator l = tgts.begin();
837 l != tgts.end(); l++)
839 switch(l->second.GetType())
841 case cmTarget::STATIC_LIBRARY:
842 this->OutputStaticLibraryRule(fout, l->first.c_str(), l->second);
843 break;
844 case cmTarget::SHARED_LIBRARY:
845 this->OutputSharedLibraryRule(fout, l->first.c_str(), l->second);
846 break;
847 case cmTarget::MODULE_LIBRARY:
848 this->OutputModuleLibraryRule(fout, l->first.c_str(), l->second);
849 break;
850 case cmTarget::EXECUTABLE:
851 case cmTarget::WIN32_EXECUTABLE:
852 this->OutputExecutableRule(fout, l->first.c_str(), l->second);
853 break;
854 case cmTarget::UTILITY:
855 this->OutputUtilityRule(fout, l->first.c_str(), l->second);
856 break;
857 // This is handled by the OutputCustomRules method
858 case cmTarget::INSTALL_FILES:
859 // This is handled by the OutputInstallRules method
860 case cmTarget::INSTALL_PROGRAMS:
861 // This is handled by the OutputInstallRules method
862 break;
869 // For each target that is an executable or shared library, generate
870 // the "<name>_DEPEND_LIBS" variable listing its library dependencies.
871 void cmLocalUnixMakefileGenerator::OutputDependLibs(std::ostream& fout)
873 // Build a set of libraries that will be linked into any target in
874 // this directory.
875 std::set<std::string> used;
877 // for each target
878 const cmTargets &tgts = m_Makefile->GetTargets();
879 for(cmTargets::const_iterator l = tgts.begin();
880 l != tgts.end(); l++)
882 // Each dependency should only be emitted once per target.
883 std::set<std::string> emitted;
884 if ((l->second.GetType() == cmTarget::SHARED_LIBRARY)
885 || (l->second.GetType() == cmTarget::MODULE_LIBRARY)
886 || (l->second.GetType() == cmTarget::EXECUTABLE)
887 || (l->second.GetType() == cmTarget::WIN32_EXECUTABLE))
889 fout << this->CreateMakeVariable(l->first.c_str(), "_DEPEND_LIBS") << " = ";
891 // A library should not depend on itself!
892 emitted.insert(l->first);
894 // Now, look at all link libraries specific to this target.
895 const cmTarget::LinkLibraries& tlibs = l->second.GetLinkLibraries();
896 for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin();
897 lib != tlibs.end(); ++lib)
899 // Record that this library was used.
900 used.insert(lib->first);
902 // Don't emit the same library twice for this target.
903 if(emitted.insert(lib->first).second)
905 // Output this dependency.
906 this->OutputLibDepend(fout, lib->first.c_str());
910 // Now, look at all utilities specific to this target.
911 const std::set<cmStdString>& tutils = l->second.GetUtilities();
912 for(std::set<cmStdString>::const_iterator util = tutils.begin();
913 util != tutils.end(); ++util)
915 // Record that this utility was used.
916 used.insert(*util);
918 // Don't emit the same utility twice for this target.
919 if(emitted.insert(*util).second)
921 // Output this dependency.
922 this->OutputExeDepend(fout, util->c_str());
926 fout << "\n";
930 fout << "\n";
932 // Loop over the libraries used and make sure there is a rule to
933 // build them in this makefile. If the library is in another
934 // directory, add a rule to jump to that directory and make sure it
935 // exists.
936 for(std::set<std::string>::const_iterator lib = used.begin();
937 lib != used.end(); ++lib)
939 // loop over the list of directories that the libraries might
940 // be in, looking for an ADD_LIBRARY(lib...) line. This would
941 // be stored in the cache
942 std::string libPath = *lib + "_CMAKE_PATH";
943 const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
944 // if cache and not the current directory add a rule, to
945 // jump into the directory and build for the first time
946 if(cacheValue &&
947 (!this->SamePath(m_Makefile->GetCurrentOutputDirectory(), cacheValue)))
949 // add the correct extension
950 std::string ltname = *lib+"_LIBRARY_TYPE";
951 const char* libType
952 = m_Makefile->GetDefinition(ltname.c_str());
953 // if it was a library..
954 if (libType)
956 std::string library = m_LibraryPrefix;
957 library += *lib;
958 std::string libpath = cacheValue;
959 if(libType && std::string(libType) == "SHARED")
961 library += m_Makefile->GetDefinition("CMAKE_SHLIB_SUFFIX");
963 else if(libType && std::string(libType) == "MODULE")
965 library += m_Makefile->GetDefinition("CMAKE_MODULE_SUFFIX");
967 else if(libType && std::string(libType) == "STATIC")
969 library += m_StaticLibraryExtension;
971 else
973 cmSystemTools::Error("Unknown library type!");
974 return;
976 if(m_LibraryOutputPath.size())
978 libpath = m_LibraryOutputPath;
980 else
982 libpath += "/";
984 libpath += library;
985 // put out a rule to build the library if it does not exist
986 this->OutputBuildTargetInDir(fout,
987 cacheValue,
988 library.c_str(),
989 libpath.c_str(),
990 m_Makefile->
991 GetDefinition("LIBRARY_OUTPUT_PATH")
994 // something other than a library...
995 else
997 std::string exepath = cacheValue;
998 if(m_ExecutableOutputPath.size())
1000 exepath = m_ExecutableOutputPath;
1002 else
1004 exepath += "/";
1006 exepath += *lib;
1007 this->OutputBuildTargetInDir(fout,
1008 cacheValue,
1009 lib->c_str(),
1010 exepath.c_str(),
1011 m_Makefile->
1012 GetDefinition("EXECUTABLE_OUTPUT_PATH")
1019 void cmLocalUnixMakefileGenerator::OutputBuildTargetInDir(std::ostream& fout,
1020 const char* path,
1021 const char* library,
1022 const char* fullpath,
1023 const char* outputPath)
1025 const char* makeTarget = library;
1026 if(outputPath && strcmp( outputPath, "" ) != 0)
1028 makeTarget = fullpath;
1030 fout << cmSystemTools::ConvertToOutputPath(fullpath)
1031 << ":\n\tcd " << cmSystemTools::ConvertToOutputPath(path)
1032 << "; $(MAKE) $(MAKESILENT) cmake.depends"
1033 << "; $(MAKE) $(MAKESILENT) cmake.check_depends"
1034 << "; $(MAKE) $(MAKESILENT) -f cmake.check_depends"
1035 << "; $(MAKE) $(MAKESILENT) "
1036 << cmSystemTools::ConvertToOutputPath(makeTarget) << "\n\n";
1040 bool cmLocalUnixMakefileGenerator::SamePath(const char* path1, const char* path2)
1042 return strcmp(path1, path2) == 0;
1045 void cmLocalUnixMakefileGenerator::OutputLibDepend(std::ostream& fout,
1046 const char* name)
1048 std::string libPath = name;
1049 libPath += "_CMAKE_PATH";
1050 const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
1051 if(cacheValue )
1053 // if there is a cache value, then this is a library that cmake
1054 // knows how to build, so we can depend on it
1055 std::string libpath;
1056 if (!this->SamePath(m_Makefile->GetCurrentOutputDirectory(), cacheValue))
1058 // if the library is not in the current directory, then get the full
1059 // path to it
1060 if(m_LibraryOutputPath.size())
1062 libpath = m_LibraryOutputPath;
1063 libpath += m_LibraryPrefix;
1065 else
1067 libpath = cacheValue;
1068 libpath += "/";
1069 libpath += m_LibraryPrefix;
1072 else
1074 // library is in current Makefile so use lib as a prefix
1075 libpath = m_LibraryOutputPath;
1076 libpath += m_LibraryPrefix;
1078 // add the library name
1079 libpath += name;
1080 // add the correct extension
1081 std::string ltname = name;
1082 ltname += "_LIBRARY_TYPE";
1083 const char* libType = m_Makefile->GetDefinition(ltname.c_str());
1084 if(libType && std::string(libType) == "SHARED")
1086 libpath += m_Makefile->GetDefinition("CMAKE_SHLIB_SUFFIX");
1088 else if (libType && std::string(libType) == "MODULE")
1090 libpath += m_Makefile->GetDefinition("CMAKE_MODULE_SUFFIX");
1092 else if (libType && std::string(libType) == "STATIC")
1094 libpath += m_StaticLibraryExtension;
1096 fout << cmSystemTools::ConvertToOutputPath(libpath.c_str()) << " ";
1101 void cmLocalUnixMakefileGenerator::OutputExeDepend(std::ostream& fout,
1102 const char* name)
1104 std::string exePath = name;
1105 exePath += "_CMAKE_PATH";
1106 const char* cacheValue = m_Makefile->GetDefinition(exePath.c_str());
1107 if(cacheValue )
1109 // if there is a cache value, then this is a executable/utility that cmake
1110 // knows how to build, so we can depend on it
1111 std::string exepath;
1112 if (!this->SamePath(m_Makefile->GetCurrentOutputDirectory(), cacheValue))
1114 // if the exe/utility is not in the current directory, then get the full
1115 // path to it
1116 if(m_ExecutableOutputPath.size())
1118 exepath = m_ExecutableOutputPath;
1120 else
1122 exepath = cacheValue;
1123 exepath += "/";
1126 else
1128 // library is in current Makefile
1129 exepath = m_ExecutableOutputPath;
1131 // add the library name
1132 exepath += name;
1133 // add the correct extension
1134 exepath += m_ExecutableExtension;
1135 fout << cmSystemTools::ConvertToOutputPath(exepath.c_str()) << " ";
1141 // fix up names of directories so they can be used
1142 // as targets in makefiles.
1143 inline std::string FixDirectoryName(const char* dir)
1145 std::string s = dir;
1146 // replace ../ with 3 under bars
1147 size_t pos = s.find("../");
1148 if(pos != std::string::npos)
1150 s.replace(pos, 3, "___");
1152 // replace / directory separators with a single under bar
1153 pos = s.find("/");
1154 while(pos != std::string::npos)
1156 s.replace(pos, 1, "_");
1157 pos = s.find("/");
1159 return s;
1163 void cmLocalUnixMakefileGenerator::BuildInSubDirectory(std::ostream& fout,
1164 const char* dir,
1165 const char* target1,
1166 const char* target2,
1167 bool silent)
1169 std::string directory = cmSystemTools::ConvertToOutputPath(dir);
1170 if(target1)
1172 fout << "\t@if test ! -d " << directory
1173 << "; then $(MAKE) rebuild_cache; fi\n";
1174 if (!silent)
1176 fout << "\techo " << directory << ": building " << target1 << "\n";
1178 fout << "\t@cd " << directory
1179 << "; $(MAKE) " << target1 << "\n";
1181 if(target2)
1183 if (!silent)
1185 fout << "\techo " << directory << ": building " << target2 << "\n";
1187 fout << "\t@cd " << directory
1188 << "; $(MAKE) " << target2 << "\n";
1190 fout << "\n";
1194 void
1195 cmLocalUnixMakefileGenerator::
1196 OutputSubDirectoryVars(std::ostream& fout,
1197 const char* var,
1198 const char* target,
1199 const char* target1,
1200 const char* target2,
1201 const char* depend,
1202 const std::vector<std::string>& SubDirectories,
1203 bool silent)
1205 if(!depend)
1207 depend = "";
1209 if( SubDirectories.size() == 0)
1211 return;
1213 fout << "# Variable for making " << target << " in subdirectories.\n";
1214 fout << var << " = \\\n";
1215 unsigned int i;
1216 for(i =0; i < SubDirectories.size(); i++)
1218 std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
1219 fout << target << "_" << subdir.c_str();
1220 if(i == SubDirectories.size()-1)
1222 fout << " \n\n";
1224 else
1226 fout << " \\\n";
1229 fout << "# Targets for making " << target << " in subdirectories.\n";
1230 std::string last = "";
1231 for(unsigned int i =0; i < SubDirectories.size(); i++)
1233 std::string subdir = FixDirectoryName(SubDirectories[i].c_str());
1234 fout << target << "_" << subdir.c_str() << ": " << depend;
1236 // Make each subdirectory depend on previous one. This forces
1237 // parallel builds (make -j 2) to build in same order as a single
1238 // threaded build to avoid dependency problems.
1239 if(i > 0)
1241 fout << " " << target << "_" << last.c_str();
1244 fout << "\n";
1245 last = subdir;
1246 std::string dir = m_Makefile->GetCurrentOutputDirectory();
1247 dir += "/";
1248 dir += SubDirectories[i];
1249 this->BuildInSubDirectory(fout, dir.c_str(),
1250 target1, target2, silent);
1252 fout << "\n\n";
1256 // output rules for decending into sub directories
1257 void cmLocalUnixMakefileGenerator::OutputSubDirectoryRules(std::ostream& fout)
1259 // Output Sub directory build rules
1260 const std::vector<std::string>& SubDirectories
1261 = m_Makefile->GetSubDirectories();
1263 if( SubDirectories.size() == 0)
1265 return;
1267 this->OutputSubDirectoryVars(fout,
1268 "SUBDIR_BUILD",
1269 "default_target",
1270 "default_target",
1271 0, "$(TARGETS)",
1272 SubDirectories,
1273 false);
1274 this->OutputSubDirectoryVars(fout, "SUBDIR_CLEAN", "clean",
1275 "clean",
1276 0, 0,
1277 SubDirectories);
1278 this->OutputSubDirectoryVars(fout, "SUBDIR_DEPEND", "depend",
1279 "depend",
1280 0, 0,
1281 SubDirectories);
1282 this->OutputSubDirectoryVars(fout, "SUBDIR_INSTALL", "install",
1283 "install",
1284 0, 0,
1285 SubDirectories);
1291 // Output the depend information for all the classes
1292 // in the makefile. These would have been generated
1293 // by the class cmMakeDepend GenerateMakefile
1294 bool cmLocalUnixMakefileGenerator::OutputObjectDepends(std::ostream& fout)
1296 bool ret = false;
1297 // Iterate over every target.
1298 std::map<cmStdString, cmTarget>& targets = m_Makefile->GetTargets();
1299 for(std::map<cmStdString, cmTarget>::const_iterator target = targets.begin();
1300 target != targets.end(); ++target)
1302 // Iterate over every source for this target.
1303 const std::vector<cmSourceFile*>& sources = target->second.GetSourceFiles();
1304 for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
1305 source != sources.end(); ++source)
1307 if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
1309 if(!(*source)->GetDepends().empty())
1311 // Iterate through all the dependencies for this source.
1312 for(std::vector<std::string>::const_iterator dep =
1313 (*source)->GetDepends().begin();
1314 dep != (*source)->GetDepends().end(); ++dep)
1316 fout << (*source)->GetSourceName() << m_ObjectFileExtension << " : "
1317 << cmSystemTools::ConvertToOutputPath(dep->c_str()) << "\n";
1318 ret = true;
1320 fout << "\n\n";
1325 return ret;
1330 // Output the depend information for all the classes
1331 // in the makefile. These would have been generated
1332 // by the class cmMakeDepend GenerateMakefile
1333 void cmLocalUnixMakefileGenerator::OutputCheckDepends(std::ostream& fout)
1335 std::set<std::string> emittedLowerPath;
1336 std::set<std::string> emitted;
1337 // Iterate over every target.
1338 std::map<cmStdString, cmTarget>& targets = m_Makefile->GetTargets();
1339 fout << "# Suppresses display of executed commands\n";
1340 fout << ".SILENT:\n";
1341 fout << "# disable some common implicit rules to speed things up\n";
1342 fout << ".SUFFIXES:\n";
1343 fout << ".SUFFIXES:.hpuxmakemusthaverule\n";
1344 this->OutputMakeVariables(fout);
1345 fout << "default:\n";
1346 fout << "\t$(MAKE) $(MAKESILENT) -f cmake.check_depends all\n"
1347 << "\t$(MAKE) $(MAKESILENT) -f cmake.check_depends cmake.depends\n\n";
1348 for(std::map<cmStdString, cmTarget>::const_iterator target = targets.begin();
1349 target != targets.end(); ++target)
1351 // Iterate over every source for this target.
1352 const std::vector<cmSourceFile*>& sources = target->second.GetSourceFiles();
1353 for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
1354 source != sources.end(); ++source)
1356 if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
1358 if(!(*source)->GetDepends().empty())
1360 for(std::vector<std::string>::const_iterator dep =
1361 (*source)->GetDepends().begin();
1362 dep != (*source)->GetDepends().end(); ++dep)
1364 std::string dependfile =
1365 cmSystemTools::ConvertToOutputPath(cmSystemTools::CollapseFullPath(dep->c_str()).c_str());
1366 // use the lower path function to create uniqe names
1367 std::string lowerpath = this->LowerCasePath(dependfile.c_str());
1368 if(emittedLowerPath.insert(lowerpath).second)
1370 emitted.insert(dependfile);
1371 fout << "all:: " << dependfile << "\n";
1378 fout << "\n\n# if any of these files changes run make dependlocal\n";
1379 std::set<std::string>::iterator i;
1380 for(i = emitted.begin(); i != emitted.end(); ++i)
1382 fout << "cmake.depends:: " << *i <<
1383 "\n\t$(MAKE) $(MAKESILENT) dependlocal\n\n";
1385 fout << "\n\n";
1386 fout << "# if a .h file is removed then run make dependlocal\n\n";
1387 for(std::set<std::string>::iterator i = emitted.begin();
1388 i != emitted.end(); ++i)
1390 fout << *i << ":\n"
1391 << "\t$(MAKE) $(MAKESILENT) dependlocal\n\n";
1395 // Output each custom rule in the following format:
1396 // output: source depends...
1397 // (tab) command...
1398 void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
1400 // We may be modifying the source groups temporarily, so make a copy.
1401 std::vector<cmSourceGroup> sourceGroups = m_Makefile->GetSourceGroups();
1403 const cmTargets &tgts = m_Makefile->GetTargets();
1404 for(cmTargets::const_iterator tgt = tgts.begin();
1405 tgt != tgts.end(); ++tgt)
1407 // add any custom rules to the source groups
1408 for (std::vector<cmCustomCommand>::const_iterator cr =
1409 tgt->second.GetCustomCommands().begin();
1410 cr != tgt->second.GetCustomCommands().end(); ++cr)
1412 // if the source for the custom command is the same name
1413 // as the target, then to not create a rule in the makefile for
1414 // the custom command, as the command will be fired when the other target
1415 // is built.
1416 if ( cr->GetSourceName().compare(tgt->first) !=0)
1418 cmSourceGroup& sourceGroup =
1419 m_Makefile->FindSourceGroup(cr->GetSourceName().c_str(),
1420 sourceGroups);
1421 cmCustomCommand cc(*cr);
1422 cc.ExpandVariables(*m_Makefile);
1423 sourceGroup.AddCustomCommand(cc);
1428 // Loop through every source group.
1429 for(std::vector<cmSourceGroup>::const_iterator sg =
1430 sourceGroups.begin(); sg != sourceGroups.end(); ++sg)
1432 const cmSourceGroup::BuildRules& buildRules = sg->GetBuildRules();
1433 if(buildRules.empty())
1434 { continue; }
1436 std::string name = sg->GetName();
1437 if(name != "")
1439 fout << "# Start of source group \"" << name.c_str() << "\"\n";
1442 // Loop through each source in the source group.
1443 for(cmSourceGroup::BuildRules::const_iterator cc =
1444 buildRules.begin(); cc != buildRules.end(); ++ cc)
1446 std::string source = cc->first;
1447 const cmSourceGroup::Commands& commands = cc->second.m_Commands;
1448 // Loop through every command generating code from the current source.
1449 for(cmSourceGroup::Commands::const_iterator c = commands.begin();
1450 c != commands.end(); ++c)
1452 // escape spaces and convert to native slashes path for
1453 // the command
1454 std::string command =
1455 cmSystemTools::ConvertToOutputPath(c->second.m_Command.c_str());
1456 command += " ";
1457 // now add the arguments
1458 command += c->second.m_Arguments;
1459 const cmSourceGroup::CommandFiles& commandFiles = c->second;
1460 // if the command has no outputs, then it is a utility command
1461 // with no outputs
1462 if(commandFiles.m_Outputs.size() == 0)
1464 std::string depends;
1465 // collect out all the dependencies for this rule.
1466 for(std::set<std::string>::const_iterator d =
1467 commandFiles.m_Depends.begin();
1468 d != commandFiles.m_Depends.end(); ++d)
1470 std::string dep = cmSystemTools::ConvertToOutputPath(d->c_str());
1471 depends += " ";
1472 depends += dep;
1474 // output rule
1475 this->OutputMakeRule(fout,
1476 "Custom command",
1477 source.c_str(),
1478 depends.c_str(),
1479 command.c_str());
1481 // Write a rule for every output generated by this command.
1482 for(std::set<std::string>::const_iterator output =
1483 commandFiles.m_Outputs.begin();
1484 output != commandFiles.m_Outputs.end(); ++output)
1486 std::string src = cmSystemTools::ConvertToOutputPath(source.c_str());
1487 std::string depends;
1488 depends += src;
1489 // Collect out all the dependencies for this rule.
1490 for(std::set<std::string>::const_iterator d =
1491 commandFiles.m_Depends.begin();
1492 d != commandFiles.m_Depends.end(); ++d)
1494 std::string dep = cmSystemTools::ConvertToOutputPath(d->c_str());
1495 depends += " ";
1496 depends += dep;
1498 // output rule
1499 this->OutputMakeRule(fout,
1500 "Custom command",
1501 output->c_str(),
1502 depends.c_str(),
1503 command.c_str());
1507 if(name != "")
1509 fout << "# End of source group \"" << name.c_str() << "\"\n\n";
1514 void cmLocalUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout)
1516 const char* variables =
1517 "# the standard shell for make\n"
1518 "SHELL = /bin/sh\n"
1519 "\n"
1520 "CMAKE_RANLIB = @CMAKE_RANLIB@\n"
1521 "CMAKE_AR = @CMAKE_AR@\n"
1522 "CMAKE_AR_ARGS = @CMAKE_AR_ARGS@\n"
1523 "CMAKE_CXX_AR = @CMAKE_CXX_AR@\n"
1524 "CMAKE_CXX_AR_ARGS = @CMAKE_CXX_AR_ARGS@\n"
1525 "CMAKE_C_FLAGS = @CMAKE_C_FLAGS@\n"
1526 "CMAKE_C_COMPILER = @CMAKE_C_COMPILER@\n"
1527 "CMAKE_C_LINK_SHARED = @CMAKE_C_LINK_SHARED@\n"
1528 "CMAKE_CXX_LINK_SHARED = @CMAKE_CXX_LINK_SHARED@\n"
1529 "CMAKE_SHLIB_CFLAGS = @CMAKE_SHLIB_CFLAGS@\n"
1531 "CMAKE_CXX_SHLIB_CFLAGS = @CMAKE_CXX_SHLIB_CFLAGS@\n"
1532 "CMAKE_CXX_SHLIB_BUILD_FLAGS = @CMAKE_CXX_SHLIB_BUILD_FLAGS@\n"
1533 "CMAKE_CXX_SHLIB_LINK_FLAGS = @CMAKE_CXX_SHLIB_LINK_FLAGS@\n"
1534 "CMAKE_CXX_MODULE_BUILD_FLAGS = @CMAKE_CXX_MODULE_BUILD_FLAGS@\n"
1535 "CMAKE_CXX_MODULE_LINK_FLAGS = @CMAKE_CXX_MODULE_LINK_FLAGS@\n"
1536 "CMAKE_CXX_SHLIB_RUNTIME_FLAG = @CMAKE_CXX_SHLIB_RUNTIME_FLAG@\n"
1537 "CMAKE_CXX_SHLIB_RUNTIME_SEP = @CMAKE_CXX_SHLIB_RUNTIME_SEP@\n"
1539 "\n"
1540 "CMAKE_CXX_COMPILER = @CMAKE_CXX_COMPILER@\n"
1541 "CMAKE_CXX_FLAGS = @CMAKE_CXX_FLAGS@\n"
1542 "\n"
1543 "CMAKE_SHLIB_BUILD_FLAGS = @CMAKE_SHLIB_BUILD_FLAGS@\n"
1544 "CMAKE_SHLIB_LINK_FLAGS = @CMAKE_SHLIB_LINK_FLAGS@\n"
1545 "CMAKE_C_SHLIB_LINK_FLAGS = @CMAKE_C_SHLIB_LINK_FLAGS@\n"
1546 "CMAKE_MODULE_BUILD_FLAGS = @CMAKE_MODULE_BUILD_FLAGS@\n"
1547 "CMAKE_MODULE_LINK_FLAGS = @CMAKE_MODULE_LINK_FLAGS@\n"
1548 "CMAKE_C_SHLIB_RUNTIME_FLAG = @CMAKE_C_SHLIB_RUNTIME_FLAG@\n"
1549 "CMAKE_SHLIB_RUNTIME_FLAG = @CMAKE_SHLIB_RUNTIME_FLAG@\n"
1550 "CMAKE_SHLIB_RUNTIME_SEP = @CMAKE_SHLIB_RUNTIME_SEP@\n"
1551 "SHLIB_LD_LIBS = @CMAKE_SHLIB_LD_LIBS@\n"
1552 "SHLIB_SUFFIX = @CMAKE_SHLIB_SUFFIX@\n"
1553 "MODULE_SUFFIX = @CMAKE_MODULE_SUFFIX@\n"
1554 "RM = rm -f\n"
1555 "\n";
1556 std::string replaceVars = variables;
1557 m_Makefile->ExpandVariablesInString(replaceVars);
1558 fout << replaceVars.c_str();
1559 fout << "CMAKE_COMMAND = "
1560 << cmSystemTools::ConvertToOutputPath(m_Makefile->GetDefinition("CMAKE_COMMAND"))
1561 << "\n";
1562 if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
1564 fout << "CMAKE_EDIT_COMMAND = "
1565 << cmSystemTools::ConvertToOutputPath(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
1566 << "\n";
1569 fout << "CMAKE_CURRENT_SOURCE = " <<
1570 cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory()) << "\n";
1571 fout << "CMAKE_CURRENT_BINARY = " <<
1572 cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartOutputDirectory()) << "\n";
1573 fout << "CMAKE_SOURCE_DIR = " <<
1574 cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeDirectory()) << "\n";
1575 fout << "CMAKE_BINARY_DIR = " <<
1576 cmSystemTools::ConvertToOutputPath(m_Makefile->GetHomeOutputDirectory()) << "\n";
1577 // Output Include paths
1578 fout << "INCLUDE_FLAGS = ";
1579 std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
1580 std::vector<std::string>::iterator i;
1581 fout << "-I" <<
1582 cmSystemTools::ConvertToOutputPath(m_Makefile->GetStartDirectory()) << " ";
1583 for(i = includes.begin(); i != includes.end(); ++i)
1585 std::string include = *i;
1586 // Don't output a -I for the standard include path "/usr/include".
1587 // This can cause problems with certain standard library
1588 // implementations because the wrong headers may be found first.
1589 if(include != "/usr/include")
1591 fout << "-I" << cmSystemTools::ConvertToOutputPath(i->c_str()) << " ";
1594 fout << m_Makefile->GetDefineFlags();
1595 fout << "\n\n";
1599 void cmLocalUnixMakefileGenerator::OutputInstallRules(std::ostream& fout)
1601 const char* root
1602 = m_Makefile->GetDefinition("CMAKE_ROOT");
1603 fout << "INSTALL = " << root << "/Templates/install-sh -c\n";
1604 fout << "INSTALL_PROGRAM = $(INSTALL)\n";
1605 fout << "INSTALL_DATA = $(INSTALL) -m 644\n";
1607 const cmTargets &tgts = m_Makefile->GetTargets();
1608 fout << "install: $(SUBDIR_INSTALL)\n";
1609 fout << "\t@echo \"Installing ...\"\n";
1611 const char* prefix
1612 = m_Makefile->GetDefinition("CMAKE_INSTALL_PREFIX");
1613 if (!prefix)
1615 prefix = "/usr/local";
1618 for(cmTargets::const_iterator l = tgts.begin();
1619 l != tgts.end(); l++)
1621 if (l->second.GetInstallPath() != "")
1623 // first make the directories for each target
1624 fout << "\t@if [ ! -d $(DESTDIR)" << prefix << l->second.GetInstallPath() <<
1625 " ] ; then \\\n";
1626 fout << "\t echo \"Making directory $(DESTDIR)" << prefix
1627 << l->second.GetInstallPath() << " \"; \\\n";
1628 fout << "\t mkdir -p $(DESTDIR)" << prefix << l->second.GetInstallPath()
1629 << "; \\\n";
1630 fout << "\t chmod 755 $(DESTDIR)" << prefix << l->second.GetInstallPath()
1631 << "; \\\n";
1632 fout << "\t else true; \\\n";
1633 fout << "\t fi\n";
1634 // now install the target
1635 switch (l->second.GetType())
1637 case cmTarget::STATIC_LIBRARY:
1638 fout << "\t$(INSTALL_DATA) " << m_LibraryOutputPath << "lib"
1639 << l->first;
1640 fout << ".a";
1641 fout << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "\n";
1642 break;
1643 case cmTarget::SHARED_LIBRARY:
1644 fout << "\t$(INSTALL_DATA) " << m_LibraryOutputPath << "lib"
1645 << l->first;
1646 fout << m_Makefile->GetDefinition("CMAKE_SHLIB_SUFFIX");
1647 fout << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "\n";
1648 break;
1649 case cmTarget::MODULE_LIBRARY:
1650 fout << "\t$(INSTALL_DATA) " << m_LibraryOutputPath << "lib"
1651 << l->first;
1652 fout << m_Makefile->GetDefinition("CMAKE_MODULE_SUFFIX");
1653 fout << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "\n";
1654 break;
1655 case cmTarget::WIN32_EXECUTABLE:
1656 case cmTarget::EXECUTABLE:
1657 fout << "\t$(INSTALL_PROGRAM) " << m_ExecutableOutputPath
1658 << l->first
1659 << cmSystemTools::GetExecutableExtension()
1660 << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "\n";
1661 break;
1662 case cmTarget::INSTALL_FILES:
1664 std::string sourcePath = m_Makefile->GetCurrentDirectory();
1665 std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
1666 sourcePath += "/";
1667 binaryPath += "/";
1668 const std::vector<std::string> &sf = l->second.GetSourceLists();
1669 std::vector<std::string>::const_iterator i;
1670 for (i = sf.begin(); i != sf.end(); ++i)
1672 std::string f = *i;
1673 if(f.substr(0, sourcePath.length()) == sourcePath)
1675 f = f.substr(sourcePath.length());
1677 else if(f.substr(0, binaryPath.length()) == binaryPath)
1679 f = f.substr(binaryPath.length());
1681 fout << "\t@echo \"Installing " << f.c_str() << " \"\n";
1682 // avoid using install-sh to install install-sh
1683 // does not work on windows....
1684 if(*i == "install-sh")
1686 fout << "\t @cp ";
1688 else
1690 fout << "\t @$(INSTALL_DATA) ";
1692 fout << *i
1693 << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "\n";
1696 break;
1697 case cmTarget::INSTALL_PROGRAMS:
1699 std::string sourcePath = m_Makefile->GetCurrentDirectory();
1700 std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
1701 sourcePath += "/";
1702 binaryPath += "/";
1703 const std::vector<std::string> &sf = l->second.GetSourceLists();
1704 std::vector<std::string>::const_iterator i;
1705 for (i = sf.begin(); i != sf.end(); ++i)
1707 std::string f = *i;
1708 if(f.substr(0, sourcePath.length()) == sourcePath)
1710 f = f.substr(sourcePath.length());
1712 else if(f.substr(0, binaryPath.length()) == binaryPath)
1714 f = f.substr(binaryPath.length());
1716 fout << "\t@echo \"Installing " << f.c_str() << " \"\n";
1717 // avoid using install-sh to install install-sh
1718 // does not work on windows....
1719 if(*i == "install-sh")
1721 fout << "\t @cp ";
1723 else
1725 fout << "\t @$(INSTALL_PROGRAM) ";
1727 fout << *i
1728 << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "\n";
1731 break;
1732 case cmTarget::UTILITY:
1733 default:
1734 break;
1740 void cmLocalUnixMakefileGenerator::OutputMakeRules(std::ostream& fout)
1742 this->OutputMakeRule(fout,
1743 "Default build rule",
1744 "all",
1745 "cmake.depends $(TARGETS) $(SUBDIR_BUILD)",
1747 this->OutputMakeRule(fout,
1748 "remove generated files",
1749 "clean",
1750 "$(SUBDIR_CLEAN)",
1751 "-@ $(RM) $(CLEAN_OBJECT_FILES) "
1752 " $(TARGETS) $(GENERATED_QT_FILES) $(GENERATED_FLTK_FILES)");
1754 // collect up all the sources
1755 std::string allsources;
1756 std::map<cmStdString, cmTarget>& targets = m_Makefile->GetTargets();
1757 for(std::map<cmStdString, cmTarget>::const_iterator target = targets.begin();
1758 target != targets.end(); ++target)
1760 // Iterate over every source for this target.
1761 const std::vector<cmSourceFile*>& sources = target->second.GetSourceFiles();
1762 for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
1763 source != sources.end(); ++source)
1765 if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
1767 allsources += " \\\n";
1768 allsources += cmSystemTools::ConvertToOutputPath((*source)->GetFullPath().c_str());
1773 this->OutputMakeRule(fout,
1774 "Rule to build the cmake.depends and Makefile as side effect, if a source cmakelist file is out of date.",
1775 "cmake.depends",
1776 "$(CMAKE_MAKEFILE_SOURCES)",
1777 "$(CMAKE_COMMAND) "
1778 "-S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
1779 "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"
1781 this->OutputMakeRule(fout,
1782 "Rule to build the cmake.check_depends and Makefile as side effect, if any source file has changed.",
1783 "cmake.check_depends",
1784 allsources.c_str(),
1785 "$(CMAKE_COMMAND) "
1786 "-S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
1787 "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)"
1790 this->OutputMakeRule(fout,
1791 "Rule to force the build of cmake.depends",
1792 "depend",
1793 "$(SUBDIR_DEPEND)",
1794 "$(CMAKE_COMMAND) "
1795 "-S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
1796 "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
1797 this->OutputMakeRule(fout,
1798 "Rule to force the build of cmake.depends "
1799 "in the current directory only.",
1800 "dependlocal",
1802 "$(CMAKE_COMMAND) "
1803 "-S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
1804 "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
1806 this->OutputMakeRule(fout,
1807 "Rebuild CMakeCache.txt file",
1808 "rebuild_cache",
1809 "$(CMAKE_BINARY_DIR)/CMakeCache.txt",
1810 "$(CMAKE_COMMAND) "
1811 "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
1812 // if CMAKE_EDIT_COMMAND is defined then add a rule to run it
1813 // called edit_cache
1814 if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
1816 this->OutputMakeRule(fout,
1817 "Edit the CMakeCache.txt file with ccmake or CMakeSetup",
1818 "edit_cache",
1820 "$(CMAKE_EDIT_COMMAND) "
1821 "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
1824 this->OutputMakeRule(fout,
1825 "Create CMakeCache.txt file",
1826 "$(CMAKE_BINARY_DIR)/CMakeCache.txt",
1828 "$(CMAKE_COMMAND) "
1829 "-H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
1831 this->OutputMakeRule(fout,
1832 "Rule to keep make from removing Makefiles "
1833 "if control-C is hit during a run of cmake.",
1834 ".PRECIOUS",
1835 "Makefile cmake.depends",
1838 this->OutputSourceObjectBuildRules(fout);
1839 // find ctest
1840 std::string ctest = m_Makefile->GetDefinition("CMAKE_COMMAND");
1841 ctest = cmSystemTools::GetFilenamePath(ctest.c_str());
1842 ctest += "/";
1843 ctest += "ctest";
1844 ctest += cmSystemTools::GetExecutableExtension();
1845 if(!cmSystemTools::FileExists(ctest.c_str()))
1847 ctest = m_Makefile->GetDefinition("CMAKE_COMMAND");
1848 ctest = cmSystemTools::GetFilenamePath(ctest.c_str());
1849 ctest += "/Debug/";
1850 ctest += "ctest";
1851 ctest += cmSystemTools::GetExecutableExtension();
1853 if(!cmSystemTools::FileExists(ctest.c_str()))
1855 ctest = m_Makefile->GetDefinition("CMAKE_COMMAND");
1856 ctest = cmSystemTools::GetFilenamePath(ctest.c_str());
1857 ctest += "/Release/";
1858 ctest += "ctest";
1859 ctest += cmSystemTools::GetExecutableExtension();
1861 if (cmSystemTools::FileExists(ctest.c_str()))
1863 this->OutputMakeRule(fout,
1864 "run any tests",
1865 "test",
1867 cmSystemTools::ConvertToOutputPath(ctest.c_str()).c_str());
1871 void
1872 cmLocalUnixMakefileGenerator::
1873 OutputBuildObjectFromSource(std::ostream& fout,
1874 const char* shortName,
1875 const cmSourceFile& source,
1876 const char* extraCompileFlags,
1877 bool shared)
1879 // Header files shouldn't have build rules.
1880 if(source.GetPropertyAsBool("HEADER_FILE_ONLY"))
1882 return;
1885 std::string comment = "Build ";
1886 std::string objectFile = std::string(shortName) + m_ObjectFileExtension;
1887 objectFile = cmSystemTools::ConvertToOutputPath(objectFile.c_str());
1888 comment += objectFile + " From ";
1889 comment += source.GetFullPath();
1890 std::string compileCommand;
1891 cmSystemTools::e_FileFormat format =
1892 cmSystemTools::GetFileFormat(source.GetSourceExtension().c_str());
1893 if( format == cmSystemTools::C_FILE_FORMAT )
1895 compileCommand = "$(CMAKE_C_COMPILER) $(CMAKE_C_FLAGS) ";
1896 compileCommand += extraCompileFlags;
1897 if(shared)
1899 compileCommand += "$(CMAKE_SHLIB_CFLAGS) ";
1901 compileCommand += "$(INCLUDE_FLAGS) -c ";
1902 compileCommand +=
1903 cmSystemTools::ConvertToOutputPath(source.GetFullPath().c_str());
1904 compileCommand += " -o ";
1905 compileCommand += objectFile;
1907 else if ( format == cmSystemTools::CXX_FILE_FORMAT )
1909 compileCommand = "$(CMAKE_CXX_COMPILER) $(CMAKE_CXX_FLAGS) ";
1910 compileCommand += extraCompileFlags;
1911 if(shared)
1913 compileCommand += "$(CMAKE_SHLIB_CFLAGS) ";
1915 compileCommand += "$(INCLUDE_FLAGS) -c ";
1916 compileCommand +=
1917 cmSystemTools::ConvertToOutputPath(source.GetFullPath().c_str());
1918 compileCommand += " -o ";
1919 compileCommand += objectFile;
1921 this->OutputMakeRule(fout,
1922 comment.c_str(),
1923 objectFile.c_str(),
1924 cmSystemTools::ConvertToOutputPath(source.GetFullPath().
1925 c_str()).c_str(),
1926 compileCommand.c_str());
1931 void cmLocalUnixMakefileGenerator::OutputSourceObjectBuildRules(std::ostream& fout)
1933 fout << "# Rules to build " << m_ObjectFileExtension
1934 << " files from their sources:\n";
1936 std::set<std::string> rules;
1938 // Iterate over every target.
1939 std::map<cmStdString, cmTarget>& targets = m_Makefile->GetTargets();
1940 for(std::map<cmStdString, cmTarget>::const_iterator target = targets.begin();
1941 target != targets.end(); ++target)
1943 bool shared = ((target->second.GetType() == cmTarget::SHARED_LIBRARY) ||
1944 (target->second.GetType() == cmTarget::MODULE_LIBRARY));
1945 std::string exportsDef = "";
1946 if(shared)
1948 exportsDef = "-D"+target->first+"_EXPORTS ";
1950 // Iterate over every source for this target.
1951 const std::vector<cmSourceFile*>& sources = target->second.GetSourceFiles();
1952 for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
1953 source != sources.end(); ++source)
1955 if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
1957 std::string shortName;
1958 std::string sourceName;
1959 // If the full path to the source file includes this
1960 // directory, we want to use the relative path for the
1961 // filename of the object file. Otherwise, we will use just
1962 // the filename portion.
1963 if((cmSystemTools::GetFilenamePath((*source)->GetFullPath()).find(m_Makefile->GetCurrentDirectory()) == 0)
1964 || (cmSystemTools::GetFilenamePath((*source)->GetFullPath()).find(m_Makefile->
1965 GetCurrentOutputDirectory()) == 0))
1967 sourceName = (*source)->GetSourceName()+"."+(*source)->GetSourceExtension();
1968 shortName = (*source)->GetSourceName();
1970 // The path may be relative. See if a directory needs to be
1971 // created for the output file. This is a ugly, and perhaps
1972 // should be moved elsewhere.
1973 std::string relPath =
1974 cmSystemTools::GetFilenamePath((*source)->GetSourceName());
1975 if(relPath != "")
1977 std::string outPath = m_Makefile->GetCurrentOutputDirectory();
1978 outPath += "/"+relPath;
1979 cmSystemTools::MakeDirectory(outPath.c_str());
1982 else
1984 sourceName = (*source)->GetFullPath();
1985 shortName = cmSystemTools::GetFilenameName((*source)->GetSourceName());
1987 std::string shortNameWithExt = shortName +
1988 (*source)->GetSourceExtension();
1989 // Only output a rule for each .o once.
1990 if(rules.find(shortNameWithExt) == rules.end())
1992 if((*source)->GetProperty("COMPILE_FLAGS"))
1994 exportsDef += (*source)->GetProperty("COMPILE_FLAGS");
1995 exportsDef += " ";
1997 this->OutputBuildObjectFromSource(fout,
1998 shortName.c_str(),
1999 *(*source),
2000 exportsDef.c_str(),
2001 shared);
2002 rules.insert(shortNameWithExt);
2009 void cmLocalUnixMakefileGenerator::OutputMakeRule(std::ostream& fout,
2010 const char* comment,
2011 const char* target,
2012 const char* depends,
2013 const char* command,
2014 const char* command2,
2015 const char* command3,
2016 const char* command4)
2018 if(!target)
2020 cmSystemTools::Error("no target for OutputMakeRule");
2021 return;
2024 std::string replace;
2025 if(comment)
2027 replace = comment;
2028 m_Makefile->ExpandVariablesInString(replace);
2029 fout << "#---------------------------------------------------------\n";
2030 fout << "# " << replace;
2031 fout << "\n#\n";
2033 fout << "\n";
2035 replace = target;
2036 m_Makefile->ExpandVariablesInString(replace);
2037 fout << cmSystemTools::ConvertToOutputPath(replace.c_str()) << ": ";
2039 if(depends)
2041 replace = depends;
2042 m_Makefile->ExpandVariablesInString(replace);
2043 fout << replace.c_str();
2045 fout << "\n";
2047 const char* commands[] = { command, command2, command3, command4 };
2049 for (unsigned int i = 0; i < sizeof(commands) / sizeof(commands[0]); ++i)
2051 if(commands[i])
2053 replace = commands[i];
2054 m_Makefile->ExpandVariablesInString(replace);
2055 if(replace[0] != '-' && replace.find("echo") != 0
2056 && replace.find("$(MAKE)") != 0)
2058 std::string echostring = replace;
2059 // for unix we want to quote the output of echo
2060 // for nmake and borland, the echo should not be quoted
2061 if(strcmp(m_GlobalGenerator->GetName(), "Unix Makefiles") == 0)
2063 cmSystemTools::ReplaceString(echostring, "\\\n", " ");
2064 cmSystemTools::ReplaceString(echostring, " \t", " ");
2065 cmSystemTools::ReplaceString(echostring, "\n\t", "\"\n\techo \"");
2066 fout << "\techo \"" << echostring.c_str() << "\"\n";
2068 else
2070 cmSystemTools::ReplaceString(echostring, "\n\t", "\n\techo ");
2071 fout << "\techo " << echostring.c_str() << "\n";
2074 fout << "\t" << replace.c_str() << "\n";
2077 fout << "\n";