premake-core icon indicating copy to clipboard operation
premake-core copied to clipboard

forced slash replacement

Open tbasnoopy opened this issue 10 years ago • 7 comments

prerequisites

premake5.lua

local qt_bin_path = "C:/dev/mx/v1/dep/qt/qt_33_x64_bin"

solution "myTestSln"
  location "testfiles/sln"

  platforms "x64"
  configurations "release"
  project "myTestPrj1"
    kind "Utility"
    files (qt_bin_path.."/bin/QtDeclarative_sofistik33_x64_4.dll")

    filter "files:**/*.dll"
      buildmessage ([[%{file.name} (copy)]])
      buildcommands [[xcopy /y "%{file.path:gsub("/","\\")}" "bla"]]
      buildoutputs ("bla")
    filter "*"

Problem The resulting path can be an absolute and all "" in the path are replaced by "/". There is - afaik - no possibility to change the slashes and not all Windows tools - like xcopy - can handle paths with "/".

Cause If premake is detecting absolute paths in non path variables, they are replaced by relative paths. This is not possible all the time (not sure but here can be a bug, too). It's never possible on Windows system where files are placed over different Partitions (C:; D:).

detoken.lua:66

local isAbs = path.isabsolute(result)
if isAbs and not field.paths and basedir then
  result = path.getrelative(basedir, result)
end

The path.getrelative function calls path.normalize which replaces all the "" to "/". This is not the system specification but required for further processing in premake.

path_normalize.c:30

if (ch == '\\') {
  ch = '/';
}

possible Solution Allow avoiding path fixing.

detoken.lua:66

local isAbs = path.isabsolute(result)
if type(result) == "string" and result:find("!$") then
  result = result:match("(.-)!$"):gsub("/","\\")
elseif isAbs and not field.paths and basedir then
  result = path.getrelative(basedir, result)
end

premake5.lua (part replacement)

buildcommands [[xcopy /y "%{file.path.."!"}" "bla"]]

Or is there a way I didn't see?

tbasnoopy avatar Apr 14 '15 10:04 tbasnoopy

A couple of things mixed up here; let's use this ticket to address the path separators and open another for the relative path logic if needed.

Premake specifies that all paths should use forward slashes, so let's take that as a given, and that path.normalize() is doing the right thing.

Translating separators in commands can sometimes be an issue even when you are not using tokens, e.g. trying to launch an executable on a relative path across different platforms. So ideally a more general solution would be best.

One solution similar to yours is to wrap it with a path.translate(), like your gsub(). We could make a shortcut for it and place it in the token environment, so maybe do something like:

buildcommands [[xcopy /y "%{T(file.path)}" "bla"]]

That helper could even have a bit of additional logic to try to determine which separator is appropriate for the target.

Makefiles are tricky because they can technically target multiple platforms now. But we can punt and just use the target OS until someone wants to tackle that fully.

starkos avatar Apr 14 '15 16:04 starkos

Oh, and an example of the relative executable would be

buildcommands [[%{T("../bin/cg")} "bla"]]

starkos avatar Apr 14 '15 16:04 starkos

No need for another ticket for relative path logic from my side.

How can we detect which separator is appropriate for the target platform?

I've written a short test:

function T(p)
  return p:gsub("/","\\")
end

buildcommands [[xcopy /y "%{T(file.path)}" "bla"]],

But this doesn't work. I didn't take an exact look on that but i think the same logic (detoken.lua:66) which breaks my gsub is breaking this, too.

If we want to avoid this issue we have to change this function (detoken.lua:66) in some way. But I think i do not understand how you think this should happen.

tbasnoopy avatar Apr 15 '15 07:04 tbasnoopy

How can we detect which separator is appropriate for the target platform?

os.is("windows") should do it.

I'm a little concerned about building this into the token expander since we don't necessarily know the context in which the path is being used? I don't have a great solution off the top of my head.

starkos avatar Apr 15 '15 18:04 starkos

xbox, xbox360, xbone all use windows slash too...

TurkeyMan avatar Apr 16 '15 02:04 TurkeyMan

I meant something like an cool api call: system_get_path_seperator. But I think there is no system comprehensive call.

@starkos : Which case could be a problem? In the most cases the path is good... or not. But I have not clue which cases can occur.

tbasnoopy avatar Apr 16 '15 07:04 tbasnoopy

https://premake.github.io/docs/Tokens/#path-in-commands %[..] handles path in commands string.

Jarod42 avatar Sep 04 '24 00:09 Jarod42