Преглед изворни кода

Merge topic 'windows-kernel-mode-driver'

b01f5eb079 Windows: Add experimental WindowsKernelModeDriver platform
d84681d8f0 try_compile(): Pass down CMAKE_EXPERIMENTAL_* feature flags
1ca82e7a04 cmake_language(): Add undocumented GET_EXPERIMENTAL_FEATURE_ENABLED mode
051cea7b7e cmExperimental: Expose feature data API

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !8634
Brad King пре 2 година
родитељ
комит
ee6335f75f

+ 22 - 2
Modules/Platform/Windows-MSVC.cmake

@@ -28,6 +28,8 @@ endif()
 
 if(CMAKE_SYSTEM_NAME STREQUAL "WindowsCE")
   set(_PLATFORM_LINK_FLAGS " /subsystem:windowsce")
+elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+  set(_PLATFORM_LINK_FLAGS " -subsystem:native -kernel -MANIFEST:NO")
 else()
   set(_PLATFORM_LINK_FLAGS "")
 endif()
@@ -223,6 +225,18 @@ elseif(WINDOWS_PHONE OR WINDOWS_STORE)
   else()
     set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib")
   endif()
+elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+  set(CMAKE_C_STANDARD_LIBRARIES_INIT "")
+  set(_FLAGS_C   " -kernel")
+  set(_FLAGS_CXX " -kernel")
+  foreach(t EXE SHARED MODULE)
+    string(APPEND CMAKE_${t}_LINKER_FLAGS_INIT " -NODEFAULTLIB")
+  endforeach()
+  if((_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "x64") OR (_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "x64"))
+    set(_PLATFORM_DEFINES "${_PLATFORM_DEFINES} -D_AMD64_ -DAMD64")
+  elseif((_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64") OR (_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM64"))
+    set(_PLATFORM_DEFINES "${_PLATFORM_DEFINES} -D_ARM64_ -DARM64")
+  endif()
 else()
   set(_PLATFORM_DEFINES "/DWIN32")
   if((_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64EC") OR (_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM64EC"))
@@ -294,7 +308,7 @@ endif()
 # add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype
 # on versions that support it
 set( MSVC_INCREMENTAL_YES_FLAG "")
