Ver Fonte

PCH: Remove restrictions for REUSE_FROM signature for MSVC

Fixes: #20201
Cristian Adam há 4 anos atrás
pai
commit
c450d66daa

+ 16 - 7
Source/cmLocalGenerator.cxx

@@ -2610,16 +2610,25 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
                 }
               }
 
-              if (reuseTarget->GetType() != cmStateEnums::OBJECT_LIBRARY) {
-                std::string pchSourceObj =
-                  reuseTarget->GetPchFileObject(config, lang, arch);
-
-                // Link to the pch object file
+              // Link to the pch object file
+              std::string pchSourceObj =
+                reuseTarget->GetPchFileObject(config, lang, arch);
+
+              if (target->GetType() != cmStateEnums::OBJECT_LIBRARY) {
+                std::string linkerProperty = "LINK_FLAGS_";
+                if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+                  linkerProperty = "STATIC_LIBRARY_FLAGS_";
+                }
                 target->Target->AppendProperty(
-                  cmStrCat("LINK_FLAGS_", configUpper),
+                  cmStrCat(linkerProperty, configUpper),
                   cmStrCat(" ",
                            this->ConvertToOutputFormat(pchSourceObj, SHELL)),
                   true);
+              } else {
+                target->Target->AppendProperty(
+                  "INTERFACE_LINK_LIBRARIES",
+                  cmStrCat("$<$<CONFIG:", config,
+                           ">:$<LINK_ONLY:", pchSourceObj, ">>"));
               }
             }
           } else {
@@ -2738,7 +2747,7 @@ void cmLocalGenerator::CopyPchCompilePdb(
     this->AddCustomCommandToTarget(
       target->GetName(), outputs, no_deps, commandLines,
       cmCustomCommandType::PRE_BUILD, no_message, no_current_dir, true, false,
-      "", "", false, cmObjectLibraryCommands::Reject, stdPipesUTF8);
+      "", "", false, cmObjectLibraryCommands::Accept, stdPipesUTF8);
   } else {
     cmImplicitDependsList no_implicit_depends;
     cmSourceFile* copy_rule = this->AddCustomCommandToOutput(

+ 2 - 1
Source/cmLocalVisualStudio7Generator.cxx

@@ -1010,7 +1010,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
       this->GetStaticLibraryFlags(
         libflags, configName, target->GetLinkerLanguage(configName), target);
       if (!libflags.empty()) {
-        fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
+        fout << "\t\t\t\tAdditionalOptions=\"" << this->EscapeForXML(libflags)
+             << "\"\n";
       }
       fout << "\t\t\t\tOutputFile=\""
            << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";

+ 4 - 0
Source/cmMakefileTargetGenerator.cxx

@@ -815,6 +815,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
       // avoiding a trailing backslash in the argument.
       targetOutPathCompilePDB.back() = '/';
     }
+
+    std::string compilePdbOutputPath =
+      this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
+    cmSystemTools::MakeDirectory(compilePdbOutputPath);
   }
   cmRulePlaceholderExpander::RuleVariables vars;
   vars.CMTargetName = this->GeneratorTarget->GetName().c_str();

+ 131 - 0
Tests/RunCMake/PrecompileHeaders/PchReuseFromObjLib.cmake

@@ -0,0 +1,131 @@
+cmake_minimum_required(VERSION 3.18)
+
+project(PchReuseFromObjLib)
+
+set(CMAKE_PCH_WARN_INVALID OFF)
+
+if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
+  add_definitions(-DHAVE_PCH_SUPPORT)
+endif()
+
+######################################################################
+
+file(WRITE ${CMAKE_BINARY_DIR}/CONFIG/config.hxx "/*empty*/\n")
+
+file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
+void nothing()
+{
+}
+]=])
+
+file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
+#include <string.h>
+
+namespace std {
+  struct string
+  {
+    char storage[20];
+
+    string(const char* s) {
+      strcpy(storage, s);
+    }
+
+    const char* c_str() const {
+      return storage;
+    }
+  };
+}
+]=])
+
+add_library(pch-generator OBJECT ${CMAKE_BINARY_DIR}/pch.cxx)
+set_property(TARGET pch-generator PROPERTY POSITION_INDEPENDENT_CODE ON)
+target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
+
+target_include_directories(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
+
+######################################################################
+
+file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
+#include "message.hxx"
+
+#ifndef HAVE_PCH_SUPPORT
+  #include "string.hxx"
+#endif
+
+const char* message()
+{
+  static std::string greeting("hi there");
+  return greeting.c_str();
+}
+]=])
+
+file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
+#include "config.hxx"
+#ifdef WIN32_BUILD_SHARED
+  #ifdef BUILD_LIBRARY
+    #define MESSAGE_EXPORT __declspec(dllexport)
+  #else
+    #define MESSAGE_EXPORT __declspec(dllimport)
+  #endif
+#else
+  #define MESSAGE_EXPORT
+#endif
+
+MESSAGE_EXPORT const char* message();
+]=])
+
+######################################################################
+
+file(WRITE ${CMAKE_BINARY_DIR}/main.cxx [=[
+#include "message.hxx"
+#include <string.h>
+
+int main()
+{
+  return strcmp(message(), "hi there");
+}
+]=])
+
+######################################################################
+
+enable_testing()
+
+function(add_library_and_executable type)
+  add_library(message_${type} ${type} ${CMAKE_BINARY_DIR}/message.cxx)
+  target_precompile_headers(message_${type} REUSE_FROM pch-generator)
+
+  set_property(TARGET message_${type} PROPERTY POSITION_INDEPENDENT_CODE ON)
+  set_property(TARGET message_${type} PROPERTY DEFINE_SYMBOL "")
+
+  if (WIN32 AND type STREQUAL "SHARED")
+    file(WRITE ${CMAKE_BINARY_DIR}/SHARED/config.hxx [=[
+      #define BUILD_LIBRARY
+      #define WIN32_BUILD_SHARED
+    ]=])
+    target_include_directories(message_${type} PRIVATE ${CMAKE_BINARY_DIR}/SHARED)
+
+    # Workaround for VS2008, the compiler fails with
+    # c1xx : fatal error C1083: Cannot open source file: '_WINDLL': No such file or directory
+    file(WRITE ${CMAKE_BINARY_DIR}/_WINDLL "/*empty*/\n")
+  else()
+    target_include_directories(message_${type} PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
+  endif()
+
+  add_executable(main_${type} ${CMAKE_BINARY_DIR}/main.cxx)
+  target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR})
+
+  if (WIN32 AND type STREQUAL "SHARED")
+    file(WRITE ${CMAKE_BINARY_DIR}/main_SHARED/config.hxx "#define WIN32_BUILD_SHARED\n")
+    target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR}/main_SHARED)
+  else()
+    target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
+  endif()
+
+  target_link_libraries(main_${type} PRIVATE message_${type})
+
+  add_test(NAME main_${type} COMMAND main_${type})
+endfunction()
+
+foreach(type OBJECT STATIC SHARED)
+  add_library_and_executable(${type})
+endforeach()

+ 1 - 0
Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake

@@ -26,3 +26,4 @@ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
     run_cmake(PchInstantiateTemplates)
   endif()
 endif()
+run_test(PchReuseFromObjLib)