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%sBuildEvent>', 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
+