-if(NOT WINDOWS_PHONE AND NOT WINDOWS_STORE)
+if(NOT WINDOWS_PHONE AND NOT WINDOWS_STORE AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
   if(NOT MSVC_INCREMENTAL_DEFAULT)
     set( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:YES")
   else()
@@ -353,8 +367,14 @@ macro(__windows_compiler_msvc lang)
     set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
     set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
   endif()
+  if(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+    set(_DLL_DRIVER "-driver")
+  else()
+    set(_DLL_DRIVER "/dll")
+  endif()
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
-    "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+    "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> ${_DLL_DRIVER} /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+  unset(_DLL_DRIVER)
 
   set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY})
   set(CMAKE_${lang}_CREATE_STATIC_LIBRARY  "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")

+ 5 - 1
Modules/Platform/Windows.cmake

@@ -1,7 +1,11 @@
 set(CMAKE_STATIC_LIBRARY_PREFIX "")
 set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
 set(CMAKE_SHARED_LIBRARY_PREFIX "")          # lib
-set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")          # .so
+if(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+  set(CMAKE_SHARED_LIBRARY_SUFFIX ".sys")          # .so
+else()
+  set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")          # .so
+endif()
 set(CMAKE_IMPORT_LIBRARY_PREFIX "")
 set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
 set(CMAKE_EXECUTABLE_SUFFIX ".exe")          # .exe

+ 11 - 0
Modules/Platform/WindowsKernelModeDriver-Initialize.cmake

@@ -0,0 +1,11 @@
+# undocumented, do not use outside of CMake
+cmake_language(GET_EXPERIMENTAL_FEATURE_ENABLED "WindowsKernelModeDriver" _cmake_windows_kernel_mode_driver_enabled)
+if(NOT _cmake_windows_kernel_mode_driver_enabled)
+  message(FATAL_ERROR "Windows kernel-mode driver experimental support is not enabled.")
+endif()
+
+if(CMAKE_GENERATOR MATCHES "Visual Studio")
+  message(FATAL_ERROR "Visual Studio generators do not yet support CMAKE_SYSTEM_NAME=WindowsKernelModeDriver.")
+endif()
+
+set(_CMAKE_FEATURE_DETECTION_TARGET_TYPE STATIC_LIBRARY)

+ 1 - 0
Modules/Platform/WindowsKernelModeDriver-MSVC-C.cmake

@@ -0,0 +1 @@
+include(Platform/Windows-MSVC-C)

+ 1 - 0
Modules/Platform/WindowsKernelModeDriver-MSVC-CXX.cmake

@@ -0,0 +1 @@
+include(Platform/Windows-MSVC-CXX)

+ 1 - 0
Modules/Platform/WindowsKernelModeDriver.cmake

@@ -0,0 +1 @@
+include(Platform/Windows)

+ 46 - 0
Source/cmCMakeLanguageCommand.cxx

@@ -17,6 +17,7 @@
 #include "cmArgumentParserTypes.h"
 #include "cmDependencyProvider.h"
 #include "cmExecutionStatus.h"
+#include "cmExperimental.h"
 #include "cmGlobalGenerator.h"
 #include "cmListFileCache.h"
 #include "cmMakefile.h"
@@ -328,6 +329,46 @@ bool cmCMakeLanguageCommandGET_MESSAGE_LOG_LEVEL(
   makefile.AddDefinition(outputVariable, outputValue);
   return true;
 }
+
+bool cmCMakeLanguageCommandGET_EXPERIMENTAL_FEATURE_ENABLED(
+  std::vector<cmListFileArgument> const& args, cmExecutionStatus& status)
+{
+  cmMakefile& makefile = status.GetMakefile();
+  std::vector<std::string> expandedArgs;
+  makefile.ExpandArguments(args, expandedArgs);
+
+  if (expandedArgs.size() != 3) {
+    return FatalError(status,
+                      "sub-command GET_EXPERIMENTAL_FEATURE_ENABLED expects "
+                      "exactly two arguments");
+  }
+
+  auto const& featureName = expandedArgs[1];
+  auto const& variableName = expandedArgs[2];
+
+  auto feature = cmExperimental::Feature::Sentinel;
+  for (std::size_t i = 0;
+       i < static_cast<std::size_t>(cmExperimental::Feature::Sentinel); i++) {
+    if (cmExperimental::DataForFeature(static_cast<cmExperimental::Feature>(i))
+          .Name == featureName) {
+      feature = static_cast<cmExperimental::Feature>(i);
+      break;
+    }
+  }
+  if (feature == cmExperimental::Feature::Sentinel) {
+    return FatalError(status,
+                      cmStrCat("Experimental feature name \"", featureName,
+                               "\" does not exist."));
+  }
+
+  if (cmExperimental::HasSupportEnabled(makefile, feature)) {
+    makefile.AddDefinition(variableName, "TRUE");
+  } else {
+    makefile.AddDefinition(variableName, "FALSE");
+  }
+
+  return true;
+}
 }
 
 bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
@@ -480,5 +521,10 @@ bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
     return cmCMakeLanguageCommandGET_MESSAGE_LOG_LEVEL(args, status);
   }
 
+  if (expArgs[expArg] == "GET_EXPERIMENTAL_FEATURE_ENABLED") {
+    return cmCMakeLanguageCommandGET_EXPERIMENTAL_FEATURE_ENABLED(args,
+                                                                  status);
+  }
+
   return FatalError(status, "called with unknown meta-operation");
 }

+ 12 - 0
Source/cmCoreTryCompile.cxx

