~ubuntu-branches/ubuntu/utopic/cmake/utopic

« back to all changes in this revision

Viewing changes to Source/cmGlobalNinjaGenerator.cxx

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-10-10 12:54:39 UTC
  • mfrom: (1.14.7)
  • Revision ID: package-import@ubuntu.com-20131010125439-h0ahaj004on6oj92
Tags: 2.8.12-0ubuntu1
New upstream release LP: #1246701

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
11
  See the License for more information.
12
12
============================================================================*/
 
13
#include "cmGeneratedFileStream.h"
 
14
#include "cmGeneratorExpressionEvaluationFile.h"
 
15
#include "cmGeneratorTarget.h"
13
16
#include "cmGlobalNinjaGenerator.h"
14
17
#include "cmLocalNinjaGenerator.h"
15
18
#include "cmMakefile.h"
16
 
#include "cmGeneratedFileStream.h"
17
 
#include "cmGeneratorTarget.h"
18
19
#include "cmVersion.h"
19
20
 
20
21
#include <algorithm>
140
141
  for(cmNinjaDeps::const_iterator i = explicitDeps.begin();
141
142
      i != explicitDeps.end();
142
143
      ++i)
 
144
    {
143
145
    arguments  << " " << EncodeIdent(EncodePath(*i), os);
144
146
 
 
147
    //we need to track every dependency that comes in, since we are trying
 
148
    //to find dependencies that are side effects of build commands
 
149
    //
 
150
    this->CombinedBuildExplicitDependencies.insert( EncodePath(*i) );
 
151
    }
 
152
 
145
153
  // Write implicit dependencies.
146
154
  if(!implicitDeps.empty())
147
155
    {
170
178
  build << "build";
171
179
  for(cmNinjaDeps::const_iterator i = outputs.begin();
172
180
      i != outputs.end(); ++i)
 
181
    {
173
182
    build << " " << EncodeIdent(EncodePath(*i), os);
 
183
    this->CombinedBuildOutputs.insert( EncodePath(*i) );
 
184
    }
174
185
  build << ":";
175
186
 
176
187
  // Write the rule.
208
219
                                             const cmNinjaDeps& orderOnlyDeps,
209
220
                                             const cmNinjaVars& variables)
210
221
{
211
 
  cmGlobalNinjaGenerator::WriteBuild(os,
212
 
                                     comment,
213
 
                                     "phony",
214
 
                                     outputs,
215
 
                                     explicitDeps,
216
 
                                     implicitDeps,
217
 
                                     orderOnlyDeps,
218
 
                                     variables);
 
222
  this->WriteBuild(os,
 
223
                   comment,
 
224
                   "phony",
 
225
                   outputs,
 
226
                   explicitDeps,
 
227
                   implicitDeps,
 
228
                   orderOnlyDeps,
 
229
                   variables);
219
230
}
220
231
 
221
232
void cmGlobalNinjaGenerator::AddCustomCommandRule()
251
262
  vars["COMMAND"] = cmd;
252
263
  vars["DESC"] = EncodeLiteral(description);
253
264
 
254
 
  cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream,
255
 
                                     comment,
256
 
                                     "CUSTOM_COMMAND",
257
 
                                     outputs,
258
 
                                     deps,
259
 
                                     cmNinjaDeps(),
260
 
                                     orderOnlyDeps,
261
 
                                     vars);
 
265
  this->WriteBuild(*this->BuildFileStream,
 
266
                   comment,
 
267
                   "CUSTOM_COMMAND",
 
268
                   outputs,
 
269
                   deps,
 
270
                   cmNinjaDeps(),
 
271
                   orderOnlyDeps,
 
272
                   vars);
262
273
}
263
274
 
264
275
void
293
304
  deps.push_back(input);
294
305
  cmNinjaVars vars;
295
306
 
296
 
  cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream,
297
 
                                     "",
298
 
                                     "COPY_OSX_CONTENT",
299
 
                                     outputs,
300
 
                                     deps,
