diff options
| author | ruki <[email protected]> | 2025-05-17 22:08:31 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-05-17 22:08:31 +0800 |
| commit | 2f8decdc353f4e18de953c074ae8fed1c0969cda (patch) | |
| tree | 48c8fc85958094ba81f635e6dcaf59f351e88374 | |
| parent | bfef847fcd6f6745b52a9f3c2ab2870dcaf23d16 (diff) | |
| parent | 2b88ba37fa0a9957b8ab24cf1bf6da59e2c39f21 (diff) | |
Merge branch 'dev' into unitybuildunitybuild
36 files changed, 301 insertions, 76 deletions
diff --git a/tests/projects/python/cython/example/src/example.py b/tests/projects/python/cython/example/src/example.py new file mode 100644 index 000000000..f7cf60e14 --- /dev/null +++ b/tests/projects/python/cython/example/src/example.py @@ -0,0 +1 @@ +print("Hello, world!") diff --git a/tests/projects/python/cython/example/xmake.lua b/tests/projects/python/cython/example/xmake.lua new file mode 100644 index 000000000..f7461dbc2 --- /dev/null +++ b/tests/projects/python/cython/example/xmake.lua @@ -0,0 +1,7 @@ +add_rules("mode.debug", "mode.release") +add_requires("python 3.x") + +target("example") + add_rules("python.cython") + add_files("src/*.py") + add_packages("python") diff --git a/tests/projects/pybind/example/src/example.cpp b/tests/projects/python/pybind/example/src/example.cpp index cb1bad194..cb1bad194 100644 --- a/tests/projects/pybind/example/src/example.cpp +++ b/tests/projects/python/pybind/example/src/example.cpp diff --git a/tests/projects/pybind/example_with_soabi/xmake.lua b/tests/projects/python/pybind/example/xmake.lua index 12d8ad334..e8435e360 100644 --- a/tests/projects/pybind/example_with_soabi/xmake.lua +++ b/tests/projects/python/pybind/example/xmake.lua @@ -2,7 +2,7 @@ add_rules("mode.release", "mode.debug") add_requires("pybind11") target("example") - add_rules("python.library", {soabi = true}) + add_rules("python.module", {soabi = false}) add_files("src/*.cpp") add_packages("pybind11") set_languages("c++11") diff --git a/tests/projects/pybind/example_with_soabi/src/example.cpp b/tests/projects/python/pybind/example_with_soabi/src/example.cpp index cb1bad194..cb1bad194 100644 --- a/tests/projects/pybind/example_with_soabi/src/example.cpp +++ b/tests/projects/python/pybind/example_with_soabi/src/example.cpp diff --git a/tests/projects/pybind/example/xmake.lua b/tests/projects/python/pybind/example_with_soabi/xmake.lua index 19b7b5a9e..93c200c57 100644 --- a/tests/projects/pybind/example/xmake.lua +++ b/tests/projects/python/pybind/example_with_soabi/xmake.lua @@ -2,7 +2,7 @@ add_rules("mode.release", "mode.debug") add_requires("pybind11") target("example") - add_rules("python.library") + add_rules("python.module") add_files("src/*.cpp") add_packages("pybind11") set_languages("c++11") diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua index 4e5aaf8c7..94adfd53f 100644 --- a/xmake/core/base/interpreter.lua +++ b/xmake/core/base/interpreter.lua @@ -1793,7 +1793,7 @@ function interpreter:api_builtin_includes(...) files = os.files(subpath) else -- @see https://github.com/xmake-io/xmake/issues/6026 - files = os.files(path.join(subpath, path.filename(curfile))) + files = os.files(path.join(subpath, "xmake.lua")) end if files and #files > 0 then table.join2(subpaths_matched, files) diff --git a/xmake/core/base/profiler.lua b/xmake/core/base/profiler.lua index ae0ced4fc..1cd1a1d2d 100644 --- a/xmake/core/base/profiler.lua +++ b/xmake/core/base/profiler.lua @@ -182,14 +182,20 @@ function profiler:stop() return a.totaltime > b.totaltime end) - -- show reports + -- show and save reports + local report_lines = "" + local outfile = path.join(os.tmpdir(), "perf-call-" .. os.date("%d-%m-%y-%S-%M-%H") .. ".log") for _, report in ipairs(reports) do local percent = (report.totaltime / totaltime) * 100 if percent < 1 then break end - utils.print("%6.3f, %6.2f%%, %7d, %s", report.totaltime, percent, report.callcount, self:_func_title(report.funcinfo)) + local report_line = string.format("%6.3f, %6.2f%%, %7d, %s", report.totaltime, percent, report.callcount, self:_func_title(report.funcinfo)) + report_lines = report_lines .. report_line .. "\n" + utils.print(report_line) end + utils.print("full log written to %s", outfile) + io.writefile(outfile, report_lines) elseif self:is_perf("tag") then -- sort reports, topN @@ -201,16 +207,27 @@ function profiler:stop() h:push(report) end - -- show reports + -- show and save reports local count = 0 - while count < 64 and h:length() > 0 do + local max_count = 64 + local outfile = path.join(os.tmpdir(), "perf-tag-" .. os.date("%d-%m-%y-%S-%M-%H") .. ".log") + local report_lines = "" + while h:length() > 0 do local report = h:pop() - utils.print("%6.3f, %7d, %s", report.totaltime, report.callcount, self:_tag_title(report.name, report.argv)) + local report_line = string.format("%6.3f, %7d, %s", report.totaltime, report.callcount, self:_tag_title(report.name, report.argv)) + report_lines = report_lines .. report_line .. "\n" count = count + 1 end - if h:length() > 0 then + if count <= max_count then + utils.print(report_lines) + elseif count > max_count then + local max_count_lines = {table.unpack(report_lines:split("\n"), 1, max_count)} + utils.print(table.concat(max_count_lines, "\n")) utils.print("...") + count = count + 1 end + utils.print("full log written to %s", outfile) + io.writefile(outfile, report_lines) end end diff --git a/xmake/modules/detect/sdks/find_qt.lua b/xmake/modules/detect/sdks/find_qt.lua index d720ac8b8..29eb65e73 100644 --- a/xmake/modules/detect/sdks/find_qt.lua +++ b/xmake/modules/detect/sdks/find_qt.lua @@ -141,7 +141,13 @@ function _find_sdkdir(sdkdir, sdkver) -- @see https://github.com/xmake-io/xmake/issues/4881 if sdkver then local major = sdkver:sub(1, 1) - qmake = find_file("qmake" .. major, paths, {suffixes = subdirs}) + local suffixes = {major, "-" .. major, "-qt" .. major, ""} + for _, suffix in ipairs(suffixes) do + qmake = find_file("qmake" .. suffix, paths, {suffixes = subdirs}) + if qmake then + break + end + end end if not qmake then qmake = find_file("qmake", paths, {suffixes = subdirs}) @@ -167,18 +173,25 @@ function _find_qmake(sdkdir, sdkver) if sdkver then sdkver = semver.try_parse(sdkver) if sdkver then - local cachekey = "qmake-" .. sdkver:major() - qmake = find_tool("qmake", {program = "qmake" .. sdkver:major(), cachekey = cachekey, paths = sdkdir and path.join(sdkdir, "bin")}) + local major = sdkver:major() + local suffixes = {major, "-" .. major, "-qt" .. major} + for _, suffix in ipairs(suffixes) do + local cachekey = "qmake" .. suffix + qmake = find_tool("qmake", {program = cachekey, cachekey = cachekey, paths = sdkdir and path.join(sdkdir, "bin")}) + if qmake then + break + end + end end end -- we need to find the default qmake in current system -- maybe we only installed qmake6 if not qmake then - local suffixes = {"", "6", "-qt5"} + local suffixes = {"", "6", "-6", "-qt6", "5", "-5", "-qt5"} for _, suffix in ipairs(suffixes) do - local cachekey = "qmake-" .. suffix - qmake = find_tool("qmake", {program = "qmake" .. suffix, cachekey = cachekey, paths = sdkdir and path.join(sdkdir, "bin")}) + local cachekey = "qmake" .. suffix + qmake = find_tool("qmake", {program = cachekey, cachekey = cachekey, paths = sdkdir and path.join(sdkdir, "bin")}) if qmake then break end diff --git a/xmake/modules/detect/sdks/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua index c3aca3ad4..3e687228a 100644 --- a/xmake/modules/detect/sdks/find_vstudio.lua +++ b/xmake/modules/detect/sdks/find_vstudio.lua @@ -109,11 +109,9 @@ function find_build_tools(opt) end local variables = {} - local VCToolsVersion - local vs_toolset = opt.vs_toolset - if vs_toolset and os.isdir(path.join(sdkdir, "VC/Tools/MSVC", vs_toolset)) then - VCToolsVersion = vs_toolset - else + local VCInstallDir = path.join(sdkdir, "VC") + local VCToolsVersion = opt.vs_toolset + if not VCToolsVersion or not os.isdir(path.join(VCInstallDir, "Tools/MSVC", VCToolsVersion)) then -- https://github.com/xmake-io/xmake/issues/6159 local latest_toolset for _, dir in ipairs(os.dirs(path.join(sdkdir, "VC/Tools/MSVC/*"))) do @@ -128,8 +126,9 @@ function find_build_tools(opt) return end end + variables.VCInstallDir = VCInstallDir variables.VCToolsVersion = VCToolsVersion - variables.VCToolsInstallDir = path.join(sdkdir, "VC/Tools/MSVC", VCToolsVersion) + variables.VCToolsInstallDir = path.join(VCInstallDir, "Tools/MSVC", VCToolsVersion) local WindowsSDKVersion local vs_sdkver = opt.vs_sdkver @@ -145,10 +144,15 @@ function find_build_tools(opt) end variables.WindowsSDKVersion = WindowsSDKVersion variables.WindowsSdkDir = path.join(sdkdir, "Windows Kits/10") + variables.WindowsSdkBinPath = path.join(variables.WindowsSdkDir, "bin") + variables.WindowsSdkVerBinPath = path.join(variables.WindowsSdkBinPath, WindowsSDKVersion) + variables.ExtensionSdkDir = path.join(variables.WindowsSdkDir, "ExtensionSdkDir") + variables.UCRTVersion = WindowsSDKVersion + variables.UniversalCRTSdkDir = variables.WindowsSdkDir local includedirs = { path.join(variables.VCToolsInstallDir, "include"), - path.join(variables.VCToolsInstallDir, "atlmfc/include"), + path.join(variables.VCToolsInstallDir, "atlmfc", "include"), path.join(variables.WindowsSdkDir, "Include", WindowsSDKVersion, "ucrt"), path.join(variables.WindowsSdkDir, "Include", WindowsSDKVersion, "shared"), path.join(variables.WindowsSdkDir, "Include", WindowsSDKVersion, "um"), @@ -158,8 +162,10 @@ function find_build_tools(opt) local linkdirs = { path.join(variables.VCToolsInstallDir, "lib"), + path.join(variables.VCToolsInstallDir, "atlmfc", "lib"), path.join(variables.WindowsSdkDir, "Lib", WindowsSDKVersion, "ucrt"), path.join(variables.WindowsSdkDir, "Lib", WindowsSDKVersion, "um"), + path.join(variables.WindowsSdkDir, "Lib", WindowsSDKVersion, "km"), } local archs = { @@ -182,32 +188,42 @@ function find_build_tools(opt) if #lib ~= 0 then local vcvars = { BUILD_TOOLS_ROOT = sdkdir, + VSInstallDir = sdkdir, -- vs runs in a windows ctx, so the envsep is always ";" INCLUDE = path.joinenv(includedirs, ';'), LIB = path.joinenv(lib, ';'), - WindowsSdkDir = variables.WindowsSdkDir, - WindowsSDKVersion = WindowsSDKVersion, - VCToolsInstallDir = variables.VCToolsInstallDir, VSCMD_ARG_HOST_ARCH = "x64", + + VCInstallDir = variables.VCInstallDir, + VCToolsVersion = variables.VCToolsVersion, + VCToolsInstallDir = variables.VCToolsInstallDir, + + WindowsSDKVersion = variables.WindowsSDKVersion, + WindowsSdkDir = variables.WindowsSdkDir, + WindowsSdkBinPath = variables.WindowsSdkBinPath, + WindowsSdkVerBinPath = variables.WindowsSdkVerBinPath, + ExtensionSdkDir = variables.ExtensionSdkDir, + UCRTVersion = variables.UCRTVersion, + UniversalCRTSdkDir = variables.UniversalCRTSdkDir, } - local buidl_tools_bin = {} + local build_tools_bin = {} local host_dir = "Host" .. vcvars.VSCMD_ARG_HOST_ARCH if is_host("windows") then - table.insert(buidl_tools_bin, path.join(vcvars.VCToolsInstallDir, "bin", host_dir, target_arch)) - table.insert(buidl_tools_bin, path.join(vcvars.WindowsSdkDir, "bin", WindowsSDKVersion)) - table.insert(buidl_tools_bin, path.join(vcvars.WindowsSdkDir, "bin", WindowsSDKVersion, "ucrt")) + table.insert(build_tools_bin, path.join(vcvars.VCToolsInstallDir, "bin", host_dir, target_arch)) + table.insert(build_tools_bin, path.join(vcvars.WindowsSdkDir, "bin", WindowsSDKVersion)) + table.insert(build_tools_bin, path.join(vcvars.WindowsSdkDir, "bin", WindowsSDKVersion, "ucrt")) elseif is_host("linux") then -- for msvc-wine - table.insert(buidl_tools_bin, path.join(sdkdir, "bin", target_arch)) + table.insert(build_tools_bin, path.join(sdkdir, "bin", target_arch)) end vcvars.VSCMD_ARG_TGT_ARCH = target_arch - vcvars.BUILD_TOOLS_BIN = path.joinenv(buidl_tools_bin) + vcvars.BUILD_TOOLS_BIN = path.joinenv(build_tools_bin) - local PATH = buidl_tools_bin + local PATH = build_tools_bin table.join2(PATH, path.splitenv(os.getenv("PATH"))) vcvars.PATH = path.joinenv(PATH) diff --git a/xmake/modules/detect/tools/find_7z.lua b/xmake/modules/detect/tools/find_7z.lua index ce1a04f4a..df0c700fc 100644 --- a/xmake/modules/detect/tools/find_7z.lua +++ b/xmake/modules/detect/tools/find_7z.lua @@ -45,7 +45,7 @@ function main(opt) -- find 7z from builtin xmake/winenv if is_host("windows") then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) table.insert(opt.paths, path.join(os.programdir(), "winenv", "bin")) end diff --git a/xmake/modules/detect/tools/find_bash.lua b/xmake/modules/detect/tools/find_bash.lua index 0c1322ad2..063895830 100644 --- a/xmake/modules/detect/tools/find_bash.lua +++ b/xmake/modules/detect/tools/find_bash.lua @@ -43,7 +43,7 @@ function main(opt) -- find bash from git for windows if is_host("windows") then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) table.insert(opt.paths, "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\GitForWindows;InstallPath)\\bin") end diff --git a/xmake/modules/detect/tools/find_clang_format.lua b/xmake/modules/detect/tools/find_clang_format.lua index d378be16e..b1839ce50 100644 --- a/xmake/modules/detect/tools/find_clang_format.lua +++ b/xmake/modules/detect/tools/find_clang_format.lua @@ -41,7 +41,7 @@ function main(opt) if not program and is_host("macosx") then local llvm = try {function () return os.iorunv("brew", {"--prefix", "llvm"}) end} if llvm then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) opt.force = true table.insert(opt.paths, path.join(llvm:trim(), "bin")) program = find_program(opt.program or "clang-format", opt) diff --git a/xmake/modules/detect/tools/find_clang_scan_deps.lua b/xmake/modules/detect/tools/find_clang_scan_deps.lua index f4b9cd87b..eae1ace5d 100644 --- a/xmake/modules/detect/tools/find_clang_scan_deps.lua +++ b/xmake/modules/detect/tools/find_clang_scan_deps.lua @@ -41,7 +41,7 @@ function main(opt) if not program and is_host("macosx") then local llvm = try {function () return os.iorunv("brew", {"--prefix", "llvm"}) end} if llvm then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) opt.force = true table.insert(opt.paths, path.join(llvm:trim(), "bin")) program = find_program(opt.program or "clang-scan-deps", opt) diff --git a/xmake/modules/detect/tools/find_clang_tidy.lua b/xmake/modules/detect/tools/find_clang_tidy.lua index 0ca6dc0d2..ffa4d5c3b 100644 --- a/xmake/modules/detect/tools/find_clang_tidy.lua +++ b/xmake/modules/detect/tools/find_clang_tidy.lua @@ -41,7 +41,7 @@ function main(opt) if not program and is_host("macosx") then local llvm = try {function () return os.iorunv("brew", {"--prefix", "llvm"}) end} if llvm then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) opt.force = true table.insert(opt.paths, path.join(llvm:trim(), "bin")) program = find_program(opt.program or "clang-tidy", opt) diff --git a/xmake/modules/detect/tools/find_curl.lua b/xmake/modules/detect/tools/find_curl.lua index 493264684..899f51721 100644 --- a/xmake/modules/detect/tools/find_curl.lua +++ b/xmake/modules/detect/tools/find_curl.lua @@ -42,7 +42,7 @@ function main(opt) -- find curl from builtin xmake/winenv if is_host("windows") then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) table.insert(opt.paths, path.join(os.programdir(), "winenv", "bin")) end diff --git a/xmake/modules/detect/tools/find_dxc.lua b/xmake/modules/detect/tools/find_dxc.lua index 3bded84c3..1563a6ec4 100644 --- a/xmake/modules/detect/tools/find_dxc.lua +++ b/xmake/modules/detect/tools/find_dxc.lua @@ -43,6 +43,7 @@ function main(opt) "$(env VK_SDK_PATH)/Bin", "$(env PATH)" } + opt.paths = table.wrap(opt.paths) local program = find_program(opt.program or "dxc.exe", opt) local version = nil if program and opt and opt.version then diff --git a/xmake/modules/detect/tools/find_iverilog.lua b/xmake/modules/detect/tools/find_iverilog.lua index 85ac740f2..0ab509d72 100644 --- a/xmake/modules/detect/tools/find_iverilog.lua +++ b/xmake/modules/detect/tools/find_iverilog.lua @@ -43,7 +43,7 @@ function main(opt) -- find it from some logical drives paths if is_host("windows") then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) for _, logical_drive in ipairs(winos.logical_drives()) do table.insert(opt.paths, path.join(logical_drive, "iverilog", "bin")) end diff --git a/xmake/modules/detect/tools/find_midl.lua b/xmake/modules/detect/tools/find_midl.lua index a8b7c6119..d9e59bef6 100644 --- a/xmake/modules/detect/tools/find_midl.lua +++ b/xmake/modules/detect/tools/find_midl.lua @@ -45,7 +45,7 @@ function main(opt) local arch = toolchain and toolchain:arch() or config.arch() local bindir = path.join(envs.WindowsSdkDir, "bin", envs.WindowsSDKVersion, arch) if os.isdir(bindir) then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) table.insert(opt.paths, bindir) end end diff --git a/xmake/modules/detect/tools/find_ollydbg.lua b/xmake/modules/detect/tools/find_ollydbg.lua index 78971c89f..62f5ca419 100644 --- a/xmake/modules/detect/tools/find_ollydbg.lua +++ b/xmake/modules/detect/tools/find_ollydbg.lua @@ -50,6 +50,7 @@ function main(opt) return (val("reg " .. reg) or ""):match("\"(.-)\"") end end + opt.paths = table.wrap(opt.paths) opt.check = opt.check or function (program) if not os.isfile(program) then raise() end end -- find program diff --git a/xmake/modules/detect/tools/find_python3.lua b/xmake/modules/detect/tools/find_python3.lua index 3b606f279..2e2477c11 100644 --- a/xmake/modules/detect/tools/find_python3.lua +++ b/xmake/modules/detect/tools/find_python3.lua @@ -40,7 +40,7 @@ function main(opt) -- init options opt = opt or {} if is_host("windows") then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) local keys = winos.registry_keys("HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.*\\InstallPath") for _, key in ipairs(keys) do local value = try {function () return winos.registry_query(key .. ";ExecutablePath") end} diff --git a/xmake/modules/detect/tools/find_renderdoc.lua b/xmake/modules/detect/tools/find_renderdoc.lua index 771fbcfd4..f8cb84381 100644 --- a/xmake/modules/detect/tools/find_renderdoc.lua +++ b/xmake/modules/detect/tools/find_renderdoc.lua @@ -40,7 +40,7 @@ function main(opt) -- init options opt = opt or {} if is_host("windows") then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) -- add paths from registry local regs = diff --git a/xmake/modules/detect/tools/find_vsjitdebugger.lua b/xmake/modules/detect/tools/find_vsjitdebugger.lua index ecaede0b7..315b333bc 100644 --- a/xmake/modules/detect/tools/find_vsjitdebugger.lua +++ b/xmake/modules/detect/tools/find_vsjitdebugger.lua @@ -50,6 +50,7 @@ function main(opt) return (val("reg " .. reg) or ""):match("\"(.-)\"") end end + opt.paths = table.wrap(opt.paths) opt.check = opt.check or function (program) if not os.isfile(program) then raise() end end -- find program diff --git a/xmake/modules/detect/tools/find_vswhere.lua b/xmake/modules/detect/tools/find_vswhere.lua index 75efb6b6e..7576ceda2 100644 --- a/xmake/modules/detect/tools/find_vswhere.lua +++ b/xmake/modules/detect/tools/find_vswhere.lua @@ -55,6 +55,7 @@ function main(opt) "$(env ProgramFiles%(x86%))\\Microsoft Visual Studio\\Installer", "$(env ProgramFiles)\\Microsoft Visual Studio\\Installer" } + opt.paths = table.wrap(opt.paths) local program = find_program(opt.program or "vswhere.exe", opt) -- find program version diff --git a/xmake/modules/detect/tools/find_vvp.lua b/xmake/modules/detect/tools/find_vvp.lua index c13cbcf1a..11a698f13 100644 --- a/xmake/modules/detect/tools/find_vvp.lua +++ b/xmake/modules/detect/tools/find_vvp.lua @@ -43,7 +43,7 @@ function main(opt) -- find it from some logical drives paths if is_host("windows") then - opt.paths = opt.paths or {} + opt.paths = table.wrap(opt.paths) for _, logical_drive in ipairs(winos.logical_drives()) do table.insert(opt.paths, path.join(logical_drive, "iverilog", "bin")) end diff --git a/xmake/modules/detect/tools/find_windbg.lua b/xmake/modules/detect/tools/find_windbg.lua index 85fc61d03..8a6e07ae4 100644 --- a/xmake/modules/detect/tools/find_windbg.lua +++ b/xmake/modules/detect/tools/find_windbg.lua @@ -50,6 +50,7 @@ function main(opt) return (val("reg " .. reg) or ""):match("\"(.-)\"") end end + opt.paths = table.wrap(opt.paths) opt.check = opt.check or function (program) if not os.isfile(program) then raise() end end -- find program diff --git a/xmake/modules/detect/tools/find_x64dbg.lua b/xmake/modules/detect/tools/find_x64dbg.lua index 350ac8ad0..472aea156 100644 --- a/xmake/modules/detect/tools/find_x64dbg.lua +++ b/xmake/modules/detect/tools/find_x64dbg.lua @@ -50,6 +50,7 @@ function main(opt) return (val("reg " .. reg) or ""):match("\"(.-)\"") end end + opt.paths = table.wrap(opt.paths) opt.check = opt.check or function (program) if not os.isfile(program) then raise() end end -- find program diff --git a/xmake/modules/private/action/require/impl/actions/install.lua b/xmake/modules/private/action/require/impl/actions/install.lua index 5e0c2c542..4d0bada1f 100644 --- a/xmake/modules/private/action/require/impl/actions/install.lua +++ b/xmake/modules/private/action/require/impl/actions/install.lua @@ -41,17 +41,33 @@ function _patch_pkgconfig(package) return end + local installdir = path.unix(path.normalize(package:installdir())) + -- get lib/pkgconfig/*.pc or share/pkgconfig/*.pc file local libpkgconfigdir = path.join(package:installdir(), "lib", "pkgconfig") local sharepkgconfigdir = path.join(package:installdir(), "share", "pkgconfig") - local pcfile = (os.isdir(libpkgconfigdir) and find_file("*.pc", libpkgconfigdir)) - or (os.isdir(sharepkgconfigdir) and find_file("*.pc", sharepkgconfigdir)) or nil - if pcfile then + local pcfiles = {} + table.join2(pcfiles, os.isdir(libpkgconfigdir) and os.files(path.join(libpkgconfigdir, "*.pc")) or {}) + table.join2(pcfiles, os.isdir(sharepkgconfigdir) and os.files(path.join(sharepkgconfigdir, "*.pc")) or {}) + if #pcfiles > 0 then + for _, pcfile in ipairs(pcfiles) do + local pcfile_content = io.readfile(pcfile) + if pcfile_content then + local pcfile_content, count = pcfile_content:replace(installdir, "${installdir}", {plain = true}) + if count > 0 then + local line_ending = pcfile_content:find("\r\n") and "\r\n" or "\n" + pcfile_content = "# Modified by Xmake: Using relative paths to make package relocatable" .. line_ending + .. "installdir=${pcfiledir}/" .. path.unix(path.relative(installdir, path.directory(pcfile))) .. line_ending + .. pcfile_content + io.writefile(pcfile, pcfile_content) + end + end + end return end -- trace - pcfile = path.join(libpkgconfigdir, package:name() .. ".pc") + local pcfile = path.join(libpkgconfigdir, package:name() .. ".pc") vprint("patching %s ..", pcfile) -- fetch package @@ -62,10 +78,10 @@ function _patch_pkgconfig(package) -- get libs local libs = "" - local installdir = package:installdir() + local base_libdir = path.join(installdir, "lib") for _, linkdir in ipairs(fetchinfo.linkdirs) do - if linkdir ~= path.join(installdir, "lib") then - libs = libs .. " -L" .. (linkdir:gsub("\\", "/")) + if linkdir ~= base_libdir then + libs = libs .. " -L" .. "${libdir}/" .. path.unix(path.relative(linkdir, base_libdir)) end end libs = libs .. " -L${libdir}" @@ -78,9 +94,10 @@ function _patch_pkgconfig(package) -- cflags local cflags = "" + local base_includedir = path.join(installdir, "include") for _, includedir in ipairs(fetchinfo.includedirs or fetchinfo.sysincludedirs) do - if includedir ~= path.join(installdir, "include") then - cflags = cflags .. " -I" .. (includedir:gsub("\\", "/")) + if includedir ~= base_includedir then + cflags = cflags .. " -I" .. "${includedir}/" .. path.unix(path.relative(includedir, base_includedir)) end end cflags = cflags .. " -I${includedir}" @@ -91,7 +108,8 @@ function _patch_pkgconfig(package) -- patch a *.pc file local file = io.open(pcfile, 'w') if file then - file:print("prefix=%s", installdir:gsub("\\", "/")) + file:print("# Generated by Xmake") + file:print("prefix=%s", "${pcfiledir}/" .. path.unix(path.relative(installdir, path.directory(pcfile)))) file:print("exec_prefix=${prefix}") file:print("libdir=${exec_prefix}/lib") file:print("includedir=${prefix}/include") diff --git a/xmake/modules/target/action/install/pkgconfig_importfiles.lua b/xmake/modules/target/action/install/pkgconfig_importfiles.lua index 65da32085..67ab51b64 100644 --- a/xmake/modules/target/action/install/pkgconfig_importfiles.lua +++ b/xmake/modules/target/action/install/pkgconfig_importfiles.lua @@ -24,7 +24,7 @@ function main(target, opt) -- check opt = opt or {} assert(target:is_library(), 'pkgconfig_importfiles: only support for library target(%s)!', target:name()) - local installdir = target:installdir() + local installdir = path.unix(path.normalize(target:installdir())) if not installdir then return end @@ -41,9 +41,10 @@ function main(target, opt) -- get libs local libs = "" + local base_libdir = path.join(installdir, "lib") for _, linkdir in ipairs(linkdirs) do - if linkdir ~= path.join(installdir, "lib") then - libs = libs .. " -L" .. (linkdir:gsub("\\", "/")) + if linkdir ~= base_libdir then + libs = libs .. " -L" .. "${libdir}/" .. path.unix(path.relative(linkdir, base_libdir)) end end libs = libs .. " -L${libdir}" @@ -56,9 +57,10 @@ function main(target, opt) -- get cflags local cflags = "" + local base_includedir = path.join(installdir, "include") for _, includedir in ipairs(includedirs) do - if includedir ~= path.join(installdir, "include") then - cflags = cflags .. " -I" .. (includedir:gsub("\\", "/")) + if includedir ~= base_includedir then + cflags = cflags .. " -I" .. "${includedir}/" .. path.unix(path.relative(includedir, base_includedir)) end end cflags = cflags .. " -I${includedir}" @@ -70,7 +72,8 @@ function main(target, opt) -- generate a *.pc file local file = io.open(pcfile, 'w') if file then - file:print("prefix=%s", installdir:gsub("\\", "/")) + file:print("# Generated by Xmake") + file:print("prefix=%s", "${pcfiledir}/" .. path.unix(path.relative(installdir, path.directory(pcfile)))) file:print("exec_prefix=${prefix}") file:print("libdir=${exec_prefix}/lib") file:print("includedir=${prefix}/include") diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua index d4b29dbc8..e650dd369 100644 --- a/xmake/plugins/project/cmake/cmakelists.lua +++ b/xmake/plugins/project/cmake/cmakelists.lua @@ -355,19 +355,25 @@ function _add_project(cmakelists, outputdir) if _can_native_support_for_cxxmodules() then cmakelists:print("set(CMAKE_CXX_SCAN_FOR_MODULES ON)") end + local languages = _get_project_languages() if project_name then local project_info = "" local project_version = project.version() if project_version then project_info = project_info .. " VERSION " .. project_version end - local languages = _get_project_languages() if languages then cmakelists:print("project(%s%s LANGUAGES %s)", project_name, project_info, table.concat(languages, " ")) else cmakelists:print("project(%s%s)", project_name, project_info) end end + -- Define a language-independant global compiler_id variable + if (languages and #languages > 0) then + cmakelists:print("set(CURRENT_COMPILER_ID ${CMAKE_%s_COMPILER_ID})", _get_project_languages()[1]) + else + cmakelists:print("set(CURRENT_COMPILER_ID ${CMAKE_C_COMPILER_ID})") -- C should be defined by default if not specified + end cmakelists:print("") end @@ -784,7 +790,7 @@ function _add_target_compile_options(cmakelists, target, outputdir) for _, toolname in toolnames:keys() do local name = compilernames[toolname] if name then - cmakelists:print("if(CMAKE_COMPILER_ID STREQUAL \"%s\")", name) + cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"%s\")", name) _add_target_compile_options_for_compiler(toolname) cmakelists:print("endif()") end @@ -811,17 +817,17 @@ function _add_target_values(cmakelists, target, name) if name:endswith("s") then name = name:sub(1, #name - 1) end - cmakelists:print("if(CMAKE_COMPILER_ID STREQUAL \"MSVC\")") + cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")") local flags_cl = _map_compflags("cl", "c", name, values) for _, flag in ipairs(flags_cl) do cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flag) end - cmakelists:print("elseif(CMAKE_COMPILER_ID STREQUAL \"Clang\")") + cmakelists:print("elseif(CURRENT_COMPILER_ID STREQUAL \"Clang\")") local flags_clang = _map_compflags("clang", "c", name, values) for _, flag in ipairs(flags_clang) do cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flag) end - cmakelists:print("elseif(CMAKE_COMPILER_ID STREQUAL \"GNU\")") + cmakelists:print("elseif(CURRENT_COMPILER_ID STREQUAL \"GNU\")") local flags_gcc = _map_compflags("gcc", "c", name, values) for _, flag in ipairs(flags_gcc) do cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flag) @@ -888,7 +894,7 @@ function _add_target_languages(cmakelists, target) if flag:endswith('++') then cmakelists:print('foreach(standard 26 23 20 17 14 11 98)') cmakelists:print(' include(CheckCXXCompilerFlag)') - cmakelists:print(' if(CMAKE_COMPILER_ID STREQUAL \"MSVC\")') + cmakelists:print(' if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")') cmakelists:print(' check_cxx_compiler_flag("/std:%s${standard}" %s_support_%s_standard_${standard})', flag, target:name(), flag) cmakelists:print(' else()') cmakelists:print(' check_cxx_compiler_flag("-std=%s${standard}" %s_support_%s_standard_${standard})', flag, target:name(), flag) @@ -901,7 +907,7 @@ function _add_target_languages(cmakelists, target) else cmakelists:print('foreach(standard 23 17 11 99 90)') cmakelists:print(' include(CheckCCompilerFlag)') - cmakelists:print(' if(CMAKE_COMPILER_ID STREQUAL \"MSVC\")') + cmakelists:print(' if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")') cmakelists:print(' check_c_compiler_flag("/std:%s${standard}" %s_support_%s_standard_${standard})', flag, target:name(), flag) cmakelists:print(' else()') cmakelists:print(' check_c_compiler_flag("-std=%s${standard}" %s_support_%s_standard_${standard})', flag, target:name(), flag) @@ -941,7 +947,7 @@ function _add_target_optimization(cmakelists, target) } local optimization = target:get("optimize") if optimization then - cmakelists:print("if(CMAKE_COMPILER_ID STREQUAL \"MSVC\")") + cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")") cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flags_msvc[optimization]) cmakelists:print("else()") cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flags_gcc[optimization]) @@ -969,7 +975,7 @@ function _add_target_symbols(cmakelists, target) if levels:has("hidden") then table.insert(flags_gcc, "-fvisibility=hidden") end - cmakelists:print("if(CMAKE_COMPILER_ID STREQUAL \"MSVC\")") + cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")") if #flags_msvc > 0 then cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), table.concat(flags_msvc, " ")) end @@ -990,7 +996,7 @@ function _add_target_runtimes(cmakelists, target) local cmake_minver = _get_cmake_minver() if cmake_minver:ge("3.15.0") then local runtimes = target:get("runtimes") - cmakelists:print("if(CMAKE_COMPILER_ID STREQUAL \"MSVC\")") + cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")") if runtimes then if runtimes == "MT" then runtimes = "MultiThreaded" @@ -1105,7 +1111,7 @@ function _add_target_link_directories(cmakelists, target, outputdir) end cmakelists:print(")") else - cmakelists:print("if(CMAKE_COMPILER_ID STREQUAL \"MSVC\")") + cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")") cmakelists:print(" target_link_libraries(%s PRIVATE", target:name()) for _, linkdir in ipairs(linkdirs) do cmakelists:print(" -libpath:" .. _get_relative_unix_path(linkdir, outputdir)) @@ -1172,7 +1178,7 @@ function _add_target_link_options(cmakelists, target, outputdir) for _, toolname in toolnames:keys() do local name = linkernames[toolname] if name then - cmakelists:print("if(CMAKE_COMPILER_ID STREQUAL \"%s\")", name) + cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"%s\")", name) _add_target_link_options_for_linker(toolname) cmakelists:print("endif()") end diff --git a/xmake/rules/c++/modules/builder.lua b/xmake/rules/c++/modules/builder.lua index 151c3ed9e..7237824b4 100644 --- a/xmake/rules/c++/modules/builder.lua +++ b/xmake/rules/c++/modules/builder.lua @@ -22,6 +22,7 @@ import("core.base.json") import("core.base.option") import("core.base.hashset") +import("core.base.profiler") import("async.runjobs") import("private.action.clean.remove_files") import("private.async.buildjobs") @@ -134,6 +135,7 @@ end -- should we build this module or headerunit ? function should_build(target, module) + profiler.enter(target:fullname(), "c++ modules", "builder", "check if " .. (module.name or module.sourcefile) .. " should be rebuilt") local memcache = support.memcache() local _should_build = memcache:get2(target:fullname(), "should_build_" .. module.sourcefile) if _should_build == nil then @@ -142,6 +144,7 @@ function should_build(target, module) if reused then local build = should_build(from, module) memcache:set2(target:fullname(), "should_build_" .. module.sourcefile, build) + profiler.leave(target:fullname(), "c++ modules", "builder", "check if " .. (module.name or module.sourcefile) .. " should be rebuilt") return build end local compinst = compiler.load("cxx", {target = target}) @@ -164,6 +167,7 @@ function should_build(target, module) if should_build(target, mapped_dep) then depend.save(dependinfo, dependfile) memcache:set2(target:fullname(), "should_build_" .. module.sourcefile, true) + profiler.leave(target:fullname(), "c++ modules", "builder", "check if " .. (module.name or module.sourcefile) .. " should be rebuilt") return true end end @@ -173,11 +177,14 @@ function should_build(target, module) if dryrun or depend.is_changed(old_dependinfo, dependinfo) then depend.save(dependinfo, dependfile) memcache:set2(target:fullname(), "should_build_" .. module.sourcefile, true) + profiler.leave(target:fullname(), "c++ modules", "builder", "check if " .. (module.name or module.sourcefile) .. " should be rebuilt") return true end memcache:set2(target:fullname(), "should_build_" .. module.sourcefile, false) + profiler.leave(target:fullname(), "c++ modules", "builder", "check if " .. (module.name or module.sourcefile) .. " should be rebuilt") return false end + profiler.leave(target:fullname(), "c++ modules", "builder", "check if " .. (module.name or module.sourcefile) .. " should be rebuilt") return _should_build end @@ -186,6 +193,7 @@ end -- it not build also objectfiles function build_modules_for_jobgraph(target, jobgraph, built_modules) + profiler.enter(target:fullname(), "c++ modules", "builder", "schedule module bmi build jobs") local builder = _builder(target) local has_two_phase_compilation_support = support.has_two_phase_compilation_support(target) local jobdeps = {} @@ -246,11 +254,13 @@ function build_modules_for_jobgraph(target, jobgraph, built_modules) jobgraph:add_orders(depname, jobname) end end + profiler.leave(target:fullname(), "c++ modules", "builder", "schedule module bmi build jobs") end -- build modules objectfiles for jobgraph if two phase compilation is supported function build_objectfiles_for_jobgraph(target, jobgraph, built_modules) + profiler.enter(target:fullname(), "c++ modules", "builder", "schedule module objectfiles build jobs") local builder = _builder(target) local has_two_phase_compilation_support = support.has_two_phase_compilation_support(target) local buildgroup = _get_module_buildgroup_for(target, "objectfile") @@ -278,6 +288,7 @@ function build_objectfiles_for_jobgraph(target, jobgraph, built_modules) end end end) + profiler.leave(target:fullname(), "c++ modules", "builder", "schedule module objectfiles build jobs") end -- build batchjobs for modules @@ -450,6 +461,7 @@ end -- build headerunits for jobgraph function build_headerunits_for_jobgraph(target, jobgraph, built_stlheaderunits, built_headerunits) + profiler.enter(target:fullname(), "c++ modules", "builder", "schedule headerunits build jobs") local builder = _builder(target) function make_headerunit_job(headerfile, opt) local reused, from = support.is_reused(target, headerfile) @@ -482,6 +494,7 @@ function build_headerunits_for_jobgraph(target, jobgraph, built_stlheaderunits, end end) end + profiler.leave(target:fullname(), "c++ modules", "builder", "schedule headerunits build jobs") end -- build headerunits for batchjobs @@ -548,6 +561,7 @@ function build_headerunits_for_batchcmds(target, batchcmds, built_stlheaderunits end function generate_metadata(target, modules) + profiler.enter(target:fullname(), "c++ modules", "builder", "generate module metadata") local public_modules for sourcefile, module in table.orderpairs(modules) do local fileconfig = target:fileconfig(sourcefile) @@ -559,6 +573,7 @@ function generate_metadata(target, modules) end if not public_modules then + profiler.leave(target:fullname(), "c++ modules", "builder", "generate module metadata") return end @@ -570,10 +585,12 @@ function generate_metadata(target, modules) local metadata = _generate_meta_module_info(target, module) json.savefile(metafilepath, metadata) end, {comax = jobs, total = #public_modules}) + profiler.leave(target:fullname(), "c++ modules", "builder", "generate module metadata") end -- check if dependencies changed function is_dependencies_changed(target, module) + profiler.enter(target:fullname(), "c++ modules", "builder", "check if dependency chain changed") local cachekey = target:fullname() .. (module.name or module.sourcefile) local requires = hashset.from(table.keys(module.deps or {})) local oldrequires = support.memcache():get2(cachekey, "oldrequires") @@ -590,6 +607,7 @@ function is_dependencies_changed(target, module) end end end + profiler.leave(target:fullname(), "c++ modules", "builder", "check if dependency chain changed") return requires, changed end @@ -643,6 +661,7 @@ function build_bmis(target, jobgraph, _, opt) if target:is_moduleonly() and not target:data("cxx.modules.reused") or target:is_phony() then return end + profiler.enter(target:fullname(), "c++ modules", "builder", "bmis") local modules = scanner.get_modules(target) -- avoid building non referenced modules local built_modules, built_headerunits, _ = scanner.sort_modules_by_dependencies(target, modules, {jobgraph = target:policy("build.jobgraph")}) @@ -679,6 +698,7 @@ function build_bmis(target, jobgraph, _, opt) else assert(false, "shouldn't be here :D") end + profiler.leave(target:fullname(), "c++ modules", "builder", "bmis") end end @@ -688,6 +708,7 @@ function build_objectfiles(target, jobgraph, _, opt) if target:is_moduleonly() and not target:data("cxx.modules.reused") or target:is_phony() then return end + profiler.enter(target:fullname(), "c++ modules", "builder", "objectfiles") local modules = scanner.get_modules(target) -- avoid building non referenced modules local built_modules, _, _ = scanner.sort_modules_by_dependencies(target, modules, {jobgraph = target:policy("build.jobgraph")}) @@ -711,6 +732,7 @@ function build_objectfiles(target, jobgraph, _, opt) else assert(false, "shouldn't be here :D") end + profiler.leave(target:fullname(), "c++ modules", "builder", "objectfiles") end end diff --git a/xmake/rules/c++/modules/scanner.lua b/xmake/rules/c++/modules/scanner.lua index 9c71fa035..3ce09e1bf 100644 --- a/xmake/rules/c++/modules/scanner.lua +++ b/xmake/rules/c++/modules/scanner.lua @@ -23,6 +23,7 @@ import("core.base.json") import("core.base.hashset") import("core.base.graph") import("core.base.option") +import("core.base.profiler") import("async.runjobs") import("support") import("mapper") @@ -32,8 +33,9 @@ function _scanner(target) return support.import_implementation_of(target, "scanner") end -function _parse_meta_info(metafile) +function _parse_meta_info(target, metafile) + profiler.enter(target:fullname(), "c++ modules", "scanner", "parse metainfo", metafile) local metadata = json.loadfile(metafile) if metadata.file and metadata.name then return metadata.file, metadata.name, metadata @@ -59,6 +61,7 @@ function _parse_meta_info(metafile) break end end + profiler.leave(target:fullname(), "c++ modules", "scanner", "parse metainfo", metafile) return filename, name, metadata end @@ -102,6 +105,7 @@ end }]] function _parse_dependencies_data(target, moduleinfos) + profiler.enter(target:fullname(), "c++ modules", "scanner", "parse modulescans") -- insert headerunit as moduleinfos local headerunitinfos = {} for _, moduleinfo in ipairs(moduleinfos) do @@ -189,12 +193,14 @@ function _parse_dependencies_data(target, moduleinfos) end end end + profiler.leave(target:fullname(), "c++ modules", "scanner", "parse modulescans") return modules, modules_names end -- generate edges for DAG function _get_edges(target, nodes, modules) + profiler.enter(target:fullname(), "c++ modules", "scanner", "get module dependency graph edges") local edges = {} local name_filemap = {} local deps_names = hashset.new() @@ -220,18 +226,20 @@ function _get_edges(target, nodes, modules) end end end + profiler.leave(target:fullname(), "c++ modules", "scanner", "get module dependency graph edges") return edges end -- get package modules function _get_package_modules(target, package, opt) + profiler.enter(target:fullname(), "c++ modules", "scanner", "get modules from package", package:name()) opt = opt or {} local package_modules local modulesdir = path.join(package:installdir(), "modules") local metafiles = os.files(path.join(modulesdir, "*", "*.meta-info")) for _, metafile in ipairs(metafiles) do package_modules = package_modules or {} - local modulefile, _, metadata = _parse_meta_info(metafile) + local modulefile, _, metadata = _parse_meta_info(target, metafile) local bmionly = package:libraryfiles() and true or false package_modules[path.join(modulesdir, modulefile)] = {defines = metadata.defines, @@ -239,6 +247,7 @@ function _get_package_modules(target, package, opt) bmionly = bmionly, external = opt.external and target:fullname()} end + profiler.leave(target:fullname(), "c++ modules", "scanner", "get modules from package", package:name()) return package_modules end @@ -258,6 +267,7 @@ end -- get packages modules function _get_packages_modules(target) + profiler.enter(target:fullname(), "c++ modules", "scanner", "get modules from package dependencies") -- parse all meta-info and append their informations to the package store local packages_modules = support.memcache():get2(target:fullname(), "cxx_packages_modules") if not packages_modules then @@ -272,12 +282,14 @@ function _get_packages_modules(target) end support.memcache():set2(target:fullname(), "cxx_packages_modules", packages_modules) end + profiler.leave(target:fullname(), "c++ modules", "get modules from package dependencies") return packages_modules end -- get target deps modules function _get_targetdeps_modules(target) + profiler.enter(target:fullname(), "c++ modules", "scanner", "get modules from target dependencies") local _, stdmodules_set = support.get_stdmodules(target) local modules for _, dep in ipairs(target:orderdeps()) do @@ -314,6 +326,7 @@ function _get_targetdeps_modules(target) end end end + profiler.leave(target:fullname(), "c++ modules", "scanner", "get modules from target dependencies") return modules end @@ -393,6 +406,7 @@ end function _do_parse(target, sourcebatch) + profiler.enter(target:fullname(), "c++ modules", "scanner", "parse module dependencies and compute dependency graph") local changed = support.memcache():get2(target:fullname(), "modules.changed") local modules if changed then @@ -447,18 +461,22 @@ function _do_parse(target, sourcebatch) -- sort modules sort_modules_by_dependencies(target, modules, {jobgraph = target:policy("build.jobgraph")}) + profiler.leave(target:fullname(), "c++ modules", "scanner", "parse module dependencies and compute dependency graph") end function _do_scan(target, sourcefile, opt) + profiler.enter(target:fullname(), "c++ modules", "scanner", "scan dependencies for", sourcefile) local changed = _scanner(target).scan_dependency_for(target, sourcefile, opt) if changed or not support.localcache():get2(target:fullname(), "module_mapper") then support.memcache():set2(target:fullname(), "modules.changed", true) end + profiler.leave(target:fullname(), "c++ modules", "scanner", "scan dependencies for", sourcefile) end -- scan module dependencies function _schedule_module_dependencies_scan(target, jobgraph, sourcebatch) + profiler.enter(target:fullname(), "c++ modules", "scanner", "schedule module dependencies scans") function get_basegroup_for(target) return target:fullname() .. "/modules" end @@ -524,10 +542,12 @@ function _schedule_module_dependencies_scan(target, jobgraph, sourcebatch) end end end + profiler.leave(target:fullname(), "c++ modules", "schedule module dependencies scans") end -- get headerunits info function sort_headerunits(target, headerunits) + profiler.enter(target:fullname(), "c++ modules", "scanner", "sort headerunits") local _headerunits local stl_headerunits for _, headerunit in ipairs(headerunits) do @@ -540,6 +560,7 @@ function sort_headerunits(target, headerunits) table.insert(_headerunits, headerunit) end end + profiler.leave(target:fullname(), "c++ modules", "scanner", "sort headerunits") return _headerunits, stl_headerunits end @@ -574,6 +595,7 @@ end }]] function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess_file) + profiler.enter(target:fullname(), "c++ modules", "fallback scanner", "scan module dependencies for", sourcefile) local output = {version = 1, revision = 0, rules = {}} local rule = {outputs = {jsonfile}} rule["primary-output"] = target:objectfile(sourcefile) @@ -648,11 +670,13 @@ function fallback_generate_dependencies(target, jsonfile, sourcefile, preprocess table.insert(output.rules, rule) local jsondata = json.encode(output) io.writefile(jsonfile, jsondata) + profiler.leave(target:fullname(), "c++ modules", "fallback scanner", "scan module dependencies for", sourcefile) end -- topological sort function sort_modules_by_dependencies(target, modules) + profiler.enter(target:fullname(), "c++ modules", "scanner", "compute module dependency dag") local memcache = support.memcache() local localcache = support.localcache() local changed = memcache:get2(target:fullname(), "modules.changed") @@ -774,6 +798,7 @@ function sort_modules_by_dependencies(target, modules) memcache:set2(target:fullname(), "modules.changed", false) end assert(built_artifacts, "shouldn't assert here, please open an issue") + profiler.leave(target:fullname(), "c++ modules", "scanner", "compute module dependency dag") return built_artifacts.modules, built_artifacts.headerunits, built_artifacts.objectfiles end @@ -811,9 +836,11 @@ function after_scan(target) end function main(target, jobgraph, sourcebatch) + profiler.enter(target:fullname(), "c++ modules", "scanner", "scan") local compile_commands = os.getenv("XMAKE_IN_PROJECT_GENERATOR") and os.getenv("XMAKE_IN_COMPILE_COMMANDS_PROJECT_GENERATOR") if target:data("cxx.has_modules") and (not os.getenv("XMAKE_IN_PROJECT_GENERATOR") or compile_commands) then _patch_sourcebatch(target, sourcebatch) _schedule_module_dependencies_scan(target, jobgraph, sourcebatch) end + profiler.leave(target:fullname(), "c++ modules", "scanner", "scan") end diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua index 8633c544c..52fe78d3e 100644 --- a/xmake/rules/c++/modules/xmake.lua +++ b/xmake/rules/c++/modules/xmake.lua @@ -36,6 +36,7 @@ rule("c++.build.modules") rule("c++.build.modules.scanner") set_sourcekinds("cxx", {objectfiles = false}) set_extensions(".cppm", ".ccm", ".cxxm", ".c++m", ".mpp", ".mxx", ".ixx") + on_prepare_files("scanner", {jobgraph = true}) after_prepare_files("scanner.after_scan") @@ -58,5 +59,6 @@ rule("c++.build.modules.builder") -- install modules rule("c++.build.modules.install") set_extensions(".cppm", ".ccm", ".cxxm", ".c++m", ".mpp", ".mxx", ".ixx") + before_install("install.install") before_uninstall("install.uninstall") diff --git a/xmake/rules/python/cython/xmake.lua b/xmake/rules/python/cython/xmake.lua new file mode 100644 index 000000000..02c73ff60 --- /dev/null +++ b/xmake/rules/python/cython/xmake.lua @@ -0,0 +1,62 @@ +--!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 Wu, Zhenyu +-- @file xmake.lua +-- + +rule("python.cython") + add_deps("python.module") + set_extensions(".py", ".pyx") + + on_load(function (target) + local language = target:extraconf("rules", "python.cython", "language") + if language == "c" then + target:add("deps", "c") + elseif language == "c++" then + target:add("deps", "c++") + end + end) + + before_buildcmd_file(function (target, batchcmds, sourcefile, opt) + import("lib.detect.find_tool") + + local cython = assert(find_tool("cython"), "cython not found! please `pip install cython`.") + local language = target:extraconf("rules", "python.cython", "language") + local ext = "c" + local arg = "-3" + if language == "c++" then + ext = "cc" + arg = arg .. "+" + end + local dirname = path.join(target:autogendir(), "rules", "python", "cython") + local sourcefile_c = path.join(dirname, path.basename(sourcefile) .. "." .. ext) + + -- add objectfile + local objectfile = target:objectfile(sourcefile_c) + table.insert(target:objectfiles(), objectfile) + + -- add commands + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.python %s", sourcefile) + batchcmds:mkdir(path.directory(sourcefile_c)) + batchcmds:vrunv(cython.program, {arg, "-o", path(sourcefile_c), path(sourcefile)}) + batchcmds:compile(sourcefile_c, objectfile) + + -- add deps + batchcmds:add_depfiles(sourcefile) + batchcmds:set_depmtime(os.mtime(objectfile)) + batchcmds:set_depcache(target:dependfile(objectfile)) + end) diff --git a/xmake/rules/python/library/xmake.lua b/xmake/rules/python/library/xmake.lua new file mode 100644 index 000000000..b587bb37e --- /dev/null +++ b/xmake/rules/python/library/xmake.lua @@ -0,0 +1,25 @@ +--!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 xmake.lua +-- + +rule("python.library") + on_config(function (target) + wprint('deprecated: please use add_rules("python.module") instead of add_rules("python.library")') + end) + add_deps("python.module") diff --git a/xmake/rules/python/xmake.lua b/xmake/rules/python/module/xmake.lua index 20c30c6b5..46d41be0b 100644 --- a/xmake/rules/python/xmake.lua +++ b/xmake/rules/python/module/xmake.lua @@ -19,13 +19,13 @@ -- -- @see https://github.com/xmake-io/xmake/issues/1896 -rule("python.library") +rule("python.module") on_config(function (target) target:set("kind", "shared") target:set("prefixname", "") target:add("runenvs", "PYTHONPATH", target:targetdir()) - local soabi = target:extraconf("rules", "python.library", "soabi") - if soabi then + local soabi = target:extraconf("rules", "python.module", "soabi") + if soabi == nil or soabi then import("lib.detect.find_tool") local python = assert(find_tool("python3"), "python not found!") local result = try { function() return os.iorunv(python.program, {"-c", "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"}) end} |
