summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur LAURENT <[email protected]>2025-09-09 21:38:20 +0200
committerArthur LAURENT <[email protected]>2025-09-09 21:38:20 +0200
commit0ca151ca12093530d8770929a5e236da55d7693c (patch)
tree8599fb80b24f30d9f8c2b35ed24d1a508192c2e6
parentc6bccc83599b6b48a22ee34be70b9a84cdbb70ce (diff)
feat(wdk rules) support clang / llvm toolchains
-rw-r--r--xmake/rules/wdk/env/load.lua5
-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
4 files changed, 63 insertions, 54 deletions
diff --git a/xmake/rules/wdk/env/load.lua b/xmake/rules/wdk/env/load.lua
index 962eeb616..fa682c207 100644
--- a/xmake/rules/wdk/env/load.lua
+++ b/xmake/rules/wdk/env/load.lua
@@ -68,7 +68,10 @@ function _base(target, mode)
-- add link directories
target:add("linkdirs", path.join(wdk.libdir, wdk.sdkver, mode, arch))
- target:add("linkdirs", path.join(wdk.libdir, "wdf", mode .. "df", arch, ver))
+ 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
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