فهرست منبع

BUG: Restore old interface of "make foo.o" and "make foo.i" even though object file names now include source extensions. For Java we also need to always remove the source extension (.java -> .class). This fixes the re-opening of bug #6169.

Brad King 18 سال پیش
والد
کامیت
52eb0ccac7

+ 1 - 0
Modules/CMakeJavaCompiler.cmake.in

@@ -7,6 +7,7 @@ SET(CMAKE_Java_COMPILER_LOADED 1)
 SET(CMAKE_Java_SOURCE_FILE_EXTENSIONS java)
 SET(CMAKE_Java_LINKER_PREFERENCE 40)
 SET(CMAKE_Java_OUTPUT_EXTENSION .class)
+SET(CMAKE_Java_OUTPUT_EXTENSION_REPLACE 1)
 SET(CMAKE_STATIC_LIBRARY_PREFIX_Java "")
 SET(CMAKE_STATIC_LIBRARY_SUFFIX_Java ".jar")
 SET(CMAKE_Java_COMPILER_ENV_VAR "JAVA_COMPILER")

+ 22 - 3
Source/cmLocalGenerator.cxx

@@ -2700,7 +2700,8 @@ cmLocalGenerator
 std::string
 cmLocalGenerator
 ::GetObjectFileNameWithoutTarget(const cmSourceFile& source,
-                                 std::string::size_type dir_len)
+                                 std::string::size_type dir_len,
+                                 bool* hasSourceExtension)
 {
   // Construct the object file name using the full path to the source
   // file which is its only unique identification.
@@ -2751,11 +2752,25 @@ cmLocalGenerator
 
   // Replace the original source file extension with the object file
   // extension.
+  bool keptSourceExtension = true;
   if(!source.GetPropertyAsBool("KEEP_EXTENSION"))
     {
-    // Remove the original extension for CMake 2.4 compatibility.
-    if(this->NeedBackwardsCompatibility(2, 4))
+    // Decide whether this language wants to replace the source
+    // extension with the object extension.  For CMake 2.4
+    // compatibility do this by default.
+    bool replaceExt = this->NeedBackwardsCompatibility(2, 4);
+    if(!replaceExt)
+      {
+      std::string repVar = "CMAKE_";
+      repVar += source.GetLanguage();
+      repVar += "_OUTPUT_EXTENSION_REPLACE";
+      replaceExt = this->Makefile->IsOn(repVar.c_str());
+      }
+
+    // Remove the source extension if it is to be replaced.
+    if(replaceExt)
       {
+      keptSourceExtension = false;
       std::string::size_type dot_pos = objectName.rfind(".");
       if(dot_pos != std::string::npos)
         {
@@ -2767,6 +2782,10 @@ cmLocalGenerator
     objectName +=
       this->GlobalGenerator->GetLanguageOutputExtension(source);
     }
+  if(hasSourceExtension)
+    {
+    *hasSourceExtension = keptSourceExtension;
+    }
 
   // Convert to a safe name.
   return this->CreateSafeUniqueObjectFileName(objectName.c_str(), dir_len);

+ 2 - 1
Source/cmLocalGenerator.h

@@ -314,7 +314,8 @@ protected:
 
   // Compute object file names.
   std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
-                                             std::string::size_type dir_len);
+                                             std::string::size_type dir_len,
+                                             bool* hasSourceExtension = 0);
   std::string& CreateSafeUniqueObjectFileName(const char* sin,
                                               std::string::size_type dir_len);
 

+ 63 - 7
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -37,6 +37,25 @@
 #include <memory> // auto_ptr
 #include <queue>
 
+//----------------------------------------------------------------------------
+// Helper function used below.
+static std::string cmSplitExtension(std::string const& in, std::string& base)
+{
+  std::string ext;
+  std::string::size_type dot_pos = in.rfind(".");
+  if(dot_pos != std::string::npos)
+    {
+    // Remove the extension first in case &base == &in.
+    ext = in.substr(dot_pos, std::string::npos);
+    base = in.substr(0, dot_pos);
+    }
+  else
+    {
+    base = in;
+    }
+  return ext;
+}
+
 //----------------------------------------------------------------------------
 cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3()
 {
@@ -298,12 +317,45 @@ void
 cmLocalUnixMakefileGenerator3
 ::WriteObjectConvenienceRule(std::ostream& ruleFileStream,
                              const char* comment, const char* output,
-                             LocalObjectInfo const& targets)
+                             LocalObjectInfo const& info)
 {
+  // If the rule includes the source file extension then create a
+  // version that has the extension removed.  The help should include
+  // only the version without source extension.
+  bool inHelp = true;
+  if(info.HasSourceExtension)
+    {
+    // Remove the last extension.  This should be kept.
+    std::string outBase1 = output;
+    std::string outExt1 = cmSplitExtension(outBase1, outBase1);
+
+    // Now remove the source extension and put back the last
+    // extension.
+    std::string outNoExt;
+    cmSplitExtension(outBase1, outNoExt);
+    outNoExt += outExt1;
+
+    // Add a rule to drive the rule below.
+    std::vector<std::string> depends;
+    depends.push_back(output);
+    std::vector<std::string> commands;
+    cmGlobalUnixMakefileGenerator3* gg =
+      static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+    std::string emptyCommand = gg->GetEmptyRuleHackCommand();
+    if(!emptyCommand.empty())
+      {
+      commands.push_back(emptyCommand);
+      }
+
+    this->WriteMakeRule(ruleFileStream, 0,
+                        outNoExt.c_str(), depends, commands, true, true);
+    inHelp = false;
+    }
+
   // Recursively make the rule for each target using the object file.
   std::vector<std::string> commands;
-  for(std::vector<LocalObjectEntry>::const_iterator t = targets.begin();
-      t != targets.end(); ++t)
+  for(std::vector<LocalObjectEntry>::const_iterator t = info.begin();
+      t != info.end(); ++t)
     {
     std::string tgtMakefileName =
       this->GetRelativeTargetDirectory(*(t->Target));
@@ -322,7 +374,7 @@ cmLocalUnixMakefileGenerator3
   // Write the rule to the makefile.
   std::vector<std::string> no_depends;
   this->WriteMakeRule(ruleFileStream, comment,
-                      output, no_depends, commands, true, true);
+                      output, no_depends, commands, true, inHelp);
 }
 
 //----------------------------------------------------------------------------
@@ -1800,13 +1852,16 @@ std::string
 cmLocalUnixMakefileGenerator3
 ::GetObjectFileName(cmTarget& target,
                     const cmSourceFile& source,
-                    std::string* nameWithoutTargetDir)
+                    std::string* nameWithoutTargetDir,
+                    bool* hasSourceExtension)
 {
   if(const char* fileTargetDirectory =
      source.GetProperty("MACOSX_PACKAGE_LOCATION"))
     {
     // Special handling for OSX package files.
-    std::string objectName = this->GetObjectFileNameWithoutTarget(source, 0);
+    std::string objectName =
+      this->GetObjectFileNameWithoutTarget(source, 0,
+                                           hasSourceExtension);
     if(nameWithoutTargetDir)
       {
       *nameWithoutTargetDir = objectName;
@@ -1857,7 +1912,8 @@ cmLocalUnixMakefileGenerator3
     dir_len += 1;
     dir_len += obj.size();
     std::string objectName =
-      this->GetObjectFileNameWithoutTarget(source, dir_len);
+      this->GetObjectFileNameWithoutTarget(source, dir_len,
+                                           hasSourceExtension);
     if(nameWithoutTargetDir)
       {
       *nameWithoutTargetDir = objectName;

+ 7 - 3
Source/cmLocalUnixMakefileGenerator3.h

@@ -238,7 +238,10 @@ public:
     LocalObjectEntry(cmTarget* t, const char* lang):
       Target(t), Language(lang) {}
   };
-  class LocalObjectInfo: public std::vector<LocalObjectEntry> {};
+  struct LocalObjectInfo: public std::vector<LocalObjectEntry>
+  {
+    bool HasSourceExtension;
+  };
   std::map<cmStdString, LocalObjectInfo> const& GetLocalObjectFiles()
     { return this->LocalObjectFiles;}
 
@@ -299,11 +302,12 @@ protected:
                                const std::vector<std::string>& objects);
   void WriteObjectConvenienceRule(std::ostream& ruleFileStream,
                                   const char* comment, const char* output,
-                                  LocalObjectInfo const& targets);
+                                  LocalObjectInfo const& info);
   
   std::string GetObjectFileName(cmTarget& target,
                                 const cmSourceFile& source,
-                                std::string* nameWithoutTargetDir = 0);
+                                std::string* nameWithoutTargetDir = 0,
+                                bool* hasSourceExtension = 0);
 
   void AppendRuleDepend(std::vector<std::string>& depends,
                         const char* ruleFileName);

+ 9 - 5
Source/cmMakefileTargetGenerator.cxx

@@ -310,10 +310,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
     }
 
   // Get the full path name of the object file.
+  bool hasSourceExtension;
   std::string objNoTargetDir;
   std::string obj =
     this->LocalGenerator->GetObjectFileName(*this->Target, source,
-                                            &objNoTargetDir);
+                                            &objNoTargetDir,
+                                            &hasSourceExtension);
 
   // Avoid generating duplicate rules.
   if(this->ObjectFiles.find(obj) == this->ObjectFiles.end())
@@ -377,10 +379,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
     {
     objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir);
     }
-  this->LocalGenerator->LocalObjectFiles[objNoTargetDir].
-    push_back(
-      cmLocalUnixMakefileGenerator3::LocalObjectEntry(this->Target, lang)
-      );
+  cmLocalUnixMakefileGenerator3::LocalObjectInfo& info =
+    this->LocalGenerator->LocalObjectFiles[objNoTargetDir];
+  info.HasSourceExtension = hasSourceExtension;
+  info.push_back(
+    cmLocalUnixMakefileGenerator3::LocalObjectEntry(this->Target, lang)
+    );
 }
 
 //----------------------------------------------------------------------------