summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-09-11 11:51:12 +0800
committerGitHub <[email protected]>2025-09-11 11:51:12 +0800
commit9ac44c13a82a49abfd37e425b967efebbbb9ab7c (patch)
treea9de74e910024f38251387306d9b1853853bcf15
parente47954aadbb5dd06b9a09b31792de72cc01295a4 (diff)
parent2f16b3d37c421f975852fec05a69d35041677368 (diff)
Merge pull request #6785 from Arthapz/support-wdk-clang
feat(wdk rules) support clang and llvm for wdk rules
-rw-r--r--tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c2
-rw-r--r--tests/projects/windows/driver/umdf/skeleton/xmake.lua10
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/intrface.c5
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/msdsm.h2
-rw-r--r--tests/projects/windows/driver/wdm/msdsm/prototypes.h2
-rw-r--r--tests/projects/windows/driver/wdm/perfcounters/kcs.c3
-rw-r--r--xmake/rules/platform/windows/subsystem/xmake.lua2
-rw-r--r--xmake/rules/wdk/env/load.lua81
-rw-r--r--xmake/rules/wdk/load.lua101
-rw-r--r--xmake/rules/wdk/man/xmake.lua7
-rw-r--r--xmake/rules/wdk/xmake.lua4
11 files changed, 101 insertions, 118 deletions
diff --git a/tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c b/tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c
index 6ec41747e..640c4a338 100644
--- a/tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c
+++ b/tests/projects/windows/driver/kmdf/ioctl/exe/testapp.c
@@ -213,7 +213,7 @@ GetCoinstallerVersion(
VOID __cdecl
main(
- _In_ ULONG argc,
+ _In_ INT argc,
_In_reads_(argc) PCHAR argv[]
)
{
diff --git a/tests/projects/windows/driver/umdf/skeleton/xmake.lua b/tests/projects/windows/driver/umdf/skeleton/xmake.lua
index ee8ed00b5..547ad376b 100644
--- a/tests/projects/windows/driver/umdf/skeleton/xmake.lua
+++ b/tests/projects/windows/driver/umdf/skeleton/xmake.lua
@@ -8,6 +8,12 @@ target("UMDFSkeleton")
add_files("*.cpp", {rules = "wdk.tracewpp"})
add_files("*.rc", "*.inx")
set_values("wdk.umdf.sdkver", "1.9")
- add_shflags("/DEF:exports.def", {force = true})
- add_shflags("/ENTRY:_DllMainCRTStartup" .. (is_arch("x86") and "@12" or ""), {force = true})
+ add_files("exports.def")
+ on_config(function(target)
+ if target:has_tool("sh", "clang", "clangxx") then
+ target:add("shflags", "-Wl,/ENTRY:_DllMainCRTStartup" .. (is_arch("x86") and "@12" or ""), {force = true})
+ else
+ target:add("shflags", "/ENTRY:_DllMainCRTStartup" .. (is_arch("x86") and "@12" or ""), {force = true})
+ end
+ end)
diff --git a/tests/projects/windows/driver/wdm/msdsm/intrface.c b/tests/projects/windows/driver/wdm/msdsm/intrface.c
index 4a390c212..4266beba7 100644
--- a/tests/projects/windows/driver/wdm/msdsm/intrface.c
+++ b/tests/projects/windows/driver/wdm/msdsm/intrface.c
@@ -32,6 +32,7 @@ Environment:
#pragma warning (disable:4305)
+DSM_INIT_DATA gDsmInitData;
//
// Flag to indicate whether to NT_ASSERT or ignore a particular condition.
@@ -3430,7 +3431,7 @@ Return Value:
NTSTATUS
DsmRemovePath(
- _In_ IN PDSM_CONTEXT DsmContext,
+ _In_ IN PVOID _DsmContext,
_In_ IN PVOID PathId
)
/*++
@@ -3456,6 +3457,8 @@ Return Value:
PDSM_FAILOVER_GROUP failGroup;
KIRQL irql;
+ PDSM_CONTEXT DsmContext = (PDSM_CONTEXT)_DsmContext;
+
TracePrint((TRACE_LEVEL_VERBOSE,
TRACE_FLAG_PNP,
"DsmRemovePath (PathId %p): Entering function.\n",
diff --git a/tests/projects/windows/driver/wdm/msdsm/msdsm.h b/tests/projects/windows/driver/wdm/msdsm/msdsm.h
index 982ed7ffc..9962b0f80 100644
--- a/tests/projects/windows/driver/wdm/msdsm/msdsm.h
+++ b/tests/projects/windows/driver/wdm/msdsm/msdsm.h
@@ -115,7 +115,7 @@ Notes:
//
// Initialization data structure that needs to be filled in for MPIO
//
-DSM_INIT_DATA gDsmInitData;
+extern DSM_INIT_DATA gDsmInitData;
//
// Macro used to round of a number to the nearest 8 byte aligned one.
diff --git a/tests/projects/windows/driver/wdm/msdsm/prototypes.h b/tests/projects/windows/driver/wdm/msdsm/prototypes.h
index c72c22cb4..08eb5ba0d 100644
--- a/tests/projects/windows/driver/wdm/msdsm/prototypes.h
+++ b/tests/projects/windows/driver/wdm/msdsm/prototypes.h
@@ -206,7 +206,7 @@ DsmRemoveDevice(
NTSTATUS
DsmRemovePath(
- _In_ IN PDSM_CONTEXT DsmContext,
+ _In_ IN PVOID DsmContext,
_In_ IN PVOID PathId
);
diff --git a/tests/projects/windows/driver/wdm/perfcounters/kcs.c b/tests/projects/windows/driver/wdm/perfcounters/kcs.c
index 67ca0e328..610cb88e0 100644
--- a/tests/projects/windows/driver/wdm/perfcounters/kcs.c
+++ b/tests/projects/windows/driver/wdm/perfcounters/kcs.c
@@ -27,6 +27,9 @@ Environment:
#include "kcs.h"
#include "kcsCounters.h"
+#include <stdlib.h>
+#include <math.h>
+
#pragma code_seg("PAGE")
DRIVER_INITIALIZE DriverEntry;
diff --git a/xmake/rules/platform/windows/subsystem/xmake.lua b/xmake/rules/platform/windows/subsystem/xmake.lua
index 6ee96324a..2f580e4e1 100644
--- a/xmake/rules/platform/windows/subsystem/xmake.lua
+++ b/xmake/rules/platform/windows/subsystem/xmake.lua
@@ -39,7 +39,7 @@ rule("platform.windows.subsystem")
assert(valid, "Invalid subsystem " .. subsystem)
if target:has_tool("ld", "clang", "clangxx", "clang_cl") then
- target:add("ldflags", "-Wl,-subsystem:" .. subsystem, { force = true })
+ target:add("ldflags", "-Xlinker", "-subsystem:" .. subsystem, { force = true })
elseif target:has_tool("ld", "link", "lld-link") then
target:add("ldflags", "/SUBSYSTEM:" .. subsystem:upper(), { force = true })
elseif target:has_tool("ld", "gcc", "gxx") then
diff --git a/xmake/rules/wdk/env/load.lua b/xmake/rules/wdk/env/load.lua
index 3e9681e61..fa682c207 100644
--- a/xmake/rules/wdk/env/load.lua
+++ b/xmake/rules/wdk/env/load.lua
@@ -38,8 +38,7 @@ function _winver_libdir(winver)
return vervals[winver]
end
--- load for umdf environment
-function umdf(target)
+function _base(target, mode)
-- get wdk
local wdk = target:data("wdk")
@@ -48,7 +47,8 @@ function umdf(target)
local arch = config.arch()
-- add definitions
- local umdfver = wdk.umdfver:split('%.')
+ local ver = mode == "um" and wdk.umdfver or wdk.kmdfver
+ local ver_split = ver:split('%.')
if arch == "x64" then
target:add("defines", "_WIN64", "_AMD64_", "AMD64")
else
@@ -57,16 +57,27 @@ function umdf(target)
target:add("defines", "STD_CALL")
target:add("cxflags", "-Gz", {force = true})
end
- target:add("defines", "UMDF_VERSION_MAJOR=" .. umdfver[1], "UMDF_VERSION_MINOR=" .. umdfver[2], "UMDF_USING_NTSTATUS")
+
+ local prefix = mode == "um" and "UM" or "KM"
+ target:add("defines", prefix .. "DF_VERSION_MAJOR=" .. ver_split[1], prefix .. "DF_VERSION_MINOR=" .. ver_split[2], prefix .. "DF_USING_NTSTATUS")
target:add("defines", "WIN32_LEAN_AND_MEAN=1", "WINNT=1", "_WINDLL")
-- add include directories
- target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "um"))
- target:add("includedirs", path.join(wdk.includedir, "wdf", "umdf", wdk.umdfver))
+ target:add("sysincludedirs", path.join(wdk.includedir, wdk.sdkver, mode))
+ target:add("sysincludedirs", path.join(wdk.includedir, "wdf", mode .. "df", ver))
-- add link directories
- target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, "um", arch))
- target:add("linkdirs", path.join(wdk.libdir, "wdf", "umdf", arch, wdk.umdfver))
+ target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, mode, arch))
+ local p = path.join(wdk.libdir, "wdf", mode .. "df", arch, ver)
+ if os.isdir(p) then
+ target:add("linkdirs", p)
+ end
+end
+
+-- load for umdf environment
+function umdf(target)
+
+ _base(target, "um")
end
-- load for kmdf environment
@@ -80,69 +91,23 @@ function kmdf(target)
-- add definitions
local winver = target:values("wdk.env.winver") or config.get("wdk_winver")
- local kmdfver = wdk.kmdfver:split('%.')
- if arch == "x64" then
- target:add("defines", "_WIN64", "_AMD64_", "AMD64")
- else
- target:add("defines", "_X86_=1", "i386=1")
- target:add("defines", "DEPRECATE_DDK_FUNCTIONS=1", "MSC_NOOPT", "_ATL_NO_WIN_SUPPORT")
- target:add("defines", "STD_CALL")
- target:add("cxflags", "-Gz", {force = true})
- end
- target:add("defines", "KMDF_VERSION_MAJOR=" .. kmdfver[1], "KMDF_VERSION_MINOR=" .. kmdfver[2], "KMDF_USING_NTSTATUS")
- target:add("defines", "WIN32_LEAN_AND_MEAN=1", "WINNT=1", "_WINDLL")
+
+ _base(target, "km")
-- add include directories
- target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "km"))
if target:rule("wdk.driver") then
- target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "km", "crt"))
+ target:add("sysincludedirs", path.join(wdk.includedir, wdk.sdkver, "km", "crt"))
end
- target:add("includedirs", path.join(wdk.includedir, "wdf", "kmdf", wdk.kmdfver))
-- add link directories
local libdirver = _winver_libdir(winver)
if libdirver then
target:add("linkdirs", path.join(wdk.libdir, libdirver, "km", arch))
end
- target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, "km", arch))
- target:add("linkdirs", path.join(wdk.libdir, "wdf", "kmdf", arch, wdk.kmdfver))
end
-- load for wdm environment
function wdm(target)
- -- get wdk
- local wdk = target:data("wdk")
-
- -- get arch
- local arch = config.arch()
-
- -- add definitions
- local winver = target:values("wdk.env.winver") or config.get("wdk_winver")
- local kmdfver = wdk.kmdfver:split('%.')
- if arch == "x64" then
- target:add("defines", "_WIN64", "_AMD64_", "AMD64")
- else
- target:add("defines", "_X86_=1", "i386=1")
- target:add("defines", "DEPRECATE_DDK_FUNCTIONS=1", "MSC_NOOPT", "_ATL_NO_WIN_SUPPORT")
- target:add("defines", "STD_CALL")
- target:add("cxflags", "-Gz", {force = true})
- end
- target:add("defines", "KMDF_VERSION_MAJOR=" .. kmdfver[1], "KMDF_VERSION_MINOR=" .. kmdfver[2], "KMDF_USING_NTSTATUS")
- target:add("defines", "WIN32_LEAN_AND_MEAN=1", "WINNT=1", "_WINDLL")
-
- -- add include directories
- target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "km"))
- if target:rule("wdk.driver") then
- target:add("includedirs", path.join(wdk.includedir, wdk.sdkver, "km", "crt"))
- end
- target:add("includedirs", path.join(wdk.includedir, "wdf", "kmdf", wdk.kmdfver))
-
- -- add link directories
- local libdirver = _winver_libdir(winver)
- if libdirver then
- target:add("linkdirs", path.join(wdk.libdir, libdirver, "km", arch))
- end
- target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, "km", arch))
- target:add("linkdirs", path.join(wdk.libdir, "wdf", "kmdf", arch, wdk.kmdfver))
+ kmdf(target)
end
diff --git a/xmake/rules/wdk/load.lua b/xmake/rules/wdk/load.lua
index 9886d45e0..637ea9f80 100644
--- a/xmake/rules/wdk/load.lua
+++ b/xmake/rules/wdk/load.lua
@@ -20,8 +20,29 @@
-- imports
import("core.project.config")
+import("core.base.semver")
import("os.winver", {alias = "os_winver"})
+function _add_linkflags(target, t, ...)
+ local args = table.pack(...)
+ if target:has_tool("ld", "clang", "clangxx") then
+ for i, flag in ipairs(args) do
+ if type(flag) == "string" then
+ args[i] = "-Wl," .. flag
+ end
+ end
+ end
+ target:add(t, table.unpack(args))
+end
+
+function _add_ldflags(target, ...)
+ _add_linkflags(target, "ldflags", ...)
+end
+
+function _add_shflags(target, ...)
+ _add_linkflags(target, "shflags", ...)
+end
+
-- load for umdf driver
function driver_umdf(target)
@@ -30,10 +51,10 @@ function driver_umdf(target)
-- add links
target:add("links", "ntdll", "OneCoreUAP", "mincore", "ucrt")
- target:add("shflags", "-NODEFAULTLIB:kernel32.lib", "-NODEFAULTLIB:user32.lib", "-NODEFAULTLIB:libucrt.lib", {force = true})
+
+ _add_shflags(target, "-NODEFAULTLIB:kernel32.lib", "-NODEFAULTLIB:user32.lib", "-NODEFAULTLIB:libucrt.lib", {force = true})
-- add subsystem
- local winver = target:values("wdk.env.winver") or config.get("wdk_winver")
if not target:values("windows.subsystem") then
target:values_set("windows.subsystem", "windows," .. os_winver.subsystem(winver))
end
@@ -47,13 +68,15 @@ function driver_umdf(target)
break
end
end
- if not entry then
+
+ -- get wdk
+ local wdk = target:data("wdk")
+ if not entry and semver.compare(wdk.umdfver, "2.0") >= 0 then
target:add("links", "WdfDriverStubUm")
end
end
--- load for kmdf driver
-function driver_kmdf(target)
+function _kernel_driver_base(target, default_entrypoint)
-- set kind
target:set("kind", "binary")
@@ -68,12 +91,17 @@ function driver_kmdf(target)
else
target:add("links", "BufferOverflowK")
end
- target:add("links", "ntoskrnl", "hal", "wmilib", "WdfLdr", "ntstrsafe", "wdmsec")
-- compile as kernel driver
- target:add("cxflags", "-kernel", {force = true})
- target:add("ldflags", "-kernel", "-driver", {force = true})
- target:add("ldflags", "-nodefaultlib", {force = true})
+ if not target:has_tool("cc", "clang", "clangxx") then
+ target:add("cxflags", "-kernel", {force = true})
+ else
+ -- emulate kernel mode https://learn.microsoft.com/en-us/cpp/build/reference/kernel-create-kernel-mode-binary?view=msvc-170
+ target:add("cxxflags", "-fno-exceptions", "-fno-rtti")
+ target:add("defines", "_KERNEL_MODE=1")
+ end
+
+ _add_ldflags(target, "-kernel", "-driver", "-nodefaultlib", {force = true})
-- add subsystem
if not target:values("windows.subsystem") then
@@ -81,63 +109,34 @@ function driver_kmdf(target)
end
-- set default driver entry if does not exist
- local entry = false
+ local has_entry = false
for _, ldflag in ipairs(target:get("ldflags")) do
if type(ldflag) == "string" then
ldflag = ldflag:lower()
if ldflag:find("[/%-]entry:") then
- entry = true
+ has_entry = true
break
end
end
end
- if not entry then
- target:add("links", "WdfDriverEntry")
- target:add("ldflags", "-entry:FxDriverEntry" .. (is_arch("x86") and "@8" or ""), {force = true})
+ if not has_entry then
+ local arch = (target:is_arch("x86") and "@8" or "") target:add("links", "WdfDriverEntry")
+ _add_ldflags(target, "-entry:" .. default_entrypoint .. arch, {force = true})
end
end
--- load for wdm driver
-function driver_wdm(target)
+-- load for kmdf driver
+function driver_kmdf(target)
- -- set kind
- target:set("kind", "binary")
+ target:add("links", "ntoskrnl", "hal", "wmilib", "WdfLdr", "ntstrsafe", "wdmsec")
- -- set filename: xxx.sys
- target:set("filename", target:basename() .. ".sys")
+ _kernel_driver_base(target, "FxDriverEntry")
+end
- -- add links
- local winver = target:values("wdk.env.winver") or config.get("wdk_winver")
- if winver and os_winver.version(winver) >= os_winver.version("win8") then
- target:add("links", "BufferOverflowFastFailK")
- else
- target:add("links", "BufferOverflowK")
- end
+-- load for wdm driver
+function driver_wdm(target)
target:add("links", "ntoskrnl", "hal", "wmilib", "ntstrsafe")
- -- compile as kernel driver
- target:add("cxflags", "-kernel", {force = true})
- target:add("ldflags", "-kernel", "-driver", {force = true})
- target:add("ldflags", "-nodefaultlib", {force = true})
-
- -- add subsystem
- if not target:values("windows.subsystem") then
- target:values_set("windows.subsystem", "native," .. os_winver.subsystem(winver))
- end
-
- -- set default driver entry if does not exist
- local entry = false
- for _, ldflag in ipairs(target:get("ldflags")) do
- if type(ldflag) == "string" then
- ldflag = ldflag:lower()
- if ldflag:find("[/%-]entry:") then
- entry = true
- break
- end
- end
- end
- if not entry then
- target:add("ldflags", "-entry:GsDriverEntry" .. (is_arch("x86") and "@8" or ""), {force = true})
- end
+ _kernel_driver_base(target, "GsDriverEntry")
end
diff --git a/xmake/rules/wdk/man/xmake.lua b/xmake/rules/wdk/man/xmake.lua
index 53063cc49..ab817ae6e 100644
--- a/xmake/rules/wdk/man/xmake.lua
+++ b/xmake/rules/wdk/man/xmake.lua
@@ -124,6 +124,13 @@ rule("wdk.man")
end
os.vrunv(ctrpp, args)
+ if target:has_tool("cxx", "clang", "clangxx") then
+ if resourcefile and os.isfile(resourcefile) then
+ local content = io.readfile(resourcefile)
+ io.writefile(resourcefile, content, {encoding = "utf8"})
+ end
+ end
+
-- update files and values to the dependent file
dependinfo.files = {sourcefile}
dependinfo.values = args
diff --git a/xmake/rules/wdk/xmake.lua b/xmake/rules/wdk/xmake.lua
index 114e0e675..d94b51fce 100644
--- a/xmake/rules/wdk/xmake.lua
+++ b/xmake/rules/wdk/xmake.lua
@@ -24,8 +24,8 @@ rule("wdk.driver")
-- add rules
add_deps("wdk.inf", "wdk.man", "wdk.mc", "wdk.mof", "wdk.tracewpp", "wdk.sign", "wdk.package.cab")
- -- after load
- after_load(function (target)
+ -- on config
+ on_config(function (target)
-- load environment
if target:rule("wdk.env.umdf") then