301
 
                                     cmNinjaDeps(),
302
 
                                     cmNinjaDeps(),
303
 
                                     cmNinjaVars());
 
307
  this->WriteBuild(*this->BuildFileStream,
 
308
                   "",
 
309
                   "COPY_OSX_CONTENT",
 
310
                   outputs,
 
311
                   deps,
 
312
                   cmNinjaDeps(),
 
313
                   cmNinjaDeps(),
 
314
                   cmNinjaVars());
304
315
}
305
316
 
306
317
void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
478
489
 
479
490
  this->WriteAssumedSourceDependencies();
480
491
  this->WriteTargetAliases(*this->BuildFileStream);
 
492
  this->WriteUnknownExplicitDependencies(*this->BuildFileStream);
481
493
  this->WriteBuiltinTargets(*this->BuildFileStream);
482
494
 
483
495
  if (cmSystemTools::GetErrorOccuredFlag()) {
523
535
std::string cmGlobalNinjaGenerator
524
536
::GenerateBuildCommand(const char* makeProgram,
525
537
                       const char* projectName,
 
538
                       const char* projectDir,
526
539
                       const char* additionalOptions,
527
540
                       const char* targetName,
528
541
                       const char* config,
529
542
                       bool ignoreErrors,
530
543
                       bool fast)
531
544
{
532
 
  // Project name and config are not used yet.
 
545
  // Project name & dir and config are not used yet.
533
546
  (void)projectName;
 
547
  (void)projectDir;
534
548
  (void)config;
535
549
  // Ninja does not have -i equivalent option yet.
536
550
  (void)ignoreErrors;
810
824
  cmLocalNinjaGenerator *ng =
811
825
    static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
812
826
 
 
827
  // for frameworks, we want the real name, not smple name
 
828
  // frameworks always appear versioned, and the build.ninja
 
829
  // will always attempt to manage symbolic links instead
 
830
  // of letting cmOSXBundleGenerator do it.
 
831
  bool realname = target->IsFrameworkOnApple();
 
832
 
813
833
  switch (target->GetType()) {
814
834
  case cmTarget::EXECUTABLE:
815
835
  case cmTarget::SHARED_LIBRARY:
816
836
  case cmTarget::STATIC_LIBRARY:
817
837
  case cmTarget::MODULE_LIBRARY:
818
838
    outputs.push_back(ng->ConvertToNinjaPath(
819
 
      target->GetFullPath(configName).c_str()));
 
839
      target->GetFullPath(configName, false, realname).c_str()));
820
840
    break;
821
841
 
822
842
  case cmTarget::OBJECT_LIBRARY:
885
905
  cmGlobalNinjaGenerator::WriteDivider(os);
886
906
  os << "# Target aliases.\n\n";
887
907
 
888
 
  for (TargetAliasMap::iterator i = TargetAliases.begin();
 
908
  for (TargetAliasMap::const_iterator i = TargetAliases.begin();
889
909
       i != TargetAliases.end(); ++i) {
890
910
    // Don't write ambiguous aliases.
891
911
    if (!i->second)
894
914
    cmNinjaDeps deps;
895
915
    this->AppendTargetOutputs(i->second, deps);
896
916
 
897
 
    cmGlobalNinjaGenerator::WritePhonyBuild(os,
898
 
                                            "",
899
 
                                            cmNinjaDeps(1, i->first),
900
 
                                            deps);
 
917
    this->WritePhonyBuild(os,
 
918
                          "",
 
919
                          cmNinjaDeps(1, i->first),
 
920
                          deps);
901
921
  }
902
922
}
903
923
 
 
924
void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
 
925
{
 
926
  //now write out the unknown explicit dependencies.
 
927
 
 
928
  //union the configured files, evaluations files and the CombinedBuildOutputs,
 
929
  //and then difference with CombinedExplicitDependencies to find the explicit
 
930
  //dependencies that we have no rule for
 
931
 
 
932
  cmGlobalNinjaGenerator::WriteDivider(os);
 
933
  os << "# Unknown Build Time Dependencies.\n"
 
934
     << "# Tell Ninja that they may appear as side effects of build rules\n"
 
935
     << "# otherwise ordered by order-only dependencies.\n\n";
 
936
 
 
937
  //get the list of files that cmake itself has generated as a
 
938
  //product of configuration.
 
939
  cmLocalNinjaGenerator *ng =
 
940
    static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
 
941
 
 
942
  std::set<std::string> knownDependencies;
 
943
  for (std::vector<cmLocalGenerator *>::const_iterator i =
 
944
       this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i)
 
945
    {
 
946
    //get the vector of files created by this makefile and convert them
 
947
    //to ninja paths, which are all relative in respect to the build directory
 
948
    const std::vector<std::string>& files =
 
949
                                    (*i)->GetMakefile()->GetOutputFiles();
 
950
    typedef std::vector<std::string>::const_iterator vect_it;
 
951
    for(vect_it j = files.begin(); j != files.end(); ++j)
 
952
      {
 
953
      knownDependencies.insert( ng->ConvertToNinjaPath( j->c_str() ) );
 
954
      }
 
955
    }
 
956
 
 
957
  for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator
 
958
      li = this->EvaluationFiles.begin();
 
959
      li != this->EvaluationFiles.end();
 
960
      ++li)
 
961
    {
 
962
    //get all the files created by generator expressions and convert them
 
963
    //to ninja paths
 
964
    std::vector<std::string> files = (*li)->GetFiles();
 
965
    typedef std::vector<std::string>::const_iterator vect_it;
 
966
    for(vect_it j = files.begin(); j != files.end(); ++j)
 
967
      {
 
968
      knownDependencies.insert( ng->ConvertToNinjaPath( j->c_str() ) );
 
969
      }
 
970
    }
 
971
 
 
972
  for(TargetAliasMap::const_iterator i= this->TargetAliases.begin();
 
973
      i != this->TargetAliases.end();
 
974
      ++i)
 
975
    {
 
976
    knownDependencies.insert( ng->ConvertToNinjaPath(i->first.c_str()) );
 
977
    }
 
978
 
 
979
  //remove all source files we know will exist.
 
980
  typedef std::map<std::string, std::set<std::string> >::const_iterator map_it;
 
981
  for(map_it i = this->AssumedSourceDependencies.begin();
 
982
      i != this->AssumedSourceDependencies.end();
 
983
      ++i)
 
984
    {
 
985
    knownDependencies.insert( ng->ConvertToNinjaPath(i->first.c_str()) );
 
986
    }
 
987
 
 
988
  //insert outputs from all WirteBuild commands
 
989
  for(std::set<std::string>::iterator i = this->CombinedBuildOutputs.begin();
 
990
      i != this->CombinedBuildOutputs.end(); ++i)
 
991
    {
 
992
    //these paths have already be encoded when added to CombinedBuildOutputs
 
993
    knownDependencies.insert(*i);
 
994
    }
 
995
 
 
996
  //after we have combined the data into knownDependencies we have no need
 
997
  //to keep this data around
 
998
  this->CombinedBuildOutputs.clear();
 
999
 
 
1000
  //now we difference with CombinedBuildExplicitDependencies to find
 
1001
  //the list of items we know nothing about.
 
1002
  //We have encoded all the paths in CombinedBuildExplicitDependencies
 
1003
  //and knownDependencies so no matter if unix or windows paths they
 
1004
  //should all match now.
 
1005
 
 
1006
  std::vector<std::string> unkownExplicitDepends;
 
1007
  this->CombinedBuildExplicitDependencies.erase("all");
 
1008
 
 
1009
  std::set_difference(this->CombinedBuildExplicitDependencies.begin(),
 
1010
                      this->CombinedBuildExplicitDependencies.end(),
 
1011
                      knownDependencies.begin(),
 
1012
                      knownDependencies.end(),
 
1013
                      std::back_inserter(unkownExplicitDepends));
 
1014
 
 
1015
 
 
1016
  std::string const rootBuildDirectory =
 
1017
      this->GetCMakeInstance()->GetHomeOutputDirectory();
 
1018
  for (std::vector<std::string>::const_iterator
 
1019
       i = unkownExplicitDepends.begin();
 
1020
       i != unkownExplicitDepends.end();
 
1021
       ++i)
 
1022
    {
 
1023
    //verify the file is in the build directory
 
1024
    std::string const absDepPath = cmSystemTools::CollapseFullPath(
 
1025
                                     i->c_str(), rootBuildDirectory.c_str());
 
1026
    bool const inBuildDir = cmSystemTools::IsSubDirectory(absDepPath.c_str(),
 
1027
                                                  rootBuildDirectory.c_str());
 
1028
    if(inBuildDir)
 
1029
      {
 
1030
      cmNinjaDeps deps(1,*i);
 
1031
      this->WritePhonyBuild(os,
 
1032
                            "",
 
1033
                            deps,
 
1034
                            deps);
 
1035
      }
 
1036
   }
 
1037
}
 
