summaryrefslogtreecommitdiff
path: root/xmake/plugins/project/make/makefile.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2023-04-27 00:32:09 +0800
committerruki <[email protected]>2023-04-27 00:32:09 +0800
commite183cdf902e4779185967cf1796a0c485ec15840 (patch)
treed0239dbdf10916f815c3296e234fe7b2b15707e8 /xmake/plugins/project/make/makefile.lua
parent0086252ba8c687e528b8172c34c874af41dc21f7 (diff)
improve makefile to support cmds
Diffstat (limited to 'xmake/plugins/project/make/makefile.lua')
-rw-r--r--xmake/plugins/project/make/makefile.lua198
1 files changed, 147 insertions, 51 deletions
diff --git a/xmake/plugins/project/make/makefile.lua b/xmake/plugins/project/make/makefile.lua
index 4cea85d15..eb7324bb1 100644
--- a/xmake/plugins/project/make/makefile.lua
+++ b/xmake/plugins/project/make/makefile.lua
@@ -19,12 +19,16 @@
--
-- imports
+import("core.base.colors")
import("core.tool.compiler")
import("core.project.config")
import("core.project.project")
import("core.language.language")
import("core.platform.platform")
import("lib.detect.find_tool")
+import("private.utils.batchcmds")
+import("private.utils.rule_groups")
+import("plugins.project.utils.target_cmds", {rootdir = os.programdir()})
-- tranlate path
function _translate_path(filepath, outputdir)
@@ -49,34 +53,48 @@ function _get_relative_unix_path(filepath, outputdir)
return os.args(filepath)
end
--- translate compiler flags
-function _translate_compflags(compflags, outputdir)
- local flags = {}
- for _, flag in ipairs(compflags) do
- for _, pattern in ipairs({"[%-](I)(.*)", "[%-](isystem)(.*)"}) do
- flag = flag:gsub(pattern, function (flag, dir)
- dir = _get_relative_unix_path(dir, outputdir)
- return "-" .. flag .. dir
- end)
+-- translate flag
+function _translate_flag(flag, outputdir)
+ if flag then
+ if path.instance_of(flag) then
+ flag = flag:clone():set(_get_relative_unix_path(flag:rawstr(), outputdir)):str()
+ elseif path.is_absolute(flag) then
+ flag = _get_relative_unix_path(flag, outputdir)
+ elseif flag:startswith("-fmodule-file=") then
+ flag = "-fmodule-file=" .. _get_relative_unix_path(flag:sub(15), outputdir)
+ elseif flag:startswith("-fmodule-mapper=") then
+ flag = "-fmodule-mapper=" .. _get_relative_unix_path(flag:sub(17), outputdir)
+ elseif flag:startswith("-isystem") and #flag > 8 then
+ flag = "-isystem" .. _get_relative_unix_path(flag:sub(9), outputdir)
+ elseif flag:startswith("-I") and #flag > 2 then
+ flag = "-I" .. _get_relative_unix_path(flag:sub(3), outputdir)
+ elseif flag:startswith("-L") and #flag > 2 then
+ flag = "-L" .. _get_relative_unix_path(flag:sub(3), outputdir)
+ elseif flag:startswith("-F") and #flag > 2 then
+ flag = "-F" .. _get_relative_unix_path(flag:sub(3), outputdir)
+ elseif flag:match("(.+)=(.+)") then
+ local k, v = flag:match("(.+)=(.+)")
+ if v and v:endswith(".ifc") then -- e.g. hello=xxx/hello.ifc
+ flag = k .. "=" .. _get_relative_unix_path(v, outputdir)
+ end
end
- table.insert(flags, flag)
end
- return flags
+ return flag
end
--- translate linker flags
-function _translate_linkflags(linkflags, outputdir)
- local flags = {}
- for _, flag in ipairs(linkflags) do
- for _, pattern in ipairs({"[%-](L)(.*)", "[%-](F)(.*)"}) do
- flag = flag:gsub(pattern, function (flag, dir)
- dir = _get_relative_unix_path(dir, outputdir)
- return "-" .. flag .. dir
- end)
+-- translate flags
+function _translate_flags(flags, outputdir)
+ local result = {}
+ for _, flag in ipairs(flags) do
+ if type(flag) == "table" and not path.instance_of(flag) then
+ for _, v in ipairs(flag) do
+ table.insert(result, _translate_flag(v, outputdir))
+ end
+ else
+ table.insert(result, _translate_flag(flag, outputdir))
end
- table.insert(flags, flag)
end
- return flags
+ return result
end
-- get program from target toolchains
@@ -141,31 +159,83 @@ function _get_common_flags(target, sourcekind, sourcebatch)
return commonflags, sourceflags_
end
--- mkdir directory
-function _add_create_directory(makefile, dir)
+-- get command: mkdir
+function _get_cmd_mkdir(dir)
+ if is_subhost("windows") then
+ return string.format("-@mkdir %s > NUL 2>&1", dir)
+ else
+ return string.format("@mkdir -p %s", dir)
+ end
+end
+
+-- get command: cp
+function _get_cmd_cp(sourcefile, targetfile)
if is_subhost("windows") then
- makefile:print("\t-@mkdir %s > NUL 2>&1", dir)
+ return string.format("@copy /Y %s %s > NUL 2>&1", sourcefile, targetfile)
else
- makefile:print("\t@mkdir -p %s", dir)
+ return string.format("@cp %s %s", sourcefile, targetfile)
end
end
--- copy file
-function _add_copy_file(makefile, sourcefile, targetfile)
+-- get command: mv
+function _get_cmd_mv(sourcefile, targetfile)
if is_subhost("windows") then
- makefile:print("\t@copy /Y %s %s > NUL 2>&1", sourcefile, targetfile)
+ return string.format("@ren %s %s > NUL 2>&1", sourcefile, targetfile)
else
- makefile:print("\t@cp %s %s", sourcefile, targetfile)
+ return string.format("@mv %s %s", sourcefile, targetfile)
end
end
--- try to remove the given file or directory
-function _add_remove_file(makefile, filedir)
+-- get command: cpdir
+function _get_cmd_cpdir(sourcedir, targetdir)
+ if is_subhost("windows") then
+ return string.format("@copy /Y %s %s > NUL 2>&1", sourcedir, targetdir)
+ else
+ return string.format("@cp -r %s %s", sourcedir, targetdir)
+ end
+end
+
+-- get command: rm
+function _get_cmd_rm(filedir)
if is_subhost("windows") then
-- we attempt to delete it as file first, we remove it as directory if failed
- makefile:print("\t@del /F /Q %s > NUL 2>&1 || rmdir /S /Q %s > NUL 2>&1", filedir, filedir)
+ return string.format("@del /F /Q %s > NUL 2>&1 || rmdir /S /Q %s > NUL 2>&1", filedir, filedir)
else
- makefile:print("\t@rm -rf %s", filedir)
+ return string.format("@rm -rf %s", filedir)
+ end
+end
+
+-- get command string
+function _get_command_string(cmd, outputdir)
+ local kind = cmd.kind
+ local opt = cmd.opt
+ if cmd.program then
+ -- @see https://github.com/xmake-io/xmake/discussions/2156
+ local argv = {}
+ for _, v in ipairs(cmd.argv) do
+ table.insert(argv, _translate_flag(v, outputdir))
+ end
+ local command = _get_relative_unix_path(cmd.program) .. " " .. os.args(argv)
+ if opt and opt.curdir then
+ wprint("curdir has been not supported in batchcmds:execv() for makefile generator!")
+ end
+ return command
+ elseif kind == "cp" then
+ if os.isdir(cmd.srcpath) then
+ return _get_cmd_cpdir(get_relative_unix_path(cmd.srcpath, outputdir), _get_relative_unix_path(cmd.dstpath, outputdir))
+ else
+ return _get_cmd_cp(_get_relative_unix_path(cmd.srcpath, outputdir), _get_relative_unix_path(cmd.dstpath, outputdir))
+ end
+ elseif kind == "rm" then
+ return _get_cmd_rm(_get_relative_unix_path(cmd.filepath, outputdir))
+ elseif kind == "mv" then
+ return _get_cmd_mv(_get_relative_unix_path(cmd.srcpath, outputdir), _get_relative_unix_path(cmd.dstpath, outputdir))
+ elseif kind == "cd" then
+ return string.format("cd %s", _get_relative_unix_path(cmd.dir, outputdir))
+ elseif kind == "mkdir" then
+ return _get_cmd_mkdir(_get_relative_unix_path(cmd.dir, outputdir))
+ elseif kind == "show" then
+ return string.format("echo %s", colors.ignore(cmd.showtext))
end
end
@@ -173,7 +243,7 @@ end
function _add_remove_files(makefile, filedirs, outputdir)
for _, filedir in ipairs(filedirs) do
filedir = _get_relative_unix_path(filedir, outputdir)
- _add_remove_file(makefile, filedir, outputdir)
+ makefile:print("\t%s", _get_cmd_rm(filedir))
end
end
@@ -259,11 +329,11 @@ function _add_flags(makefile, targetflags, outputdir)
local sourcekind = sourcebatch.sourcekind
if sourcekind then
local commonflags, sourceflags = _get_common_flags(target, sourcekind, sourcebatch)
- makefile:print("%s_%sFLAGS=%s", targetname, sourcekind:upper(), os.args(_translate_compflags(commonflags, outputdir)))
+ makefile:print("%s_%sFLAGS=%s", targetname, sourcekind:upper(), os.args(_translate_flags(commonflags, outputdir)))
targetflags[targetname .. '_' .. sourcekind:upper()] = sourceflags
end
end
- makefile:print("%s_%sFLAGS=%s", targetname, target:linker():kind():upper(), os.args(_translate_linkflags(target:linkflags(), outputdir)))
+ makefile:print("%s_%sFLAGS=%s", targetname, target:linker():kind():upper(), os.args(_translate_flags(target:linkflags(), outputdir)))
end
end
makefile:print("")
@@ -284,7 +354,7 @@ function _add_build_object(makefile, target, sourcefile, objectfile, sourceflags
end
-- get complier flags
- local compflags = _translate_compflags(sourceflags[sourcefile], outputdir)
+ local compflags = _translate_flags(sourceflags[sourcefile], outputdir)
-- translate file paths
sourcefile = _get_relative_unix_path(sourcefile, outputdir)
@@ -329,7 +399,7 @@ function _add_build_object(makefile, target, sourcefile, objectfile, sourceflags
-- make body
makefile:print("\t@echo %scompiling.$(mode) %s", ccache and "ccache " or "", sourcefile)
- _add_create_directory(makefile, path.directory(objectfile))
+ makefile:print("\t%s", _get_cmd_mkdir(path.directory(objectfile)))
makefile:writef("\t$(VV)%s\n", command)
-- make tail
@@ -366,20 +436,43 @@ function _add_build_phony(makefile, target)
end
-- add custom commands before building target
-function _add_build_target_custom_commands_before(makefile, target, outputdir)
+function _add_build_custom_commands_before(makefile, target, sourcegroups, outputdir)
+
+ -- add before commands
+ -- we use irpairs(groups), because the last group that should be given the highest priority.
+ local cmds_before = {}
+ target_cmds.get_target_buildcmd(target, cmds_before, "before")
+ target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups, "before")
+ target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups)
+
local targetname = target:name()
local label = "precmds_" .. targetname
-
- makefile:print("%s:", label)
- makefile:print("\techo hello %s", targetname)
- makefile:print("")
- return label
+ if #cmds_before > 0 then
+ makefile:print("%s:", label)
+ for _, cmd in ipairs(cmds_before) do
+ local command = _get_command_string(cmd, outputdir)
+ if command then
+ makefile:print("\t%s", command)
+ end
+ end
+ makefile:print("")
+ return label
+ end
end
-- add custom commands after building target
-function _add_build_target_custom_commands_after(makefile, target, outputdir)
- local targetname = target:name()
- makefile:print("\techo hello %s", targetname)
+function _add_build_custom_commands_after(makefile, target, sourcegroups, outputdir)
+ local cmds_after = {}
+ target_cmds.get_target_buildcmd_sourcegroups(target, cmds_after, sourcegroups, "after")
+ target_cmds.get_target_buildcmd(target, cmds_after, "after")
+ if #cmds_after > 0 then
+ for _, cmd in ipairs(cmds_after) do
+ local command = _get_command_string(cmd, outputdir)
+ if command then
+ makefile:print("\t%s", command)
+ end
+ end
+ end
end
-- add build target
@@ -388,8 +481,11 @@ function _add_build_target(makefile, target, targetflags, outputdir)
-- https://github.com/xmake-io/xmake/issues/2337
target:data_set("plugin.project.kind", "makefile")
+ -- build sourcebatch groups first
+ local sourcegroups = rule_groups.build_sourcebatch_groups(target, target:sourcebatches())
+
-- add custom commands before building target
- local precmds_label = _add_build_target_custom_commands_before(makefile, target, outputdir)
+ local precmds_label = _add_build_custom_commands_before(makefile, target, sourcegroups, outputdir)
-- is phony target?
if target:is_phony() then
@@ -469,11 +565,11 @@ function _add_build_target(makefile, target, targetflags, outputdir)
-- make body
makefile:print("\t@echo linking.$(mode) %s", path.filename(targetfile))
- _add_create_directory(makefile, path.directory(targetfile))
+ makefile:print("\t%s", _get_cmd_mkdir(path.directory(targetfile)))
makefile:writef("\t$(VV)%s\n", command)
-- add custom commands after building target
- _add_build_target_custom_commands_after(makefile, target, outputdir)
+ _add_build_custom_commands_after(makefile, target, sourcegroups, outputdir)
-- end
makefile:print("")