1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmMakefileLibraryTargetGenerator.h"
14 #include "cmGeneratedFileStream.h"
15 #include "cmGlobalUnixMakefileGenerator3.h"
16 #include "cmLocalUnixMakefileGenerator3.h"
17 #include "cmMakefile.h"
18 #include "cmSourceFile.h"
22 #include <memory> // auto_ptr
24 //----------------------------------------------------------------------------
25 cmMakefileLibraryTargetGenerator
26 ::cmMakefileLibraryTargetGenerator(cmTarget* target):
27 cmMakefileTargetGenerator(target)
29 cmOSXBundleGenerator::PrepareTargetProperties(this->Target);
31 this->CustomCommandDriver = OnDepends;
32 this->Target->GetLibraryNames(
33 this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
34 this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
36 this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
39 this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
40 this->MacContentDirectory =
41 this->OSXBundleGenerator->GetMacContentDirectory();
44 //----------------------------------------------------------------------------
45 cmMakefileLibraryTargetGenerator
46 ::~cmMakefileLibraryTargetGenerator()
48 delete this->OSXBundleGenerator;
51 //----------------------------------------------------------------------------
52 void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
54 // create the build.make file and directory, put in the common blocks
55 this->CreateRuleFile();
57 // write rules used to help build object files
58 this->WriteCommonCodeRules();
60 // write the per-target per-language flags
61 this->WriteTargetLanguageFlags();
63 // write in rules for object files and custom commands
64 this->WriteTargetBuildRules();
66 // write the link rules
67 // Write the rule for this target type.
68 switch(this->Target->GetType())
70 case cmTarget::STATIC_LIBRARY:
71 this->WriteStaticLibraryRules();
73 case cmTarget::SHARED_LIBRARY:
74 this->WriteSharedLibraryRules(false);
75 if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
77 // Write rules to link an installable version of the target.
78 this->WriteSharedLibraryRules(true);
81 case cmTarget::MODULE_LIBRARY:
82 this->WriteModuleLibraryRules(false);
83 if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
85 // Write rules to link an installable version of the target.
86 this->WriteModuleLibraryRules(true);
89 case cmTarget::OBJECT_LIBRARY:
90 this->WriteObjectLibraryRules();
93 // If language is not known, this is an error.
94 cmSystemTools::Error("Unknown Library Type");
98 // Write the requires target.
99 this->WriteTargetRequiresRules();
101 // Write clean target
102 this->WriteTargetCleanRules();
104 // Write the dependency generation rule. This must be done last so
105 // that multiple output pair information is available.
106 this->WriteTargetDependRules();
109 this->CloseFileStreams();
112 //----------------------------------------------------------------------------
113 void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
115 std::vector<std::string> commands;
116 std::vector<std::string> depends;
118 // Add post-build rules.
119 this->LocalGenerator->
120 AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
123 // Depend on the object files.
124 this->AppendObjectDepends(depends);
127 this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
128 this->Target->GetName(),
129 depends, commands, true);
131 // Write the main driver rule to build everything in this target.
132 this->WriteTargetDriverRule(this->Target->GetName(), false);
135 //----------------------------------------------------------------------------
136 void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
138 const char* linkLanguage =
139 this->Target->GetLinkerLanguage(this->ConfigName);
140 std::string linkRuleVar = "CMAKE_";
143 linkRuleVar += linkLanguage;
145 linkRuleVar += "_CREATE_STATIC_LIBRARY";
147 if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION") &&
148 this->Makefile->GetDefinition((linkRuleVar+"_IPO").c_str()))
150 linkRuleVar += "_IPO";
153 std::string extraFlags;
154 this->LocalGenerator->AppendFlags
155 (extraFlags,this->Target->GetProperty("STATIC_LIBRARY_FLAGS"));
156 std::string staticLibraryFlagsConfig = "STATIC_LIBRARY_FLAGS_";
157 staticLibraryFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
158 this->LocalGenerator->AppendFlags
159 (extraFlags, this->Target->GetProperty(staticLibraryFlagsConfig.c_str()));
160 this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), false);
163 //----------------------------------------------------------------------------
164 void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
166 if(this->Target->IsFrameworkOnApple())
168 this->WriteFrameworkRules(relink);
171 const char* linkLanguage =
172 this->Target->GetLinkerLanguage(this->ConfigName);
173 std::string linkRuleVar = "CMAKE_";
176 linkRuleVar += linkLanguage;
178 linkRuleVar += "_CREATE_SHARED_LIBRARY";
180 std::string extraFlags;
181 this->LocalGenerator->AppendFlags
182 (extraFlags, this->Target->GetProperty("LINK_FLAGS"));
183 std::string linkFlagsConfig = "LINK_FLAGS_";
184 linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
185 this->LocalGenerator->AppendFlags
186 (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
188 this->LocalGenerator->AddConfigVariableFlags
189 (extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
190 this->AddModuleDefinitionFlag(extraFlags);
192 this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
195 //----------------------------------------------------------------------------
196 void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
198 const char* linkLanguage =
199 this->Target->GetLinkerLanguage(this->ConfigName);
200 std::string linkRuleVar = "CMAKE_";
203 linkRuleVar += linkLanguage;
205 linkRuleVar += "_CREATE_SHARED_MODULE";
207 std::string extraFlags;
208 this->LocalGenerator->AppendFlags(extraFlags,
209 this->Target->GetProperty("LINK_FLAGS"));
210 std::string linkFlagsConfig = "LINK_FLAGS_";
211 linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
212 this->LocalGenerator->AppendFlags
213 (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
214 this->LocalGenerator->AddConfigVariableFlags
215 (extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
216 this->AddModuleDefinitionFlag(extraFlags);
218 this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
221 //----------------------------------------------------------------------------
222 void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
224 const char* linkLanguage =
225 this->Target->GetLinkerLanguage(this->ConfigName);
226 std::string linkRuleVar = "CMAKE_";
229 linkRuleVar += linkLanguage;
231 linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
233 std::string extraFlags;
234 this->LocalGenerator->AppendFlags(extraFlags,
235 this->Target->GetProperty("LINK_FLAGS"));
236 std::string linkFlagsConfig = "LINK_FLAGS_";
237 linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
238 this->LocalGenerator->AppendFlags
239 (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
240 this->LocalGenerator->AddConfigVariableFlags
241 (extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
243 this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
246 //----------------------------------------------------------------------------
247 void cmMakefileLibraryTargetGenerator::WriteLibraryRules
248 (const char* linkRuleVar, const char* extraFlags, bool relink)
250 // TODO: Merge the methods that call this method to avoid
252 std::vector<std::string> commands;
254 // Build list of dependencies.
255 std::vector<std::string> depends;
256 this->AppendLinkDepends(depends);
258 // Get the language to use for linking this library.
259 const char* linkLanguage =
260 this->Target->GetLinkerLanguage(this->ConfigName);
262 // Make sure we have a link language.
265 cmSystemTools::Error("Cannot determine link language for target \"",
266 this->Target->GetName(), "\".");
270 // Create set of linking flags.
271 std::string linkFlags;
272 this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
274 // Add OSX version flags, if any.
275 if(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
276 this->Target->GetType() == cmTarget::MODULE_LIBRARY)
278 this->AppendOSXVerFlag(linkFlags, linkLanguage, "COMPATIBILITY", true);
279 this->AppendOSXVerFlag(linkFlags, linkLanguage, "CURRENT", false);
282 // Construct the name of the library.
283 std::string targetName;
284 std::string targetNameSO;
285 std::string targetNameReal;
286 std::string targetNameImport;
287 std::string targetNamePDB;
288 this->Target->GetLibraryNames(
289 targetName, targetNameSO, targetNameReal, targetNameImport, targetNamePDB,
292 // Construct the full path version of the names.
294 std::string outpathImp;
295 if(this->Target->IsFrameworkOnApple())
297 outpath = this->MacContentDirectory;
298 this->OSXBundleGenerator->CreateFramework(targetName);
300 else if(this->Target->IsCFBundleOnApple())
302 outpath = this->Target->GetDirectory(this->ConfigName);
304 this->OSXBundleGenerator->CreateCFBundle(targetName, outpath);
308 outpath = this->Makefile->GetStartOutputDirectory();
309 outpath += cmake::GetCMakeFilesDirectory();
310 outpath += "/CMakeRelink.dir";
311 cmSystemTools::MakeDirectory(outpath.c_str());
313 if(!targetNameImport.empty())
315 outpathImp = outpath;
320 outpath = this->Target->GetDirectory(this->ConfigName);
321 cmSystemTools::MakeDirectory(outpath.c_str());
323 if(!targetNameImport.empty())
325 outpathImp = this->Target->GetDirectory(this->ConfigName, true);
326 cmSystemTools::MakeDirectory(outpathImp.c_str());
331 std::string targetFullPath = outpath + targetName;
332 std::string targetFullPathPDB = outpath + targetNamePDB;
333 std::string targetFullPathSO = outpath + targetNameSO;
334 std::string targetFullPathReal = outpath + targetNameReal;
335 std::string targetFullPathImport = outpathImp + targetNameImport;
337 // Construct the output path version of the names for use in command
339 std::string targetOutPathPDB =
340 this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
341 cmLocalGenerator::SHELL);
342 std::string targetOutPath =
343 this->Convert(targetFullPath.c_str(),cmLocalGenerator::START_OUTPUT,
344 cmLocalGenerator::SHELL);
345 std::string targetOutPathSO =
346 this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT,
347 cmLocalGenerator::SHELL);
348 std::string targetOutPathReal =
349 this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT,
350 cmLocalGenerator::SHELL);
351 std::string targetOutPathImport =
352 this->Convert(targetFullPathImport.c_str(),cmLocalGenerator::START_OUTPUT,
353 cmLocalGenerator::SHELL);
355 if(!this->NoRuleMessages)
357 // Add the link message.
358 std::string buildEcho = "Linking ";
359 buildEcho += linkLanguage;
360 switch(this->Target->GetType())
362 case cmTarget::STATIC_LIBRARY:
363 buildEcho += " static library ";
365 case cmTarget::SHARED_LIBRARY:
366 buildEcho += " shared library ";
368 case cmTarget::MODULE_LIBRARY:
369 if (this->Target->IsCFBundleOnApple())
370 buildEcho += " CFBundle";
371 buildEcho += " shared module ";
374 buildEcho += " library ";
377 buildEcho += targetOutPath.c_str();
378 this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
379 cmLocalUnixMakefileGenerator3::EchoLink);
382 const char* forbiddenFlagVar = 0;
383 switch(this->Target->GetType())
385 case cmTarget::SHARED_LIBRARY:
386 forbiddenFlagVar = "_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS";
388 case cmTarget::MODULE_LIBRARY:
389 forbiddenFlagVar = "_CREATE_SHARED_MODULE_FORBIDDEN_FLAGS";
394 // Clean files associated with this library.
395 std::vector<std::string> libCleanFiles;
396 libCleanFiles.push_back(this->Convert(targetFullPath.c_str(),
397 cmLocalGenerator::START_OUTPUT,
398 cmLocalGenerator::UNCHANGED));
399 if(targetNameReal != targetName)
401 libCleanFiles.push_back(this->Convert(targetFullPathReal.c_str(),
402 cmLocalGenerator::START_OUTPUT,
403 cmLocalGenerator::UNCHANGED));
405 if(targetNameSO != targetName &&
406 targetNameSO != targetNameReal)
408 libCleanFiles.push_back(this->Convert(targetFullPathSO.c_str(),
409 cmLocalGenerator::START_OUTPUT,
410 cmLocalGenerator::UNCHANGED));
412 if(!targetNameImport.empty())
414 libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
415 cmLocalGenerator::START_OUTPUT,
416 cmLocalGenerator::UNCHANGED));
418 if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib))
420 libCleanFiles.push_back(this->Convert(implib.c_str(),
421 cmLocalGenerator::START_OUTPUT,
422 cmLocalGenerator::UNCHANGED));
426 // List the PDB for cleaning only when the whole target is
427 // cleaned. We do not want to delete the .pdb file just before
428 // linking the target.
429 this->CleanFiles.push_back
430 (this->Convert(targetFullPathPDB.c_str(),
431 cmLocalGenerator::START_OUTPUT,
432 cmLocalGenerator::UNCHANGED));
435 // There may be a manifest file for this target. Add it to the
436 // clean set just in case.
437 if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
439 libCleanFiles.push_back(
440 this->Convert((targetFullPath+".manifest").c_str(),
441 cmLocalGenerator::START_OUTPUT,
442 cmLocalGenerator::UNCHANGED));
446 std::vector<std::string> commands1;
447 // Add a command to remove any existing files for this library.
448 // for static libs only
449 if(this->Target->GetType() == cmTarget::STATIC_LIBRARY)
451 this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles,
452 *this->Target, "target");
453 this->LocalGenerator->CreateCDCommand
455 this->Makefile->GetStartOutputDirectory(),
456 cmLocalGenerator::HOME_OUTPUT);
457 commands.insert(commands.end(), commands1.begin(), commands1.end());
461 // Add the pre-build and pre-link rules building but not when relinking.
465 ->AppendCustomCommands(commands, this->Target->GetPreBuildCommands(),
468 ->AppendCustomCommands(commands, this->Target->GetPreLinkCommands(),
472 // Determine whether a link script will be used.
473 bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
475 // Select whether to use a response file for objects.
476 bool useResponseFile = false;
478 std::string responseVar = "CMAKE_";
479 responseVar += linkLanguage;
480 responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
481 if(this->Makefile->IsOn(responseVar.c_str()))
483 useResponseFile = true;
487 // For static libraries there might be archiving rules.
488 bool haveStaticLibraryRule = false;
489 std::vector<std::string> archiveCreateCommands;
490 std::vector<std::string> archiveAppendCommands;
491 std::vector<std::string> archiveFinishCommands;
492 std::string::size_type archiveCommandLimit = std::string::npos;
493 if(this->Target->GetType() == cmTarget::STATIC_LIBRARY)
495 haveStaticLibraryRule =
496 this->Makefile->GetDefinition(linkRuleVar)? true:false;
497 std::string arCreateVar = "CMAKE_";
498 arCreateVar += linkLanguage;
499 arCreateVar += "_ARCHIVE_CREATE";
500 if(const char* rule = this->Makefile->GetDefinition(arCreateVar.c_str()))
502 cmSystemTools::ExpandListArgument(rule, archiveCreateCommands);
504 std::string arAppendVar = "CMAKE_";
505 arAppendVar += linkLanguage;
506 arAppendVar += "_ARCHIVE_APPEND";
507 if(const char* rule = this->Makefile->GetDefinition(arAppendVar.c_str()))
509 cmSystemTools::ExpandListArgument(rule, archiveAppendCommands);
511 std::string arFinishVar = "CMAKE_";
512 arFinishVar += linkLanguage;
513 arFinishVar += "_ARCHIVE_FINISH";
514 if(const char* rule = this->Makefile->GetDefinition(arFinishVar.c_str()))
516 cmSystemTools::ExpandListArgument(rule, archiveFinishCommands);
520 // Decide whether to use archiving rules.
521 bool useArchiveRules =
522 !haveStaticLibraryRule &&
523 !archiveCreateCommands.empty() && !archiveAppendCommands.empty();
526 // Archiving rules are always run with a link script.
527 useLinkScript = true;
529 // Archiving rules never use a response file.
530 useResponseFile = false;
532 // Limit the length of individual object lists to less than the
533 // 32K command line length limit on Windows. We could make this a
534 // platform file variable but this should work everywhere.
535 archiveCommandLimit = 30000;
538 // Expand the rule variables.
539 std::vector<std::string> real_link_commands;
541 // Set path conversion for link script shells.
542 this->LocalGenerator->SetLinkScriptShell(useLinkScript);
544 // Collect up flags to link in needed libraries.
545 cmOStringStream linklibs;
546 if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
549 ->OutputLinkLibraries(linklibs, *this->Target, relink);
552 // Construct object file lists that may be needed to expand the
554 std::string buildObjs;
555 this->CreateObjectLists(useLinkScript, useArchiveRules, useResponseFile,
558 cmLocalGenerator::RuleVariables vars;
559 vars.TargetPDB = targetOutPathPDB.c_str();
561 // Setup the target version.
562 std::string targetVersionMajor;
563 std::string targetVersionMinor;
565 cmOStringStream majorStream;
566 cmOStringStream minorStream;
569 this->Target->GetTargetVersion(major, minor);
570 majorStream << major;
571 minorStream << minor;
572 targetVersionMajor = majorStream.str();
573 targetVersionMinor = minorStream.str();
575 vars.TargetVersionMajor = targetVersionMajor.c_str();
576 vars.TargetVersionMinor = targetVersionMinor.c_str();
578 vars.RuleLauncher = "RULE_LAUNCH_LINK";
579 vars.CMTarget = this->Target;
580 vars.Language = linkLanguage;
581 vars.Objects = buildObjs.c_str();
582 std::string objdir = cmake::GetCMakeFilesDirectoryPostSlash();
583 objdir += this->Target->GetName();
585 objdir = this->Convert(objdir.c_str(),
586 cmLocalGenerator::START_OUTPUT,
587 cmLocalGenerator::SHELL);
588 vars.ObjectDir = objdir.c_str();
589 vars.Target = targetOutPathReal.c_str();
590 std::string linkString = linklibs.str();
591 vars.LinkLibraries = linkString.c_str();
592 vars.ObjectsQuoted = buildObjs.c_str();
593 if (this->Target->HasSOName(this->ConfigName))
595 vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
596 vars.TargetSOName= targetNameSO.c_str();
598 vars.LinkFlags = linkFlags.c_str();
600 // Compute the directory portion of the install_name setting.
601 std::string install_name_dir;
602 if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
604 // Get the install_name directory for the build tree.
606 this->Target->GetInstallNameDirForBuildTree(this->ConfigName);
608 // Set the rule variable replacement value.
609 if(install_name_dir.empty())
611 vars.TargetInstallNameDir = "";
615 // Convert to a path for the native build tool.
617 this->LocalGenerator->Convert(install_name_dir.c_str(),
618 cmLocalGenerator::NONE,
619 cmLocalGenerator::SHELL, false);
620 vars.TargetInstallNameDir = install_name_dir.c_str();
624 // Add language feature flags.
625 std::string langFlags;
626 this->AddFeatureFlags(langFlags, linkLanguage);
628 this->LocalGenerator->AddArchitectureFlags(langFlags, this->Target,
629 linkLanguage, this->ConfigName);
631 // remove any language flags that might not work with the
635 this->RemoveForbiddenFlags(forbiddenFlagVar,
636 linkLanguage, langFlags);
638 vars.LanguageCompileFlags = langFlags.c_str();
640 // Construct the main link rule and expand placeholders.
641 this->LocalGenerator->TargetImplib = targetOutPathImport;
644 // Construct the individual object list strings.
645 std::vector<std::string> object_strings;
646 this->WriteObjectsStrings(object_strings, archiveCommandLimit);
648 // Create the archive with the first set of objects.
649 std::vector<std::string>::iterator osi = object_strings.begin();
651 vars.Objects = osi->c_str();
652 for(std::vector<std::string>::const_iterator
653 i = archiveCreateCommands.begin();
654 i != archiveCreateCommands.end(); ++i)
656 std::string cmd = *i;
657 this->LocalGenerator->ExpandRuleVariables(cmd, vars);
658 real_link_commands.push_back(cmd);
661 // Append to the archive with the other object sets.
662 for(++osi; osi != object_strings.end(); ++osi)
664 vars.Objects = osi->c_str();
665 for(std::vector<std::string>::const_iterator
666 i = archiveAppendCommands.begin();
667 i != archiveAppendCommands.end(); ++i)
669 std::string cmd = *i;
670 this->LocalGenerator->ExpandRuleVariables(cmd, vars);
671 real_link_commands.push_back(cmd);
674 // Finish the archive.
676 for(std::vector<std::string>::const_iterator
677 i = archiveFinishCommands.begin();
678 i != archiveFinishCommands.end(); ++i)
680 std::string cmd = *i;
681 this->LocalGenerator->ExpandRuleVariables(cmd, vars);
682 real_link_commands.push_back(cmd);
687 // Get the set of commands.
688 std::string linkRule = this->GetLinkRule(linkRuleVar);
689 cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
691 // Expand placeholders.
692 for(std::vector<std::string>::iterator i = real_link_commands.begin();
693 i != real_link_commands.end(); ++i)
695 this->LocalGenerator->ExpandRuleVariables(*i, vars);
698 this->LocalGenerator->TargetImplib = "";
700 // Restore path conversion to normal shells.
701 this->LocalGenerator->SetLinkScriptShell(false);
704 // Optionally convert the build rule to use a script to avoid long
705 // command lines in the make shell.
708 // Use a link script.
709 const char* name = (relink? "relink.txt" : "link.txt");
710 this->CreateLinkScript(name, real_link_commands, commands1, depends);
714 // No link script. Just use the link rule directly.
715 commands1 = real_link_commands;
717 this->LocalGenerator->CreateCDCommand
719 this->Makefile->GetStartOutputDirectory(),
720 cmLocalGenerator::HOME_OUTPUT);
721 commands.insert(commands.end(), commands1.begin(), commands1.end());
724 // Add a rule to create necessary symlinks for the library.
725 if(targetOutPath != targetOutPathReal)
727 std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library ";
728 symlink += targetOutPathReal;
730 symlink += targetOutPathSO;
732 symlink += targetOutPath;
733 commands1.push_back(symlink);
734 this->LocalGenerator->CreateCDCommand(commands1,
735 this->Makefile->GetStartOutputDirectory(),
736 cmLocalGenerator::HOME_OUTPUT);
737 commands.insert(commands.end(), commands1.begin(), commands1.end());
740 // Add the post-build rules when building but not when relinking.
743 this->LocalGenerator->
744 AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
748 // Write the build rule.
749 this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
750 targetFullPathReal.c_str(),
751 depends, commands, false);
753 // Some targets have more than one output file. Create rules to
754 // drive the build if any extra outputs are missing.
755 std::vector<std::string> extraOutputs;
756 if(targetNameSO != targetNameReal)
758 this->GenerateExtraOutput(targetFullPathSO.c_str(),
759 targetFullPathReal.c_str());
761 if(targetName != targetNameSO &&
762 targetName != targetNameReal)
764 this->GenerateExtraOutput(targetFullPath.c_str(),
765 targetFullPathReal.c_str());
768 // Write the main driver rule to build everything in this target.
769 this->WriteTargetDriverRule(targetFullPath.c_str(), relink);
771 // Clean all the possible library names and symlinks.
772 this->CleanFiles.insert(this->CleanFiles.end(),
773 libCleanFiles.begin(),libCleanFiles.end());
776 //----------------------------------------------------------------------------
778 cmMakefileLibraryTargetGenerator
779 ::AppendOSXVerFlag(std::string& flags, const char* lang,
780 const char* name, bool so)
782 // Lookup the flag to specify the version.
783 std::string fvar = "CMAKE_";
787 fvar += "_VERSION_FLAG";
788 const char* flag = this->Makefile->GetDefinition(fvar.c_str());
790 // Skip if no such flag.
796 // Lookup the target version information.
800 this->Target->GetTargetVersion(so, major, minor, patch);
801 if(major > 0 || minor > 0 || patch > 0)
803 // Append the flag since a non-zero version is specified.
804 cmOStringStream vflag;
805 vflag << flag << major << "." << minor << "." << patch;
806 this->LocalGenerator->AppendFlags(flags, vflag.str().c_str());