1038
 
904
1039
void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
905
1040
{
906
1041
  // Write headers.
918
1053
  cmNinjaDeps outputs;
919
1054
  outputs.push_back("all");
920
1055
 
921
 
  cmGlobalNinjaGenerator::WritePhonyBuild(os,
922
 
                                          "The main all target.",
923
 
                                          outputs,
924
 
                                          this->AllDependencies);
 
1056
  this->WritePhonyBuild(os,
 
1057
                        "The main all target.",
 
1058
                        outputs,
 
1059
                        this->AllDependencies);
925
1060
 
926
1061
  cmGlobalNinjaGenerator::WriteDefault(os,
927
1062
                                       outputs,
959
1094
       this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i) {
960
1095
    const std::vector<std::string>& lf = (*i)->GetMakefile()->GetListFiles();
961
1096
    implicitDeps.insert(implicitDeps.end(), lf.begin(), lf.end());
 
1097
 
 
1098
    const std::vector<std::string>& of = (*i)->GetMakefile()->GetOutputFiles();
 
1099
    implicitDeps.insert(implicitDeps.end(), of.begin(), of.end());
962
1100
  }
963
1101
  std::sort(implicitDeps.begin(), implicitDeps.end());
964
1102
  implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()),
965
1103
                     implicitDeps.end());
