diff options
| author | ruki <[email protected]> | 2025-04-22 21:44:50 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-04-22 21:44:50 +0800 |
| commit | aeaeda4045e99ac49e225485ba269ff8541d9b03 (patch) | |
| tree | 5c3024e39b6b286cedaf92b0fc9176ea819d006c | |
| parent | 50def2df2bd6099720c7db2480004f29c7bc7e74 (diff) | |
| parent | 700b5497b88aecdfc604ef866f666d13f7d6c0b5 (diff) | |
Merge pull request #6301 from lakor64/dev
Improve MIDL support
| -rw-r--r-- | tests/projects/idl/test_norpc/src/lockowner.idl | 28 | ||||
| -rw-r--r-- | tests/projects/idl/test_norpc/src/test_iid.c | 8 | ||||
| -rw-r--r-- | tests/projects/idl/test_norpc/xmake.lua | 7 | ||||
| -rw-r--r-- | tests/projects/idl/test_norpc_proxy/src/lockowner.idl | 28 | ||||
| -rw-r--r-- | tests/projects/idl/test_norpc_proxy/src/test_iid.c | 8 | ||||
| -rw-r--r-- | tests/projects/idl/test_norpc_proxy/xmake.lua | 7 | ||||
| -rw-r--r-- | tests/projects/idl/test_rpc/src/example.idl | 13 | ||||
| -rw-r--r-- | tests/projects/idl/test_rpc/src/test_iid.c | 18 | ||||
| -rw-r--r-- | tests/projects/idl/test_rpc/xmake.lua | 7 | ||||
| -rw-r--r-- | tests/projects/idl/test_rpc_noserver/src/example.idl | 13 | ||||
| -rw-r--r-- | tests/projects/idl/test_rpc_noserver/src/test_iid.c | 17 | ||||
| -rw-r--r-- | tests/projects/idl/test_rpc_noserver/xmake.lua | 7 | ||||
| -rw-r--r-- | xmake/rules/platform/windows/idl/idl.lua | 190 | ||||
| -rw-r--r-- | xmake/rules/platform/windows/idl/xmake.lua | 48 |
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}) |