@@ -18,6 +18,7 @@
 
 #include "cmArgumentParser.h"
 #include "cmConfigureLog.h"
+#include "cmExperimental.h"
 #include "cmExportTryCompileFileGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmList.h"
@@ -1068,6 +1069,17 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
       cmakeVariables.emplace("CMAKE_OSX_ARCHITECTURES", *tcArchs);
     }
 
+    // Pass down CMAKE_EXPERIMENTAL_* feature flags
+    for (std::size_t i = 0;
+         i < static_cast<std::size_t>(cmExperimental::Feature::Sentinel);
+         i++) {
+      auto const& data = cmExperimental::DataForFeature(
+        static_cast<cmExperimental::Feature>(i));
+      if (data.ForwardThroughTryCompile) {
+        vars.insert(data.Variable);
+      }
+    }
+
     for (std::string const& var : vars) {
       if (cmValue val = this->Makefile->GetDefinition(var)) {
         std::string flag = "-D" + var + "=" + *val;

+ 16 - 11
Source/cmExperimental.cxx

@@ -18,36 +18,41 @@ namespace {
  * Search for other instances to keep the documentation and test suite
  * up-to-date.
  */
-
-struct FeatureData
-{
-  std::string const Uuid;
-  std::string const Variable;
-  std::string const Description;
-  bool Warned;
-} LookupTable[] = {
+cmExperimental::FeatureData LookupTable[] = {
   // CxxModuleCMakeApi
-  { "bf70d4b0-9fb7-465c-9803-34014e70d112",
+  { "CxxModuleCMakeApi", "bf70d4b0-9fb7-465c-9803-34014e70d112",
     "CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API",
     "CMake's C++ module support is experimental. It is meant only for "
     "experimentation and feedback to CMake developers.",
+    false, // https://gitlab.kitware.com/cmake/cmake/-/issues/25097
     false },
+  // WindowsKernelModeDriver
+  { "WindowsKernelModeDriver", "5c2d848d-4efa-4529-a768-efd57171bf68",
+    "CMAKE_EXPERIMENTAL_WINDOWS_KERNEL_MODE_DRIVER",
+    "CMake's Windows kernel-mode driver support is experimental. It is meant "
+    "only for experimentation and feedback to CMake developers.",
+    true, false },
 };
 static_assert(sizeof(LookupTable) / sizeof(LookupTable[0]) ==
                 static_cast<size_t>(cmExperimental::Feature::Sentinel),
               "Experimental feature lookup table mismatch");
 
-FeatureData& DataForFeature(cmExperimental::Feature f)
+cmExperimental::FeatureData& DataForFeature(cmExperimental::Feature f)
 {
   assert(f != cmExperimental::Feature::Sentinel);
   return LookupTable[static_cast<size_t>(f)];
 }
 }
 
+const cmExperimental::FeatureData& cmExperimental::DataForFeature(Feature f)
+{
+  return ::DataForFeature(f);
+}
+
 bool cmExperimental::HasSupportEnabled(cmMakefile const& mf, Feature f)
 {
   bool enabled = false;
-  auto& data = DataForFeature(f);
+  auto& data = ::DataForFeature(f);
 
   auto value = mf.GetDefinition(data.Variable);
   if (value == data.Uuid) {

+ 14 - 0
Source/cmExperimental.h

@@ -5,6 +5,8 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <string>
+
 class cmMakefile;
 
 class cmExperimental
@@ -13,9 +15,21 @@ public:
   enum class Feature
   {
     CxxModuleCMakeApi,
+    WindowsKernelModeDriver,
 
     Sentinel,
   };
 
+  struct FeatureData
+  {
+    std::string const Name;
+    std::string const Uuid;
+    std::string const Variable;
+    std::string const Description;
+    bool const ForwardThroughTryCompile;
+    bool Warned;
+  };
+
+  static const FeatureData& DataForFeature(Feature f);
   static bool HasSupportEnabled(cmMakefile const& mf, Feature f);
 };