966
1104
  implicitDeps.push_back("CMakeCache.txt");
967
1105
 
968
 
  WriteBuild(os,
969
 
             "Re-run CMake if any of its inputs changed.",
970
 
             "RERUN_CMAKE",
971
 
             /*outputs=*/ cmNinjaDeps(1, NINJA_BUILD_FILE),
972
 
             /*explicitDeps=*/ cmNinjaDeps(),
973
 
             implicitDeps,
974
 
             /*orderOnlyDeps=*/ cmNinjaDeps(),
975
 
             /*variables=*/ cmNinjaVars());
 
1106
  this->WriteBuild(os,
 
1107
                   "Re-run CMake if any of its inputs changed.",
 
1108
                   "RERUN_CMAKE",
 
1109
                   /*outputs=*/ cmNinjaDeps(1, NINJA_BUILD_FILE),
 
1110
                   /*explicitDeps=*/ cmNinjaDeps(),
 
1111
                   implicitDeps,
 
1112
                   /*orderOnlyDeps=*/ cmNinjaDeps(),
 
1113
                   /*variables=*/ cmNinjaVars());
976
1114
 
977
 
  WritePhonyBuild(os,
978
 
                  "A missing CMake input file is not an error.",
979
 
                  implicitDeps,
980
 
                  cmNinjaDeps());
 
1115
  this->WritePhonyBuild(os,
 
1116
                        "A missing CMake input file is not an error.",
 
1117
                        implicitDeps,
 
1118
                        cmNinjaDeps());
981
1119
}
982
1120
 
983
1121
std::string cmGlobalNinjaGenerator::ninjaCmd() const