浏览代码

Merge branch 'custom-command-multiple-outputs' into release

Brad King 10 年之前
父节点
当前提交
74337b87ac

+ 34 - 24
Source/cmMakefileTargetGenerator.cxx

@@ -767,7 +767,7 @@ cmMakefileTargetGenerator
 
   // Write the rule.
   this->WriteMakeRule(*this->BuildFileStream, 0, outputs,
-                      depends, commands, false);
+                      depends, commands);
 
   bool do_preprocess_rules = lang_has_preprocessor &&
     this->LocalGenerator->GetCreatePreprocessedSourceRules();
@@ -989,18 +989,30 @@ void cmMakefileTargetGenerator::WriteTargetCleanRules()
 }
 
 //----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::WriteMakeRule(
+bool cmMakefileTargetGenerator::WriteMakeRule(
   std::ostream& os,
   const char* comment,
   const std::vector<std::string>& outputs,
   const std::vector<std::string>& depends,
   const std::vector<std::string>& commands,
-  bool symbolic,
   bool in_help)
 {
+  bool symbolic = false;
   if (outputs.size() == 0)
     {
-    return;
+    return symbolic;
+    }
+
+  // Check whether we need to bother checking for a symbolic output.
+  bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
+
+  // Check whether the first output is marked as symbolic.
+  if(need_symbolic)
+    {
+    if(cmSourceFile* sf = this->Makefile->GetSource(outputs[0]))
+      {
+      symbolic = sf->GetPropertyAsBool("SYMBOLIC");
+      }
     }
 
   // We always attach the actual commands to the first output.
@@ -1010,7 +1022,7 @@ void cmMakefileTargetGenerator::WriteMakeRule(
   // For single outputs, we are done.
   if (outputs.size() == 1)
     {
-    return;
+    return symbolic;
     }
 
   // For multiple outputs, make the extra ones depend on the first one.
@@ -1023,14 +1035,25 @@ void cmMakefileTargetGenerator::WriteMakeRule(
     std::string const out = this->Convert(*o, cmLocalGenerator::HOME_OUTPUT,
                                           cmLocalGenerator::SHELL);
     std::vector<std::string> output_commands;
-    if (!symbolic)
+
+    bool o_symbolic = false;
+    if(need_symbolic)
+      {
+      if(cmSourceFile* sf = this->Makefile->GetSource(*o))
+        {
+        o_symbolic = sf->GetPropertyAsBool("SYMBOLIC");
+        }
+      }
+    symbolic = symbolic && o_symbolic;
+
+    if (!o_symbolic)
       {
       output_commands.push_back("@$(CMAKE_COMMAND) -E touch_nocreate " + out);
       }
     this->LocalGenerator->WriteMakeRule(os, 0, *o, output_depends,
-                                        output_commands, symbolic, in_help);
+                                        output_commands, o_symbolic, in_help);
 
-    if (!symbolic)
+    if (!o_symbolic)
       {
       // At build time, remove the first output if this one does not exist
       // so that "make" will rerun the real commands that create this one.
@@ -1038,6 +1061,7 @@ void cmMakefileTargetGenerator::WriteMakeRule(
       this->MultipleOutputPairs.insert(p);
       }
     }
+  return symbolic;
 }
 
 //----------------------------------------------------------------------------
@@ -1289,30 +1313,16 @@ void cmMakefileTargetGenerator
   std::vector<std::string> depends;
   this->LocalGenerator->AppendCustomDepend(depends, ccg);
 
-  // Check whether we need to bother checking for a symbolic output.
-  bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
-
   // Write the rule.
   const std::vector<std::string>& outputs = ccg.GetOutputs();
-  std::vector<std::string>::const_iterator o = outputs.begin();
-  {
-  bool symbolic = false;
-  if(need_symbolic)
-    {
-    if(cmSourceFile* sf = this->Makefile->GetSource(*o))
-      {
-      symbolic = sf->GetPropertyAsBool("SYMBOLIC");
-      }
-    }
-  this->WriteMakeRule(*this->BuildFileStream, 0, outputs,
-                      depends, commands, symbolic);
+  bool symbolic = this->WriteMakeRule(*this->BuildFileStream, 0,
+                                      outputs, depends, commands);
 
   // If the rule has changed make sure the output is rebuilt.
   if(!symbolic)
     {
     this->GlobalGenerator->AddRuleHash(ccg.GetOutputs(), content.str());
     }
-  }
 
   // Setup implicit dependency scanning.
   for(cmCustomCommand::ImplicitDependsList::const_iterator

+ 1 - 2
Source/cmMakefileTargetGenerator.h

@@ -224,12 +224,11 @@ protected:
 
   typedef std::map<std::string, std::string> MultipleOutputPairsType;
   MultipleOutputPairsType MultipleOutputPairs;
-  void WriteMakeRule(std::ostream& os,
+  bool WriteMakeRule(std::ostream& os,
                      const char* comment,
                      const std::vector<std::string>& outputs,
                      const std::vector<std::string>& depends,
                      const std::vector<std::string>& commands,
-                     bool symbolic,
                      bool in_help = false);
 
   // Target name info.

+ 12 - 5
Source/kwsys/SystemTools.cxx

@@ -1215,15 +1215,22 @@ bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
 
 bool SystemTools::Touch(const kwsys_stl::string& filename, bool create)
 {
-  if(create && !SystemTools::FileExists(filename))
+  if (!SystemTools::FileExists(filename))
     {
-    FILE* file = Fopen(filename, "a+b");
-    if(file)
+    if(create)
+      {
+      FILE* file = Fopen(filename, "a+b");
+      if(file)
+        {
+        fclose(file);
+        return true;
+        }
+      return false;
+      }
+    else
       {
-      fclose(file);
       return true;
       }
-    return false;
     }
 #if defined(_WIN32) && !defined(__CYGWIN__)
   HANDLE h = CreateFileW(

+ 65 - 0
Tests/BuildDepends/CMakeLists.txt

@@ -42,6 +42,11 @@ list(APPEND _cmake_options "-DTEST_LINK_DEPENDS=${TEST_LINK_DEPENDS}")
 
 list(APPEND _cmake_options "-DCMAKE_FORCE_DEPFILES=1")
 
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio ([^6789]|[6789][0-9])")
+  set(TEST_MULTI3 1)
+  list(APPEND _cmake_options "-DTEST_MULTI3=1")
+endif()
+
 file(MAKE_DIRECTORY ${BuildDepends_BINARY_DIR}/Project)
 message("Creating Project/foo.cxx")
 write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
@@ -66,6 +71,8 @@ set(link_depends_no_shared_check_txt ${BuildDepends_BINARY_DIR}/Project/link_dep
 
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external original\n")
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in original\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt "multi2-stamp original\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt "multi3-stamp original\n")
 
 help_xcode_depends()
 
@@ -191,6 +198,34 @@ else()
     "multi1-out2-copy.txt is missing")
 endif()
 
+if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi2-real.txt)
+  if(${BuildDepends_BINARY_DIR}/Project/multi2-real.txt
+      IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt)
+    message(STATUS "multi2-real.txt is newer than multi2-stamp.txt")
+  else()
+    message(SEND_ERROR "Project did not initially build properly: "
+      "multi2-real.txt is not newer than multi2-stamp.txt")
+  endif()
+else()
+  message(SEND_ERROR "Project did not initially build properly: "
+    "multi2-real.txt is missing")
+endif()
+
+if(TEST_MULTI3)
+  if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi3-real.txt)
+    if(${BuildDepends_BINARY_DIR}/Project/multi3-real.txt
+        IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt)
+      message(STATUS "multi3-real.txt is newer than multi3-stamp.txt")
+    else()
+      message(SEND_ERROR "Project did not initially build properly: "
+        "multi3-real.txt is not newer than multi3-stamp.txt")
+    endif()
+  else()
+    message(SEND_ERROR "Project did not initially build properly: "
+      "multi3-real.txt is missing")
+  endif()
+endif()
+
 message("Waiting 3 seconds...")
 execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 3)
 
@@ -217,6 +252,8 @@ endif()
 
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external changed\n")
 file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in changed\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt "multi2-stamp changed\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt "multi3-stamp changed\n")
 
 help_xcode_depends()
 
@@ -347,3 +384,31 @@ else()
   message(SEND_ERROR "Project did not rebuild properly: "
     "multi1-out2-copy.txt is missing")
 endif()
+
+if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi2-real.txt)
+  if(${BuildDepends_BINARY_DIR}/Project/multi2-real.txt
+      IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt)
+    message(STATUS "multi2-real.txt is newer than multi2-stamp.txt")
+  else()
+    message(SEND_ERROR "Project did not rebuild properly: "
+      "multi2-real.txt is not newer than multi2-stamp.txt")
+  endif()
+else()
+  message(SEND_ERROR "Project did not rebuild properly: "
+    "multi2-real.txt is missing")
+endif()
+
+if(TEST_MULTI3)
+  if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi3-real.txt)
+    if(${BuildDepends_BINARY_DIR}/Project/multi3-real.txt
+        IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt)
+      message(STATUS "multi3-real.txt is newer than multi3-stamp.txt")
+    else()
+      message(SEND_ERROR "Project did not rebuild properly: "
+        "multi3-real.txt is not newer than multi3-stamp.txt")
+    endif()
+  else()
+    message(SEND_ERROR "Project did not rebuild properly: "
+      "multi3-real.txt is missing")
+  endif()
+endif()

+ 18 - 0
Tests/BuildDepends/Project/CMakeLists.txt

@@ -164,3 +164,21 @@ add_custom_command(
   DEPENDS multi1-out2.txt
   )
 add_custom_target(multi1 ALL DEPENDS multi1-out2-copy.txt)
+
+# Test having the first output never created.
+add_custom_command(
+  OUTPUT multi2-dummy.txt multi2-real.txt
+  COMMAND ${CMAKE_COMMAND} -E touch multi2-real.txt
+  )
+set_property(SOURCE multi2-real.txt multi2-dummy.txt PROPERTY SYMBOLIC 1)
+add_custom_target(multi2 ALL DEPENDS multi2-real.txt)
+
+if(TEST_MULTI3)
+  # Test having the second output never created.  Does not work with msbuild.
+  add_custom_command(
+    OUTPUT multi3-real.txt multi3-dummy.txt
+    COMMAND ${CMAKE_COMMAND} -E touch multi3-real.txt
+    )
+  set_property(SOURCE multi3-real.txt multi3-dummy.txt PROPERTY SYMBOLIC 1)
+  add_custom_target(multi3 ALL DEPENDS multi3-real.txt)
+endif()