1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: cmLocalUnixMakefileGenerator.cxx,v $
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());
94 md
.SetMakefile(m_Makefile
);
95 md
.GenerateMakefileDependencies();
96 this->ProcessDepends(md
);
98 // output the makefile fragment
99 std::string dest
= m_Makefile
->GetStartOutputDirectory();
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"))
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.
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
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
,
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] != '/')
166 cmSystemTools::MakeDirectory(dir
.c_str());
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();
182 cmSystemTools::Error("Error can not open for write: ", file
);
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();
194 std::sort(lfiles
.begin(), lfiles
.end(), std::less
<std::string
>());
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";
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());
224 this->OutputMakeVariables(fout
);
225 // Set up the default target as the VERY first target, so that make with no arguments will run it
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",
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";
244 std::ofstream
dependout(dependName
.c_str());
247 cmSystemTools::Error("Error can not open for write: ", dependName
.c_str());
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());
257 cmSystemTools::Error("Error can not open for write: ", checkDepend
.c_str());
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
);
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
,
285 fout
<< "include " << file
<< "\n";
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
;
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");
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");
328 << cmSystemTools::ConvertToOutputPath(path
.c_str());
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
) &&
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
&&
352 fout
<< " \\\n" << l
->first
.c_str();
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()));
372 fout
<< "\\\n" << cmSystemTools::ConvertToOutputPath((*i
)->GetSourceName().c_str())
373 << outExt
.c_str() << " ";
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()));
387 fout
<< "\\\n\"" << cmSystemTools::ConvertToOutputPath((*i
)->GetSourceName().c_str())
388 << outExt
.c_str() << "\" ";
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")
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 = ";
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
,
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();
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");
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");
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
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
)
503 runtimeDirs
.push_back( libpath
);
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(),
531 std::string libpath
= cmSystemTools::ConvertToOutputPath(dir
.c_str());
532 if(emitted
.insert(libpath
).second
)
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
562 if(!reg
.find(lib
->first
))
564 librariesLinked
+= "-l";
566 librariesLinked
+= lib
->first
;
567 librariesLinked
+= " ";
571 linkLibs
+= librariesLinked
;
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
580 std::vector
<std::string
>::iterator itr
= runtimeDirs
.begin();
583 for( ; itr
!= runtimeDirs
.end(); ++itr
)
585 if(runtimeConcatenate
)
587 fout
<< runtimeSep
<< *itr
;
591 fout
<< " " << runtimeFlag
<< *itr
;
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
)
614 customRuleCode
+= "\n\t";
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
,
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";
638 command
+= "$(SHLIB_SUFFIX)";
639 std::string command2
;
642 command2
= "$(CMAKE_CXX_LINK_SHARED) $(CMAKE_CXX_SHLIB_LINK_FLAGS) "
643 "$(CMAKE_CXX_SHLIB_BUILD_FLAGS) $(CMAKE_CXX_FLAGS) -o \\\n";
647 command2
= "$(CMAKE_C_LINK_SHARED) $(CMAKE_SHLIB_LINK_FLAGS) "
648 "$(CMAKE_SHLIB_BUILD_FLAGS) -o \\\n";
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
);
660 if(customCommands
.size() > 0)
662 cc
= customCommands
.c_str();
664 this->OutputMakeRule(fout
, "rules for a shared library",
672 void cmLocalUnixMakefileGenerator::OutputModuleLibraryRule(std::ostream
& fout
,
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
;
684 command2
= "$(CMAKE_CXX_LINK_SHARED) $(CMAKE_CXX_MODULE_LINK_FLAGS) "
685 "$(CMAKE_CXX_MODULE_BUILD_FLAGS) $(CMAKE_CXX_FLAGS) -o \\\n";
689 command2
= "$(CMAKE_C_LINK_SHARED) $(CMAKE_SHLIB_LINK_FLAGS) "
690 "$(CMAKE_MODULE_BUILD_FLAGS) -o \\\n";
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
);
702 if(customCommands
.size() > 0)
704 cc
= customCommands
.c_str();
706 this->OutputMakeRule(fout
, "rules for a shared module library",
715 void cmLocalUnixMakefileGenerator::OutputStaticLibraryRule(std::ostream
& fout
,
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") + ")";
726 command
= "$(CMAKE_CXX_AR) $(CMAKE_CXX_AR_ARGS) ";
730 command
= "$(CMAKE_AR) $(CMAKE_AR_ARGS) ";
734 command
+= this->CreateMakeVariable(name
, "_SRC_OBJS") + ")";
735 std::string command2
= "$(CMAKE_RANLIB) ";
737 std::string comment
= "rule to build static library: ";
739 std::string customCommands
= this->CreateTargetRules(t
, name
);
741 if(customCommands
.size() > 0)
743 cc
= customCommands
.c_str();
745 this->OutputMakeRule(fout
,
754 void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream
& fout
,
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") + ")";
766 "$(CMAKE_CXX_COMPILER) $(CMAKE_CXX_SHLIB_LINK_FLAGS) $(CMAKE_CXX_FLAGS) ";
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: ";
782 std::string customCommands
= this->CreateTargetRules(t
, name
);
784 if(customCommands
.size() > 0)
786 cc
= customCommands
.c_str();
788 this->OutputMakeRule(fout
,
798 void cmLocalUnixMakefileGenerator::OutputUtilityRule(std::ostream
& fout
,
802 std::string customCommands
= this->CreateTargetRules(t
, name
);
804 if(customCommands
.size() > 0)
806 cc
= customCommands
.c_str();
808 std::string comment
= "Rule to build Utility ";
811 std::string replaceVars
;
812 const std::vector
<cmCustomCommand
> &ccs
= t
.GetCustomCommands();
813 for(std::vector
<cmCustomCommand
>::const_iterator i
= ccs
.begin();
816 const std::vector
<std::string
> & dep
= i
->GetDepends();
817 for(std::vector
<std::string
>::const_iterator d
= dep
.begin();
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
)
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
);
844 case cmTarget::SHARED_LIBRARY
:
845 this->OutputSharedLibraryRule(fout
, l
->first
.c_str(), l
->second
);
847 case cmTarget::MODULE_LIBRARY
:
848 this->OutputModuleLibraryRule(fout
, l
->first
.c_str(), l
->second
);
850 case cmTarget::EXECUTABLE
:
851 case cmTarget::WIN32_EXECUTABLE
:
852 this->OutputExecutableRule(fout
, l
->first
.c_str(), l
->second
);
854 case cmTarget::UTILITY
:
855 this->OutputUtilityRule(fout
, l
->first
.c_str(), l
->second
);
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
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
875 std::set
<std::string
> used
;
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.
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());
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
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
947 (!this->SamePath(m_Makefile
->GetCurrentOutputDirectory(), cacheValue
)))
949 // add the correct extension
950 std::string ltname
= *lib
+"_LIBRARY_TYPE";
952 = m_Makefile
->GetDefinition(ltname
.c_str());
953 // if it was a library..
956 std::string library
= m_LibraryPrefix
;
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
;
973 cmSystemTools::Error("Unknown library type!");
976 if(m_LibraryOutputPath
.size())
978 libpath
= m_LibraryOutputPath
;
985 // put out a rule to build the library if it does not exist
986 this->OutputBuildTargetInDir(fout
,
991 GetDefinition("LIBRARY_OUTPUT_PATH")
994 // something other than a library...
997 std::string exepath
= cacheValue
;
998 if(m_ExecutableOutputPath
.size())
1000 exepath
= m_ExecutableOutputPath
;
1007 this->OutputBuildTargetInDir(fout
,
1012 GetDefinition("EXECUTABLE_OUTPUT_PATH")
1019 void cmLocalUnixMakefileGenerator::OutputBuildTargetInDir(std::ostream
& fout
,
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
,
1048 std::string libPath
= name
;
1049 libPath
+= "_CMAKE_PATH";
1050 const char* cacheValue
= m_Makefile
->GetDefinition(libPath
.c_str());
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
1060 if(m_LibraryOutputPath
.size())
1062 libpath
= m_LibraryOutputPath
;
1063 libpath
+= m_LibraryPrefix
;
1067 libpath
= cacheValue
;
1069 libpath
+= m_LibraryPrefix
;
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
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
,
1104 std::string exePath
= name
;
1105 exePath
+= "_CMAKE_PATH";
1106 const char* cacheValue
= m_Makefile
->GetDefinition(exePath
.c_str());
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
1116 if(m_ExecutableOutputPath
.size())
1118 exepath
= m_ExecutableOutputPath
;
1122 exepath
= cacheValue
;
1128 // library is in current Makefile
1129 exepath
= m_ExecutableOutputPath
;
1131 // add the library 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
1154 while(pos
!= std::string::npos
)
1156 s
.replace(pos
, 1, "_");
1163 void cmLocalUnixMakefileGenerator::BuildInSubDirectory(std::ostream
& fout
,
1165 const char* target1
,
1166 const char* target2
,
1169 std::string directory
= cmSystemTools::ConvertToOutputPath(dir
);
1172 fout
<< "\t@if test ! -d " << directory
1173 << "; then $(MAKE) rebuild_cache; fi\n";
1176 fout
<< "\techo " << directory
<< ": building " << target1
<< "\n";
1178 fout
<< "\t@cd " << directory
1179 << "; $(MAKE) " << target1
<< "\n";
1185 fout
<< "\techo " << directory
<< ": building " << target2
<< "\n";
1187 fout
<< "\t@cd " << directory
1188 << "; $(MAKE) " << target2
<< "\n";
1195 cmLocalUnixMakefileGenerator::
1196 OutputSubDirectoryVars(std::ostream
& fout
,
1199 const char* target1
,
1200 const char* target2
,
1202 const std::vector
<std::string
>& SubDirectories
,
1209 if( SubDirectories
.size() == 0)
1213 fout
<< "# Variable for making " << target
<< " in subdirectories.\n";
1214 fout
<< var
<< " = \\\n";
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)
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.
1241 fout
<< " " << target
<< "_" << last
.c_str();
1246 std::string dir
= m_Makefile
->GetCurrentOutputDirectory();
1248 dir
+= SubDirectories
[i
];
1249 this->BuildInSubDirectory(fout
, dir
.c_str(),
1250 target1
, target2
, silent
);
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)
1267 this->OutputSubDirectoryVars(fout
,
1274 this->OutputSubDirectoryVars(fout
, "SUBDIR_CLEAN", "clean",
1278 this->OutputSubDirectoryVars(fout
, "SUBDIR_DEPEND", "depend",
1282 this->OutputSubDirectoryVars(fout
, "SUBDIR_INSTALL", "install",
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
)
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";
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";
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
)
1391 << "\t$(MAKE) $(MAKESILENT) dependlocal\n\n";
1395 // Output each custom rule in the following format:
1396 // output: source depends...
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
1416 if ( cr
->GetSourceName().compare(tgt
->first
) !=0)
1418 cmSourceGroup
& sourceGroup
=
1419 m_Makefile
->FindSourceGroup(cr
->GetSourceName().c_str(),
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())
1436 std::string name
= sg
->GetName();
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
1454 std::string command
=
1455 cmSystemTools::ConvertToOutputPath(c
->second
.m_Command
.c_str());
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
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());
1475 this->OutputMakeRule(fout
,
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
;
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());
1499 this->OutputMakeRule(fout
,
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"
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"
1540 "CMAKE_CXX_COMPILER = @CMAKE_CXX_COMPILER@\n"
1541 "CMAKE_CXX_FLAGS = @CMAKE_CXX_FLAGS@\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"
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"))
1562 if(m_Makefile
->GetDefinition("CMAKE_EDIT_COMMAND"))
1564 fout
<< "CMAKE_EDIT_COMMAND = "
1565 << cmSystemTools::ConvertToOutputPath(m_Makefile
->GetDefinition("CMAKE_EDIT_COMMAND"))
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
;
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();
1599 void cmLocalUnixMakefileGenerator::OutputInstallRules(std::ostream
& fout
)
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";
1612 = m_Makefile
->GetDefinition("CMAKE_INSTALL_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() <<
1626 fout
<< "\t echo \"Making directory $(DESTDIR)" << prefix
1627 << l
->second
.GetInstallPath() << " \"; \\\n";
1628 fout
<< "\t mkdir -p $(DESTDIR)" << prefix
<< l
->second
.GetInstallPath()
1630 fout
<< "\t chmod 755 $(DESTDIR)" << prefix
<< l
->second
.GetInstallPath()
1632 fout
<< "\t else true; \\\n";
1634 // now install the target
1635 switch (l
->second
.GetType())
1637 case cmTarget::STATIC_LIBRARY
:
1638 fout
<< "\t$(INSTALL_DATA) " << m_LibraryOutputPath
<< "lib"
1641 fout
<< " $(DESTDIR)" << prefix
<< l
->second
.GetInstallPath() << "\n";
1643 case cmTarget::SHARED_LIBRARY
:
1644 fout
<< "\t$(INSTALL_DATA) " << m_LibraryOutputPath
<< "lib"
1646 fout
<< m_Makefile
->GetDefinition("CMAKE_SHLIB_SUFFIX");
1647 fout
<< " $(DESTDIR)" << prefix
<< l
->second
.GetInstallPath() << "\n";
1649 case cmTarget::MODULE_LIBRARY
:
1650 fout
<< "\t$(INSTALL_DATA) " << m_LibraryOutputPath
<< "lib"
1652 fout
<< m_Makefile
->GetDefinition("CMAKE_MODULE_SUFFIX");
1653 fout
<< " $(DESTDIR)" << prefix
<< l
->second
.GetInstallPath() << "\n";
1655 case cmTarget::WIN32_EXECUTABLE
:
1656 case cmTarget::EXECUTABLE
:
1657 fout
<< "\t$(INSTALL_PROGRAM) " << m_ExecutableOutputPath
1659 << cmSystemTools::GetExecutableExtension()
1660 << " $(DESTDIR)" << prefix
<< l
->second
.GetInstallPath() << "\n";
1662 case cmTarget::INSTALL_FILES
:
1664 std::string sourcePath
= m_Makefile
->GetCurrentDirectory();
1665 std::string binaryPath
= m_Makefile
->GetCurrentOutputDirectory();
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
)
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")
1690 fout
<< "\t @$(INSTALL_DATA) ";
1693 << " $(DESTDIR)" << prefix
<< l
->second
.GetInstallPath() << "\n";
1697 case cmTarget::INSTALL_PROGRAMS
:
1699 std::string sourcePath
= m_Makefile
->GetCurrentDirectory();
1700 std::string binaryPath
= m_Makefile
->GetCurrentOutputDirectory();
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
)
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")
1725 fout
<< "\t @$(INSTALL_PROGRAM) ";
1728 << " $(DESTDIR)" << prefix
<< l
->second
.GetInstallPath() << "\n";
1732 case cmTarget::UTILITY
:
1740 void cmLocalUnixMakefileGenerator::OutputMakeRules(std::ostream
& fout
)
1742 this->OutputMakeRule(fout
,
1743 "Default build rule",
1745 "cmake.depends $(TARGETS) $(SUBDIR_BUILD)",
1747 this->OutputMakeRule(fout
,
1748 "remove generated files",
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.",
1776 "$(CMAKE_MAKEFILE_SOURCES)",
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",
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",
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.",
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",
1809 "$(CMAKE_BINARY_DIR)/CMakeCache.txt",
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",
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",
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.",
1835 "Makefile cmake.depends",
1838 this->OutputSourceObjectBuildRules(fout
);
1840 std::string ctest
= m_Makefile
->GetDefinition("CMAKE_COMMAND");
1841 ctest
= cmSystemTools::GetFilenamePath(ctest
.c_str());
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());
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/";
1859 ctest
+= cmSystemTools::GetExecutableExtension();
1861 if (cmSystemTools::FileExists(ctest
.c_str()))
1863 this->OutputMakeRule(fout
,
1867 cmSystemTools::ConvertToOutputPath(ctest
.c_str()).c_str());
1872 cmLocalUnixMakefileGenerator::
1873 OutputBuildObjectFromSource(std::ostream
& fout
,
1874 const char* shortName
,
1875 const cmSourceFile
& source
,
1876 const char* extraCompileFlags
,
1879 // Header files shouldn't have build rules.
1880 if(source
.GetPropertyAsBool("HEADER_FILE_ONLY"))
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
;
1899 compileCommand
+= "$(CMAKE_SHLIB_CFLAGS) ";
1901 compileCommand
+= "$(INCLUDE_FLAGS) -c ";
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
;
1913 compileCommand
+= "$(CMAKE_SHLIB_CFLAGS) ";
1915 compileCommand
+= "$(INCLUDE_FLAGS) -c ";
1917 cmSystemTools::ConvertToOutputPath(source
.GetFullPath().c_str());
1918 compileCommand
+= " -o ";
1919 compileCommand
+= objectFile
;
1921 this->OutputMakeRule(fout
,
1924 cmSystemTools::ConvertToOutputPath(source
.GetFullPath().
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
= "";
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());
1977 std::string outPath
= m_Makefile
->GetCurrentOutputDirectory();
1978 outPath
+= "/"+relPath
;
1979 cmSystemTools::MakeDirectory(outPath
.c_str());
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");
1997 this->OutputBuildObjectFromSource(fout
,
2002 rules
.insert(shortNameWithExt
);
2009 void cmLocalUnixMakefileGenerator::OutputMakeRule(std::ostream
& fout
,
2010 const char* comment
,
2012 const char* depends
,
2013 const char* command
,
2014 const char* command2
,
2015 const char* command3
,
2016 const char* command4
)
2020 cmSystemTools::Error("no target for OutputMakeRule");
2024 std::string replace
;
2028 m_Makefile
->ExpandVariablesInString(replace
);
2029 fout
<< "#---------------------------------------------------------\n";
2030 fout
<< "# " << replace
;
2036 m_Makefile
->ExpandVariablesInString(replace
);
2037 fout
<< cmSystemTools::ConvertToOutputPath(replace
.c_str()) << ": ";
2042 m_Makefile
->ExpandVariablesInString(replace
);
2043 fout
<< replace
.c_str();
2047 const char* commands
[] = { command
, command2
, command3
, command4
};
2049 for (unsigned int i
= 0; i
< sizeof(commands
) / sizeof(commands
[0]); ++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";
2070 cmSystemTools::ReplaceString(echostring
, "\n\t", "\n\techo ");
2071 fout
<< "\techo " << echostring
.c_str() << "\n";
2074 fout
<< "\t" << replace
.c_str() << "\n";