From c167aa90ca9a0000b7933a9df9306d18dee60f5c Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 29 Mar 2025 22:41:41 +0800 Subject: build binary --- xmake/actions/build/builtin/build_binary.lua | 127 ++++++++++++++++++++- xmake/actions/build/builtin/linkdepfiles.lua | 39 +++++++ xmake/actions/build/deprecated/kinds/binary.lua | 2 +- .../build/deprecated/kinds/linkdepfiles.lua | 39 ------- xmake/actions/build/deprecated/kinds/shared.lua | 2 +- xmake/actions/build/deprecated/kinds/static.lua | 2 +- 6 files changed, 167 insertions(+), 44 deletions(-) create mode 100644 xmake/actions/build/builtin/linkdepfiles.lua delete mode 100644 xmake/actions/build/deprecated/kinds/linkdepfiles.lua diff --git a/xmake/actions/build/builtin/build_binary.lua b/xmake/actions/build/builtin/build_binary.lua index 89c24a1e7..7b9b7d7b9 100644 --- a/xmake/actions/build/builtin/build_binary.lua +++ b/xmake/actions/build/builtin/build_binary.lua @@ -20,9 +20,132 @@ -- imports import("core.base.option") +import("core.theme.theme") +import("core.tool.linker") +import("core.tool.compiler") +import("core.project.depend") +import("utils.progress") +import("private.utils.batchcmds") +import("linkdepfiles", {alias = "get_linkdepfiles"}) import("build_object") +-- do link target +function _do_link_target(target, opt) + local linkinst = linker.load(target:kind(), target:sourcekinds(), {target = target}) + local linkflags = linkinst:linkflags({target = target}) + + -- need build this target? + local depfiles = get_linkdepfiles(target) + local dryrun = option.get("dry-run") + local depvalues = {linkinst:program(), linkflags} + depend.on_changed(function () + local filename = target:filename() + if target:namespace() then + filename = target:namespace() .. "::" .. filename + end + progress.show(opt.progress, "${color.build.target}linking.$(mode) %s", filename) + + local targetfile = target:targetfile() + local objectfiles = target:objectfiles() + local verbose = option.get("verbose") + if verbose then + -- show the full link command with raw arguments, it will expand @xxx.args for msvc/link on windows + print(linkinst:linkcmd(objectfiles, targetfile, {linkflags = linkflags, rawargs = true})) + end + + if not dryrun then + assert(linkinst:link(objectfiles, targetfile, {linkflags = linkflags})) + end + end, {dependfile = target:dependfile(), + lastmtime = os.mtime(target:targetfile()), + changed = target:is_rebuilt() or option.get("linkonly"), + values = depvalues, files = depfiles, dryrun = dryrun}) +end + +-- on link the given target +function _on_link_target(target, opt) + + -- link target with rules + local done = false + for _, r in ipairs(target:orderules()) do + local on_link = r:script("link") + if on_link then + on_link(target, opt) + done = true + end + local on_linkcmd = r:script("linkcmd") + if on_linkcmd then + local batchcmds_ = batchcmds.new({target = target}) + on_linkcmd(target, batchcmds_, {progress = opt.progress}) + batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + done = true + end + end + if done then return end + + -- do link + _do_link_target(target, opt) +end + +-- link target +function _link_target(target, opt) + + -- do before link for target + local before_link = target:script("link_before") + if before_link then + before_link(target, opt) + end + + -- do before link for rules + for _, r in ipairs(target:orderules()) do + local before_link = r:script("link_before") + if before_link then + before_link(target, opt) + end + local before_linkcmd = r:script("linkcmd_before") + if before_linkcmd then + local batchcmds_ = batchcmds.new({target = target}) + before_linkcmd(target, batchcmds_, {progress = opt.progress}) + batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + end + end + + -- on link + target:script("link", _on_link_target)(target, opt) + + -- do after link for target + local after_link = target:script("link_after") + if after_link then + after_link(target, opt) + end + + -- do after link for rules + for _, r in ipairs(target:orderules()) do + local after_link = r:script("link_after") + if after_link then + after_link(target, opt) + end + local after_linkcmd = r:script("linkcmd_after") + if after_linkcmd then + local batchcmds_ = batchcmds.new({target = target}) + after_linkcmd(target, batchcmds_, {progress = opt.progress}) + batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + end + end +end + + function main(jobgraph, target) - build_object(jobgraph, target) - -- TODO add link jobs + local objects_group = target:fullname() .. "/objects" + local jobsize = jobgraph:size() + jobgraph:group(objects_group, function () + build_object(jobgraph, target) + end) + if jobgraph:size() > jobsize then + local linkjob = target:fullname() .. "/link" + jobgraph:add(linkjob, function (index, total, opt) + _link_target(target, opt) + end) + jobgraph:add_orders(objects_group, linkjob) + end end diff --git a/xmake/actions/build/builtin/linkdepfiles.lua b/xmake/actions/build/builtin/linkdepfiles.lua new file mode 100644 index 000000000..f96e532fc --- /dev/null +++ b/xmake/actions/build/builtin/linkdepfiles.lua @@ -0,0 +1,39 @@ +--!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 linkdepfiles.lua +-- + +-- get link depfiles +function main(target) + local extrafiles = {} + for _, dep in ipairs(target:orderdeps()) do + if dep:kind() == "static" then + table.insert(extrafiles, dep:targetfile()) + end + end + local linkdepfiles = target:data("linkdepfiles") + if linkdepfiles then + table.join2(extrafiles, linkdepfiles) + end + local objectfiles = target:objectfiles() + local depfiles = objectfiles + if #extrafiles > 0 then + depfiles = table.join(objectfiles, extrafiles) + end + return depfiles +end diff --git a/xmake/actions/build/deprecated/kinds/binary.lua b/xmake/actions/build/deprecated/kinds/binary.lua index 3f67232f7..fddc4c8bf 100644 --- a/xmake/actions/build/deprecated/kinds/binary.lua +++ b/xmake/actions/build/deprecated/kinds/binary.lua @@ -27,7 +27,7 @@ import("core.project.depend") import("utils.progress") import("private.utils.batchcmds") import("object", {alias = "object_target"}) -import("linkdepfiles", {alias = "get_linkdepfiles"}) +import("..builtin.linkdepfiles", {alias = "get_linkdepfiles"}) -- do link target function _do_link_target(target, opt) diff --git a/xmake/actions/build/deprecated/kinds/linkdepfiles.lua b/xmake/actions/build/deprecated/kinds/linkdepfiles.lua deleted file mode 100644 index f96e532fc..000000000 --- a/xmake/actions/build/deprecated/kinds/linkdepfiles.lua +++ /dev/null @@ -1,39 +0,0 @@ ---!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 linkdepfiles.lua --- - --- get link depfiles -function main(target) - local extrafiles = {} - for _, dep in ipairs(target:orderdeps()) do - if dep:kind() == "static" then - table.insert(extrafiles, dep:targetfile()) - end - end - local linkdepfiles = target:data("linkdepfiles") - if linkdepfiles then - table.join2(extrafiles, linkdepfiles) - end - local objectfiles = target:objectfiles() - local depfiles = objectfiles - if #extrafiles > 0 then - depfiles = table.join(objectfiles, extrafiles) - end - return depfiles -end diff --git a/xmake/actions/build/deprecated/kinds/shared.lua b/xmake/actions/build/deprecated/kinds/shared.lua index cc7aa010c..2b53e98e8 100644 --- a/xmake/actions/build/deprecated/kinds/shared.lua +++ b/xmake/actions/build/deprecated/kinds/shared.lua @@ -27,7 +27,7 @@ import("core.project.depend") import("utils.progress") import("private.utils.batchcmds") import("object", {alias = "object_target"}) -import("linkdepfiles", {alias = "get_linkdepfiles"}) +import("..builtin.linkdepfiles", {alias = "get_linkdepfiles"}) -- do link target function _do_link_target(target, opt) diff --git a/xmake/actions/build/deprecated/kinds/static.lua b/xmake/actions/build/deprecated/kinds/static.lua index abb6c5f72..21fc253b5 100644 --- a/xmake/actions/build/deprecated/kinds/static.lua +++ b/xmake/actions/build/deprecated/kinds/static.lua @@ -27,7 +27,7 @@ import("core.project.depend") import("utils.progress") import("private.utils.batchcmds") import("object", {alias = "object_target"}) -import("linkdepfiles", {alias = "get_linkdepfiles"}) +import("..builtin.linkdepfiles", {alias = "get_linkdepfiles"}) -- do link target function _do_link_target(target, opt) -- cgit v1.3.1