Bläddra i källkod

VSResource: Avoid windres /D with quoted spaces (#11695)

Improve test: print out what's happening along the way.
David Cole 14 år sedan
förälder
incheckning
008d116b17
4 ändrade filer med 109 tillägg och 13 borttagningar
  1. 22 3
      Tests/VSResource/CMakeLists.txt
  2. 77 7
      Tests/VSResource/main.cpp
  3. 9 2
      Tests/VSResource/test.rc
  4. 1 1
      Tests/VSResource/test.txt

+ 22 - 3
Tests/VSResource/CMakeLists.txt

@@ -5,12 +5,31 @@ string(REPLACE "/INCREMENTAL:YES" ""
   CMAKE_EXE_LINKER_FLAGS_DEBUG
   "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
 
-if(MSVC60 OR CYGWIN)
-  # VS6 and Cygwin rc compilers do not deal well with spaces in a "/D" value
+message(STATUS "CMAKE_RC_COMPILER='${CMAKE_RC_COMPILER}'")
+
+# Because of the following avoidance techniques required for windres and VS6,
+# we recommend using a configured header file, and defining preprocessor
+# symbols via #define code and including that header in the rc file. Using
+# add_definitions is fine for simple definitions (with no spaces and no
+# quoting), but requires avoidance or work-arounds beyond that...
+
+if(CMAKE_RC_COMPILER MATCHES windres)
+  # windres rc compiler does not properly define quoted /D values as strings
+  message(STATUS "CMAKE_RC_COMPILER MATCHES windres")
+  add_definitions(/DCMAKE_RCDEFINE=test.txt)
+  add_definitions(/DCMAKE_RCDEFINE_NO_QUOTED_STRINGS)
+elseif(MSVC60)
+  # VS6 rc compiler does not deal well with spaces in a "/D" value, but it can
+  # handle the quoting
+  message(STATUS "MSVC60")
   add_definitions(/DCMAKE_RCDEFINE="test.txt")
 else()
+  # expected case -- rc compiler is "capable enough"
+  message(STATUS
+    "rc compiler handles quoted strings with spaces in values via /D")
+  set(TEXTFILE_FROM_SOURCE_DIR "textfile, spaces in name, from binary dir")
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test.txt
-    "${CMAKE_CURRENT_BINARY_DIR}/test with spaces.txt" COPYONLY)
+    "${CMAKE_CURRENT_BINARY_DIR}/test with spaces.txt" @ONLY)
   include_directories(${CMAKE_CURRENT_BINARY_DIR})
   add_definitions(/DCMAKE_RCDEFINE="test with spaces.txt")
 endif()

+ 77 - 7
Tests/VSResource/main.cpp

@@ -1,10 +1,80 @@
 #include <windows.h>
+#include <stdio.h>
 
-int main(int argc, char** argv) {
-   HRSRC hello = ::FindResource(0, "hello", "TEXT");
-   if(hello) {
-      return 0;
-   } else {
-      return 1;
-   }
+struct x
+{
+  const char *txt;
+};
+
+int main(int argc, char** argv)
+{
+  int ret = 1;
+
+  fprintf(stdout, "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)\n");
+
+#ifdef CMAKE_RCDEFINE
+  fprintf(stdout, "CMAKE_RCDEFINE defined\n");
+#endif
+
+#ifdef CMAKE_RCDEFINE_NO_QUOTED_STRINGS
+  // Expect CMAKE_RCDEFINE to preprocess to exactly test.txt
+  x test;
+  test.txt = "*exactly* test.txt";
+  fprintf(stdout, "CMAKE_RCDEFINE_NO_QUOTED_STRINGS defined\n");
+  fprintf(stdout, "CMAKE_RCDEFINE is %s, and is *not* a string constant\n",
+    CMAKE_RCDEFINE);
+#else
+  // Expect CMAKE_RCDEFINE to be a string:
+  fprintf(stdout, "CMAKE_RCDEFINE='%s', and is a string constant\n",
+    CMAKE_RCDEFINE);
+#endif
+
+  HRSRC hello = ::FindResource(NULL, MAKEINTRESOURCE(1025), "TEXTFILE");
+  if(hello)
+    {
+    fprintf(stdout, "FindResource worked\n");
+    HGLOBAL hgbl = ::LoadResource(NULL, hello);
+    int datasize = (int) ::SizeofResource(NULL, hello);
+    if(hgbl && datasize>0)
+      {
+      fprintf(stdout, "LoadResource worked\n");
+      fprintf(stdout, "SizeofResource returned datasize='%d'\n", datasize);
+      void *data = ::LockResource(hgbl);
+      if (data)
+        {
+        fprintf(stdout, "LockResource worked\n");
+        char *str = (char *) malloc(datasize+4);
+        if (str)
+          {
+          memcpy(str, data, datasize);
+          str[datasize] = 'E';
+          str[datasize+1] = 'O';
+          str[datasize+2] = 'R';
+          str[datasize+3] = 0;
+          fprintf(stdout, "str='%s'\n", str);
+          free(str);
+
+          ret = 0;
+
+#ifdef CMAKE_RCDEFINE_NO_QUOTED_STRINGS
+          fprintf(stdout, "LoadString skipped\n");
+#else
+          char buf[256];
+          if (::LoadString(NULL, 1026, buf, sizeof(buf)) > 0)
+            {
+            fprintf(stdout, "LoadString worked\n");
+            fprintf(stdout, "buf='%s'\n", buf);
+            }
+          else
+            {
+            fprintf(stdout, "LoadString failed\n");
+            ret = 1;
+            }
+#endif
+          }
+        }
+      }
+    }
+
+  return ret;
 }

+ 9 - 2
Tests/VSResource/test.rc

@@ -1,10 +1,17 @@
 #ifdef CMAKE_RCDEFINE
-hello TEXT DISCARDABLE CMAKE_RCDEFINE
 
+// This line can compile with either an unquoted or a quoted string
+1025 TEXTFILE CMAKE_RCDEFINE
+
+#ifndef CMAKE_RCDEFINE_NO_QUOTED_STRINGS
+// This block can only be compiled if CMAKE_RCDEFINE preprocesses
+// to a double quoted string
 STRINGTABLE
 BEGIN
-  1 CMAKE_RCDEFINE
+  1026 CMAKE_RCDEFINE
 END
+#endif
+
 #else
 #error "resource compiler did not get defines from command line!"
 #endif

+ 1 - 1
Tests/VSResource/test.txt

@@ -1 +1 @@
-Hello World!
+Hello World! (@TEXTFILE_FROM_SOURCE_DIR@)