diff --git a/packages/m/mcpplibs-tinyhttps/xmake.lua b/packages/m/mcpplibs-tinyhttps/xmake.lua index 08c6b27..207b779 100644 --- a/packages/m/mcpplibs-tinyhttps/xmake.lua +++ b/packages/m/mcpplibs-tinyhttps/xmake.lua @@ -18,7 +18,13 @@ package("mcpplibs-tinyhttps") on_load(function (package) package:add("links", "tinyhttps") - package:add("deps", "mbedtls >=3.6.1") + -- UPPER BOUND, not just a floor. mbedtls 4.x moved its headers: + -- `` became ``, so + -- `>=3.6.1` resolves to 4.2.0 and tinyhttps fails to compile at all: + -- src/tls.cppm:4:10: fatal error: mbedtls/entropy.h: + -- No such file or directory + -- The 3.6 series is what this source expects. + package:add("deps", "mbedtls >=3.6.1 <4.0") end) on_install(function (package) diff --git a/packages/m/mcpplibs-xpkg/xmake.lua b/packages/m/mcpplibs-xpkg/xmake.lua index 9d33d84..b074645 100644 --- a/packages/m/mcpplibs-xpkg/xmake.lua +++ b/packages/m/mcpplibs-xpkg/xmake.lua @@ -67,6 +67,53 @@ package("mcpplibs-xpkg") -- — five modules directly under src/ instead of one directory each — so -- one static target replaces the five below. if not os.isfile("xmake.lua") then + -- Generate the lua_stdlib module FIRST, so it is an ordinary source + -- file by the time xmake reads the description below. + local outfile = path.join(os.curdir(), "src/xpkg-lua-stdlib.cppm") + local f = io.open(outfile, "w") + f:write("// Auto-generated by mcpplibs-index - do not edit manually\n") + f:write("module;\n") + f:write("export module mcpplibs.xpkg.lua_stdlib;\n") + f:write("import std;\n\n") + f:write("export namespace mcpplibs::xpkg::detail {\n\n") + local MSVC_LIMIT = 15000 -- MSVC C2026: literals cap at 16380 bytes + local function embed(varname, file) + local content = io.readfile(file) + if #content <= MSVC_LIMIT then + f:write("inline constexpr std::string_view " .. varname) + f:write(" = R\"__LUA__(\n" .. content .. "\n)__LUA__\";\n\n") + else + local chunks, pos, idx = {}, 1, 0 + while pos <= #content do + local chunk = content:sub(pos, pos + MSVC_LIMIT - 1) + if pos + MSVC_LIMIT - 1 < #content then + local nl = chunk:reverse():find("\n") + if nl and nl < MSVC_LIMIT then + chunk = content:sub(pos, pos + MSVC_LIMIT - nl - 1) + end + end + local cname = varname .. "_" .. idx + f:write("inline constexpr std::string_view " .. cname) + f:write(" = R\"__LUA__(\n" .. chunk .. "\n)__LUA__\";\n\n") + chunks[#chunks + 1] = cname + pos, idx = pos + #chunk, idx + 1 + end + f:write("inline const std::string " .. varname .. "_storage = []{ std::string s;\n") + for _, c in ipairs(chunks) do f:write(" s += " .. c .. ";\n") end + f:write(" return s; }();\n") + f:write("inline const std::string_view " .. varname .. " = " .. varname .. "_storage;\n\n") + end + end + -- GLOBBED, not transcribed: 0.0.41 embedded ten files, 0.0.57 ships + -- eleven (xim/libxpkg/subos.lua is new). Sorted so the output is + -- byte-identical between runs. + local files = os.files(path.join(os.curdir(), "src/lua-stdlib/**.lua")) + assert(#files > 0, "no .lua under src/lua-stdlib - the layout changed") + table.sort(files) + for _, file in ipairs(files) do embed(path.basename(file) .. "_lua", file) end + f:write("} // namespace mcpplibs::xpkg::detail\n") + f:close() + io.writefile("xmake.lua", [==[ add_rules("mode.release", "mode.debug") set_languages("c++23") @@ -76,83 +123,21 @@ add_requires("mcpplibs-capi-lua") target("mcpplibs-xpkg") set_kind("static") add_files("src/*.cppm", {public = true, install = true}) - -- NAMED EXPLICITLY, not left to the glob above. The glob is evaluated when - -- the description is read, and `src/xpkg-lua-stdlib.cppm` does not exist - -- yet at that point — before_build creates it. Relying on the glob alone - -- leaves the generated module out of the source list entirely and the build - -- fails with - -- missing mcpplibs.xpkg.lua_stdlib dependency for module - -- mcpplibs.xpkg.executor - -- which names a consumer and never the file that was not compiled. - -- (This is exactly how libxpkg's own xmake.lua declares it.) - add_files("src/xpkg-lua-stdlib.cppm", {public = true, install = true}) add_packages("mcpplibs-capi-lua", {public = true}) set_policy("build.c++.modules", true) - -- `mcpplibs.xpkg.lua_stdlib` is generated: every .lua under src/lua-stdlib - -- embedded as a string_view named after the file. It is written INTO src/, - -- which the glob above already covers — emitting it elsewhere and adding it - -- afterwards lands it in the source list after the module scanner has built - -- its provider map, and the build then fails with - -- `missing mcpplibs.xpkg.lua_stdlib dependency` naming a consumer. - before_build(function (target) - local proj = target:scriptdir() - local outfile = path.join(proj, "src/xpkg-lua-stdlib.cppm") - local f = io.open(outfile, "w") - f:write("// Auto-generated by xmake before_build - do not edit manually\n") - f:write("module;\n") - f:write("export module mcpplibs.xpkg.lua_stdlib;\n") - f:write("import std;\n\n") - f:write("export namespace mcpplibs::xpkg::detail {\n\n") - - -- MSVC C2026: a string literal may not exceed 16380 bytes. - local MSVC_LIMIT = 15000 - local function embed(varname, file) - local content = io.readfile(file) - if #content <= MSVC_LIMIT then - f:write("inline constexpr std::string_view " .. varname) - f:write(" = R\"__LUA__(\n") - f:write(content) - f:write("\n)__LUA__\";\n\n") - else - local chunks, pos, idx = {}, 1, 0 - while pos <= #content do - local chunk = content:sub(pos, pos + MSVC_LIMIT - 1) - if pos + MSVC_LIMIT - 1 < #content then - local nl = chunk:reverse():find("\n") - if nl and nl < MSVC_LIMIT then - chunk = content:sub(pos, pos + MSVC_LIMIT - nl - 1) - end - end - local cname = varname .. "_" .. idx - f:write("inline constexpr std::string_view " .. cname) - f:write(" = R\"__LUA__(\n") - f:write(chunk) - f:write("\n)__LUA__\";\n\n") - chunks[#chunks + 1] = cname - pos = pos + #chunk - idx = idx + 1 - end - f:write("inline const std::string " .. varname .. "_storage = []{ std::string s;\n") - for _, c in ipairs(chunks) do f:write(" s += " .. c .. ";\n") end - f:write(" return s; }();\n") - f:write("inline const std::string_view " .. varname) - f:write(" = " .. varname .. "_storage;\n\n") - end - end - - -- GLOBBED, not transcribed. 0.0.41 embedded ten files; 0.0.57 ships - -- eleven (xim/libxpkg/subos.lua is new), and a copied list would drop it - -- silently. Sorted so the output is byte-identical between runs. - local files = os.files(path.join(proj, "src/lua-stdlib/**.lua")) - table.sort(files) - for _, file in ipairs(files) do - embed(path.basename(file) .. "_lua", file) - end - - f:write("} // namespace mcpplibs::xpkg::detail\n") - f:close() - end) + -- The generated module is already on disk when this description is read + -- (on_install writes it before writing this file), so the glob above picks + -- it up like any other source. Generating it from `before_build` — where + -- libxpkg's own five-target layout could put it — does NOT work here: + -- before_build runs AFTER module dependency scanning, and the scan of + -- xpkg-executor.cppm hits `import mcpplibs.xpkg.lua_stdlib` with no + -- provider and stops the build first: + -- missing mcpplibs.xpkg.lua_stdlib dependency for module + -- mcpplibs.xpkg.executor + -- libxpkg got away with it by giving the generated module its own target + -- that consumers `add_deps` on; 0.0.42+ is flat, so there is no such + -- ordering to lean on. ]==]) install(package, configs, {target = "mcpplibs-xpkg"}) return