diff --git a/src/actions/make/_make.lua b/src/actions/make/_make.lua index d9c5d85b..585fa913 100644 --- a/src/actions/make/_make.lua +++ b/src/actions/make/_make.lua @@ -256,7 +256,7 @@ local steps = cfg[event .. "commands"] local msg = cfg[event .. "message"] if #steps > 0 then - steps = os.translateCommands(steps) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) msg = msg or string.format("Running %s commands", event) _p('\t@echo %s', msg) _p('\t%s', table.implode(steps, "", "", "\n\t")) diff --git a/src/actions/make/make_cpp.lua b/src/actions/make/make_cpp.lua index fb3a227f..aa3cb432 100644 --- a/src/actions/make/make_cpp.lua +++ b/src/actions/make/make_cpp.lua @@ -178,7 +178,7 @@ _p('%s: %s', output, dependencies) _p('\t@echo "%s"', filecfg.buildmessage or ("Building " .. filecfg.relpath)) - local cmds = os.translateCommands(filecfg.buildcommands) + local cmds = os.translateCommandsAndPaths(filecfg.buildcommands, cfg.project.basedir, cfg.project.location) for _, cmd in ipairs(cmds) do if cfg.bindirs and #cfg.bindirs > 0 then _p('\t$(SILENT) $(EXE_PATHS) %s', cmd) diff --git a/src/actions/make/make_makefile.lua b/src/actions/make/make_makefile.lua index 739995b0..e5c67bcd 100644 --- a/src/actions/make/make_makefile.lua +++ b/src/actions/make/make_makefile.lua @@ -72,7 +72,7 @@ _p(' define BUILDCMDS') local steps = cfg.buildcommands if #steps > 0 then - steps = os.translateCommands(steps) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) _p('\t@echo Running build commands') _p('\t%s', table.implode(steps, "", "", "\n\t")) end @@ -84,7 +84,7 @@ _p(' define CLEANCMDS') local steps = cfg.cleancommands if #steps > 0 then - steps = os.translateCommands(steps) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) _p('\t@echo Running clean commands') _p('\t%s', table.implode(steps, "", "", "\n\t")) end diff --git a/src/actions/vstudio/vs2005_csproj.lua b/src/actions/vstudio/vs2005_csproj.lua index b6d5ab01..0ce1c3f4 100644 --- a/src/actions/vstudio/vs2005_csproj.lua +++ b/src/actions/vstudio/vs2005_csproj.lua @@ -226,7 +226,7 @@ function cs2005.buildEvents(prj) local function output(name, steps) if #steps > 0 then - steps = os.translateCommands(steps, p.WINDOWS) + steps = os.translateCommandsAndPaths(steps, prj.basedir, prj.location) steps = table.implode(steps, "", "", "\r\n") _x(2,'<%sBuildEvent>%s', name, steps, name) end diff --git a/src/actions/vstudio/vs200x_vcproj.lua b/src/actions/vstudio/vs200x_vcproj.lua index 478b0697..e7762ded 100644 --- a/src/actions/vstudio/vs200x_vcproj.lua +++ b/src/actions/vstudio/vs200x_vcproj.lua @@ -945,7 +945,7 @@ function m.buildCommandLine(cfg) - local cmds = os.translateCommands(cfg.buildcommands, p.WINDOWS) + local cmds = os.translateCommandsAndPaths(cfg.buildcommands, cfg.project.basedir, cfg.project.location) p.x('BuildCommandLine="%s"', table.concat(cmds, "\r\n")) end @@ -960,7 +960,7 @@ function m.cleanCommandLine(cfg) - local cmds = os.translateCommands(cfg.cleancommands, p.WINDOWS) + local cmds = os.translateCommandsAndPaths(cfg.cleancommands, cfg.project.basedir, cfg.project.location) cmds = table.concat(cmds, "\r\n") p.x('CleanCommandLine="%s"', cmds) end @@ -975,7 +975,7 @@ if msg then p.x('Description="%s"', msg) end - steps = os.translateCommands(steps, p.WINDOWS) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) p.x('CommandLine="%s"', table.implode(steps, "", "", "\r\n")) end end @@ -1045,7 +1045,7 @@ function m.customBuildTool(cfg) local cfg, filecfg = config.normalize(cfg) if filecfg and fileconfig.hasCustomBuildRule(filecfg) then - local cmds = os.translateCommands(filecfg.buildcommands, p.WINDOWS) + local cmds = os.translateCommandsAndPaths(filecfg.buildcommands, filecfg.project.basedir, filecfg.project.location) p.x('CommandLine="%s"', table.concat(cmds,'\r\n')) local outputs = project.getrelative(filecfg.project, filecfg.buildoutputs) diff --git a/src/actions/vstudio/vs2010_vcxproj.lua b/src/actions/vstudio/vs2010_vcxproj.lua index 0d32112a..f9ec67f3 100644 --- a/src/actions/vstudio/vs2010_vcxproj.lua +++ b/src/actions/vstudio/vs2010_vcxproj.lua @@ -511,7 +511,7 @@ local msg = cfg[field .. "message"] if #steps > 0 then - steps = os.translateCommands(steps, p.WINDOWS) + steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location) p.push('<%s>', name) p.x('%s', table.implode(steps, "", "", "\r\n")) if msg then @@ -1131,7 +1131,7 @@ function m.buildCommands(fcfg, condition) - local commands = os.translateCommands(fcfg.buildcommands, p.WINDOWS) + local commands = os.translateCommandsAndPaths(fcfg.buildcommands, fcfg.project.basedir, fcfg.project.location) commands = table.concat(commands,'\r\n') m.element("Command", condition, '%s', commands) end @@ -1768,7 +1768,7 @@ function m.nmakeCommandLine(cfg, commands, phase) if #commands > 0 then - commands = os.translateCommands(commands, p.WINDOWS) + commands = os.translateCommandsAndPaths(commands, cfg.project.basedir, cfg.project.location) commands = table.concat(p.esc(commands), p.eol()) p.w('%s', phase, commands, phase) end diff --git a/src/base/os.lua b/src/base/os.lua index 43ed5f6d..2ac7c323 100644 --- a/src/base/os.lua +++ b/src/base/os.lua @@ -610,6 +610,47 @@ +--- +-- Translate decorated command paths into their OS equivalents. +--- + + function os.translateCommandsAndPaths(cmds, basedir, location, map) + local translatedBaseDir = path.getrelative(location, basedir) + + map = map or os.target() + + local translateFunction = function(value) + local result = path.join(translatedBaseDir, value) + if value:endswith('/') or value:endswith('\\') or + value:endswith('/"') or value:endswith('\\"') then + result = result .. '/' + end + if map == 'windows' then + result = path.translate(result) + end + return result + end + + local processOne = function(cmd) + local replaceFunction = function(value) + value = value:sub(3, #value - 1) + return '"' .. translateFunction(value) .. '"' + end + return string.gsub(cmd, "%%%[[^%]\r\n]*%]", replaceFunction) + end + + if type(cmds) == "table" then + local result = {} + for i = 1, #cmds do + result[i] = processOne(cmds[i]) + end + return os.translateCommands(result, map) + else + return os.translateCommands(processOne(cmds), map) + end + end + + -- -- Generate a UUID. -- diff --git a/tests/base/test_os.lua b/tests/base/test_os.lua index f2414b95..ce5222db 100644 --- a/tests/base/test_os.lua +++ b/tests/base/test_os.lua @@ -281,3 +281,22 @@ local version = os.getversion(); test.istrue(version ~= nil) end + + + +-- +-- os.translateCommandsAndPaths. +-- + + function suite.translateCommandsAndPaths() + test.isequal('cmdtool "../foo/path1"', os.translateCommandsAndPaths("cmdtool %[path1]", '../foo', '.', 'osx')) + end + + function suite.translateCommandsAndPaths_PreserveSlash() + test.isequal('cmdtool "../foo/path1/"', os.translateCommandsAndPaths("cmdtool %[path1/]", '../foo', '.', 'osx')) + end + + function suite.translateCommandsAndPaths_MultipleTokens() + test.isequal('cmdtool "../foo/path1" "../foo/path2/"', os.translateCommandsAndPaths("cmdtool %[path1] %[path2/]", '../foo', '.', 'osx')) + end +