diff options
| author | Arthur LAURENT <[email protected]> | 2025-09-09 21:38:20 +0200 |
|---|---|---|
| committer | Arthur LAURENT <[email protected]> | 2025-09-09 21:38:20 +0200 |
| commit | 0ca151ca12093530d8770929a5e236da55d7693c (patch) | |
| tree | 8599fb80b24f30d9f8c2b35ed24d1a508192c2e6 | |
| parent | c6bccc83599b6b48a22ee34be70b9a84cdbb70ce (diff) | |
feat(wdk rules) support clang / llvm toolchains
| -rw-r--r-- | xmake/rules/wdk/env/load.lua | 5 | ||||
| -rw-r--r-- | xmake/rules/wdk/load.lua | 101 | ||||
| -rw-r--r-- | xmake/rules/wdk/man/xmake.lua | 7 | ||||
| -rw-r--r-- | xmake/rules/wdk/xmake.lua | 4 |
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 |
