summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-04-22 21:44:50 +0800
committerGitHub <[email protected]>2025-04-22 21:44:50 +0800
commitaeaeda4045e99ac49e225485ba269ff8541d9b03 (patch)
tree5c3024e39b6b286cedaf92b0fc9176ea819d006c
parent50def2df2bd6099720c7db2480004f29c7bc7e74 (diff)
parent700b5497b88aecdfc604ef866f666d13f7d6c0b5 (diff)
Merge pull request #6301 from lakor64/dev
Improve MIDL support
-rw-r--r--tests/projects/idl/test_norpc/src/lockowner.idl28
-rw-r--r--tests/projects/idl/test_norpc/src/test_iid.c8
-rw-r--r--tests/projects/idl/test_norpc/xmake.lua7
-rw-r--r--tests/projects/idl/test_norpc_proxy/src/lockowner.idl28
-rw-r--r--tests/projects/idl/test_norpc_proxy/src/test_iid.c8
-rw-r--r--tests/projects/idl/test_norpc_proxy/xmake.lua7
-rw-r--r--tests/projects/idl/test_rpc/src/example.idl13
-rw-r--r--tests/projects/idl/test_rpc/src/test_iid.c18
-rw-r--r--tests/projects/idl/test_rpc/xmake.lua7
-rw-r--r--tests/projects/idl/test_rpc_noserver/src/example.idl13
-rw-r--r--tests/projects/idl/test_rpc_noserver/src/test_iid.c17
-rw-r--r--tests/projects/idl/test_rpc_noserver/xmake.lua7
-rw-r--r--xmake/rules/platform/windows/idl/idl.lua190
-rw-r--r--xmake/rules/platform/windows/idl/xmake.lua48
14 files changed, 358 insertions, 41 deletions
diff --git a/tests/projects/idl/test_norpc/src/lockowner.idl b/tests/projects/idl/test_norpc/src/lockowner.idl
new file mode 100644
index 000000000..49d314ca2
--- /dev/null
+++ b/tests/projects/idl/test_norpc/src/lockowner.idl
@@ -0,0 +1,28 @@
+/*
+ * PROJECT: SupernovaX SDK
+ * LICENSE: MIT (https://spdx.org/licenses/MIT)
+ * PURPOSE: Lock owner COM interfaces
+ * COPYRIGHT: Copyright 2023 Christian Rendina <[email protected]>
+ */
+import "oaidl.idl";
+import "ocidl.idl";
+
+[
+ object,
+ local,
+ uuid(9b7e4a00-342c-4106-a19f-4f2704f689f0)
+]
+interface ILockOwner : IUnknown
+{
+ void LOEnter(
+ void
+ );
+
+ void LOLeave(
+ void
+ );
+
+ BOOL LOTryEnter(
+ void
+ );
+};
diff --git a/tests/projects/idl/test_norpc/src/test_iid.c b/tests/projects/idl/test_norpc/src/test_iid.c
new file mode 100644
index 000000000..79b344b9a
--- /dev/null
+++ b/tests/projects/idl/test_norpc/src/test_iid.c
@@ -0,0 +1,8 @@
+#include <lockowner.h>
+#include <stdio.h>
+
+int main(int argc, char** argv) {
+ IID g = IID_ILockOwner;
+ printf("GUID: %x-%x-%x-%llx", g.Data1, g.Data2, g.Data3, *(unsigned long long*)g.Data4);
+ return 0;
+}
diff --git a/tests/projects/idl/test_norpc/xmake.lua b/tests/projects/idl/test_norpc/xmake.lua
new file mode 100644
index 000000000..d1596e3d5
--- /dev/null
+++ b/tests/projects/idl/test_norpc/xmake.lua
@@ -0,0 +1,7 @@
+add_rules("mode.debug", "mode.release")
+
+target("idltest_norpc")
+ set_kind("binary")
+ add_files("src/*.idl", { proxy = false })
+ add_files("src/*.c")
+ add_syslinks("Rpcrt4")
diff --git a/tests/projects/idl/test_norpc_proxy/src/lockowner.idl b/tests/projects/idl/test_norpc_proxy/src/lockowner.idl
new file mode 100644
index 000000000..49d314ca2
--- /dev/null
+++ b/tests/projects/idl/test_norpc_proxy/src/lockowner.idl
@@ -0,0 +1,28 @@
+/*
+ * PROJECT: SupernovaX SDK
+ * LICENSE: MIT (https://spdx.org/licenses/MIT)
+ * PURPOSE: Lock owner COM interfaces
+ * COPYRIGHT: Copyright 2023 Christian Rendina <[email protected]>
+ */
+import "oaidl.idl";
+import "ocidl.idl";
+
+[
+ object,
+ local,
+ uuid(9b7e4a00-342c-4106-a19f-4f2704f689f0)
+]
+interface ILockOwner : IUnknown
+{
+ void LOEnter(
+ void
+ );
+
+ void LOLeave(
+ void
+ );
+
+ BOOL LOTryEnter(
+ void
+ );
+};
diff --git a/tests/projects/idl/test_norpc_proxy/src/test_iid.c b/tests/projects/idl/test_norpc_proxy/src/test_iid.c
new file mode 100644
index 000000000..79b344b9a
--- /dev/null
+++ b/tests/projects/idl/test_norpc_proxy/src/test_iid.c
@@ -0,0 +1,8 @@
+#include <lockowner.h>
+#include <stdio.h>
+
+int main(int argc, char** argv) {
+ IID g = IID_ILockOwner;
+ printf("GUID: %x-%x-%x-%llx", g.Data1, g.Data2, g.Data3, *(unsigned long long*)g.Data4);
+ return 0;
+}
diff --git a/tests/projects/idl/test_norpc_proxy/xmake.lua b/tests/projects/idl/test_norpc_proxy/xmake.lua
new file mode 100644
index 000000000..f4255cea5
--- /dev/null
+++ b/tests/projects/idl/test_norpc_proxy/xmake.lua
@@ -0,0 +1,7 @@
+add_rules("mode.debug", "mode.release")
+
+target("idltest_norpc")
+ set_kind("binary")
+ add_files("src/*.idl")
+ add_files("src/*.c")
+ add_syslinks("Rpcrt4")
diff --git a/tests/projects/idl/test_rpc/src/example.idl b/tests/projects/idl/test_rpc/src/example.idl
new file mode 100644
index 000000000..1eb750a97
--- /dev/null
+++ b/tests/projects/idl/test_rpc/src/example.idl
@@ -0,0 +1,13 @@
+[
+ uuid(ba209999-0c6c-11d2-97cf-00c04f8eea45),
+ version(1.0)
+]
+interface MyInterface
+{
+ const unsigned short INT_ARRAY_LEN = 100;
+
+ void MyRemoteProc(
+ [in] int param1,
+ [out] int outArray[INT_ARRAY_LEN]
+ );
+}
diff --git a/tests/projects/idl/test_rpc/src/test_iid.c b/tests/projects/idl/test_rpc/src/test_iid.c
new file mode 100644
index 000000000..56e1e6e47
--- /dev/null
+++ b/tests/projects/idl/test_rpc/src/test_iid.c
@@ -0,0 +1,18 @@
+#include <Windows.h>
+#include <example.h>
+#include <stdio.h>
+
+int main(int argc, char** argv) {
+ MyInterface_v1_0_c_ifspec = (void*)1;
+ MyInterface_v1_0_s_ifspec = (void*)1;
+ printf("set ok\n");
+ return 0;
+}
+
+void __RPC_FAR * __RPC_API midl_user_allocate(size_t cBytes) {
+ return(malloc(cBytes));
+}
+
+void __RPC_API midl_user_free(void __RPC_FAR * p) {
+ free(p);
+}
diff --git a/tests/projects/idl/test_rpc/xmake.lua b/tests/projects/idl/test_rpc/xmake.lua
new file mode 100644
index 000000000..3eba457d6
--- /dev/null
+++ b/tests/projects/idl/test_rpc/xmake.lua
@@ -0,0 +1,7 @@
+add_rules("mode.debug", "mode.release")
+
+target("idltest_rpc")
+ set_kind("binary")
+ add_files("src/*.idl" )
+ add_files("src/*.c")
+ add_syslinks("Rpcrt4")
diff --git a/tests/projects/idl/test_rpc_noserver/src/example.idl b/tests/projects/idl/test_rpc_noserver/src/example.idl
new file mode 100644
index 000000000..1eb750a97
--- /dev/null
+++ b/tests/projects/idl/test_rpc_noserver/src/example.idl
@@ -0,0 +1,13 @@
+[
+ uuid(ba209999-0c6c-11d2-97cf-00c04f8eea45),
+ version(1.0)
+]
+interface MyInterface
+{
+ const unsigned short INT_ARRAY_LEN = 100;
+
+ void MyRemoteProc(
+ [in] int param1,
+ [out] int outArray[INT_ARRAY_LEN]
+ );
+}
diff --git a/tests/projects/idl/test_rpc_noserver/src/test_iid.c b/tests/projects/idl/test_rpc_noserver/src/test_iid.c
new file mode 100644
index 000000000..041033894
--- /dev/null
+++ b/tests/projects/idl/test_rpc_noserver/src/test_iid.c
@@ -0,0 +1,17 @@
+#include <Windows.h>
+#include <example.h>
+#include <stdio.h>
+
+int main(int argc, char** argv) {
+ MyInterface_v1_0_c_ifspec = (void*)1;
+ printf("call ok\n");
+ return 0;
+}
+
+void __RPC_FAR * __RPC_API midl_user_allocate(size_t cBytes) {
+ return(malloc(cBytes));
+}
+
+void __RPC_API midl_user_free(void __RPC_FAR * p) {
+ free(p);
+}
diff --git a/tests/projects/idl/test_rpc_noserver/xmake.lua b/tests/projects/idl/test_rpc_noserver/xmake.lua
new file mode 100644
index 000000000..c44a6433b
--- /dev/null
+++ b/tests/projects/idl/test_rpc_noserver/xmake.lua
@@ -0,0 +1,7 @@
+add_rules("mode.debug", "mode.release")
+
+target("idltest_rpc_noserver")
+ set_kind("binary")
+ add_files("src/*.idl", { server = false } )
+ add_files("src/*.c")
+ add_syslinks("Rpcrt4")
diff --git a/xmake/rules/platform/windows/idl/idl.lua b/xmake/rules/platform/windows/idl/idl.lua
new file mode 100644
index 000000000..3f18380cf
--- /dev/null
+++ b/xmake/rules/platform/windows/idl/idl.lua
@@ -0,0 +1,190 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file idl.lua
+--
+
+-- imports
+import("lib.detect.find_tool")
+import("core.project.depend")
+import("utils.progress")
+import("private.action.build.object", {alias = "build_objectfiles"})
+
+function generate_single(target, sourcefile, opt)
+ local msvc = target:toolchain("msvc") or target:toolchain("clang-cl") or target:toolchain("clang")
+ local midl = assert(find_tool("midl", {envs = msvc:runenvs(), toolchain = msvc}), "midl not found!")
+
+ local name = path.basename(sourcefile)
+ local fileconfig = target:fileconfig(sourcefile)
+ local autogendir = path.join(target:autogendir(), "platform/windows/idl")
+
+ local enable_server = true
+ local enable_client = true
+ local defs = table.wrap(target:get("defines") or {})
+ local incs = table.wrap(target:get("includedirs") or {})
+ local undefs = table.wrap(target:get("undefines") or {})
+
+ if fileconfig then
+ if fileconfig.server then
+ enable_server = fileconfig.server
+ end
+ if fileconfig.client then
+ enable_client = fileconfig.client
+ end
+ if fileconfig.includedirs then
+ table.join2(incs, fileconfig.includedirs)
+ end
+ if fileconfig.defines then
+ table.join2(defs, fileconfig.defines)
+ end
+ if fileconfig.undefines then
+ table.join2(undefs, fileconfig.undefines)
+ end
+ end
+
+ local flags = {"/nologo"}
+ table.join2(flags, table.wrap(target:values("idl.flags")))
+
+ -- specify warn levels
+ local warns = target:get("warnings")
+ if warns == "none" then
+ table.insert(flags, "/W0")
+ table.insert(flags, "/no_warn")
+ elseif warns == "less" then
+ table.insert(flags, "/W1")
+ elseif warns == "more" then
+ table.insert(flags, "/W2")
+ elseif warns == "extra" then
+ table.insert(flags, "/W3")
+ elseif warns == "error" then
+ table.insert(flags, "/WX")
+ table.insert(flags, "/W4")
+ end
+
+ -- add include dirs, defines and undefines from compiler flags
+ for _, inc in ipairs(incs) do
+ table.insert(flags, "/I")
+ table.insert(flags, path(inc))
+ end
+
+ for _, def in ipairs(defs) do
+ table.insert(flags, "/D")
+ table.insert(flags, def)
+ end
+
+ for _, undef in ipairs(undefs) do
+ table.insert(flags, "/U")
+ table.insert(flags, undef)
+ end
+
+ table.join2(flags, {
+ "/out", path(autogendir),
+ "/header", name .. ".h",
+ "/iid", name .. "_i.c",
+ "/proxy", name .. "_p.c",
+ "/tlb", name .. ".tlb",
+ "/cstub", name .. "_c.c",
+ "/sstub", name .. "_s.c",
+ "/server", (enable_server and "stub" or "none"),
+ "/client", (enable_client and "stub" or "none"),
+ path(sourcefile)
+ })
+
+ local dependfile = path.join(autogendir, path.basename(sourcefile) .. ".idl.d")
+ depend.on_changed(function()
+ progress.show(opt.progress or 0, "${color.build.object}generating.idl %s", sourcefile)
+ os.vrunv(midl.program, flags, { envs = msvc:runenvs() })
+ end, {
+ files = sourcefile,
+ dependfile = dependfile
+ })
+end
+
+function configure(target)
+ local sourcebatch = target:sourcebatches()["platform.windows.idl"]
+ if sourcebatch then
+ local autogendir = path.join(target:autogendir(), "platform/windows/idl")
+ os.mkdir(autogendir)
+ target:add("includedirs", autogendir, {public = true})
+ end
+end
+
+function generate_idl(target, jobgraph, sourcebatch, opt)
+ local idljob = target:fullname() .. "/generate/midl"
+ jobgraph:group(idljob, function()
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local midljob = target:fullname() .. "/generate/" .. sourcefile
+ jobgraph:add(midljob, function (index, total, opt)
+ generate_single(target, sourcefile, opt)
+ end)
+ end
+ end)
+end
+
+function build_idlfiles(target, jobgraph, sourcebatch, opt)
+ local autogendir = path.join(target:autogendir(), "platform/windows/idl")
+
+ local function addsrc(sourcename, suffix, mysources)
+ local fullfile = path.join(autogendir, sourcename .. suffix)
+ if os.exists(fullfile) then
+ table.insert(mysources, fullfile)
+ end
+ end
+
+ local build_midl = target:fullname() .. "/obj/midl"
+ jobgraph:group(build_midl, function()
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local ccjob = target:fullname() .. "/obj/" .. sourcefile
+ jobgraph:add(ccjob, function (index, total, opt)
+ local fileconfig = target:fileconfig(sourcefile)
+ local enable_proxy = true
+ if fileconfig then
+ if fileconfig.proxy then
+ enable_proxy = fileconfig.proxy
+ end
+ end
+ local name = path.basename(sourcefile)
+ local mysources = {}
+
+ -- we don't have a way to detect which midl files are generated
+ addsrc(name, "_i.c", mysources)
+ if enable_proxy then
+ addsrc(name, "_p.c", mysources)
+ end
+ addsrc(name, "_c.c", mysources)
+ addsrc(name, "_s.c", mysources)
+
+ local batchcxx = {
+ rulename = "c.build",
+ sourcekind = "cc",
+ sourcefiles = mysources,
+ objectfiles = {},
+ dependfiles = {}
+ }
+ for _, sourcefile in ipairs(batchcxx.sourcefiles) do
+ local objfile = target:objectfile(sourcefile)
+ local depfile = target:objectfile(objfile)
+ table.insert(target:objectfiles(), objfile)
+ table.insert(batchcxx.objectfiles, objfile)
+ table.insert(batchcxx.dependfiles, depfile)
+ table.insert(target:objectfiles(), objfile)
+ end
+ build_objectfiles.build(target, batchcxx, opt)
+ end)
+ end
+ end)
+end
diff --git a/xmake/rules/platform/windows/idl/xmake.lua b/xmake/rules/platform/windows/idl/xmake.lua
index f3a907f09..4e3aabd1b 100644
--- a/xmake/rules/platform/windows/idl/xmake.lua
+++ b/xmake/rules/platform/windows/idl/xmake.lua
@@ -16,52 +16,18 @@
--
-- @author ruki
-- @file xmake.lua
---
-- add *.idl for rc file
rule("platform.windows.idl")
set_extensions(".idl")
-
on_config("windows", "mingw", function (target)
- local sourcebatch = target:sourcebatches()["platform.windows.idl"]
- if sourcebatch then
- local autogendir = path.join(target:autogendir(), "platform/windows/idl")
- os.mkdir(autogendir)
- target:add("includedirs", autogendir, {public = true})
- end
+ import("idl").configure(target)
end)
- before_buildcmd_file(function (target, batchcmds, sourcefile, opt)
- import("lib.detect.find_tool")
-
- local msvc = target:toolchain("msvc") or target:toolchain("clang-cl") or target:toolchain("clang")
- local midl = assert(find_tool("midl", {envs = msvc:runenvs(), toolchain = msvc}), "midl not found!")
-
- local name = path.basename(sourcefile)
- local autogendir = path.join(target:autogendir(), "platform/windows/idl")
-
- local flags = {"/nologo"}
- table.join2(flags, table.wrap(target:values("idl.flags")))
- table.join2(flags, {
- "/out", path(autogendir),
- "/header", name .. ".h",
- "/iid", name .. "_i.c",
- "/proxy", name .. "_p.c",
- "/tlb", name .. ".tlb",
- path(sourcefile)
- })
+ before_build_files(function (target, jobgraph, sourcebatch, opt)
+ import("idl").generate_idl(target, jobgraph, sourcebatch, opt)
+ end, {jobgraph = true, batch = true})
- batchcmds:show_progress(opt.progress, "${color.build.object}compiling.idl %s", sourcefile)
- batchcmds:vrunv(midl.program, flags, {envs = msvc:runenvs()})
-
- local iid_file = path.join(autogendir, name .. "_i.c")
- local objectfile = target:objectfile(iid_file)
- table.insert(target:objectfiles(), objectfile)
-
- batchcmds:show_progress(opt.progress, "${color.build.object}compiling.$(mode) %s", iid_file)
- batchcmds:compile(iid_file, objectfile)
-
- batchcmds:add_depfiles(sourcefile, iid_file)
- batchcmds:set_depmtime(os.mtime(objectfile))
- batchcmds:set_depcache(target:dependfile(objectfile))
- end)
+ on_build_files(function (target, jobgraph, sourcebatch, opt)
+ import("idl").build_idlfiles(target, jobgraph, sourcebatch, opt)
+ end, {jobgraph = true, batch = true, distcc = true})