premake / premake-core

Premake
https://premake.github.io/
BSD 3-Clause "New" or "Revised" License
3.24k stars 617 forks source link

cfg.buildtarget tokens incorrect in postbuildcommands #2248

Open richard-sim opened 2 months ago

richard-sim commented 2 months ago

What seems to be the problem? The various cfg.buildtarget tokens appear to be incorrect in postbuildcommands.

The complete (dummy) project I'm using for learning Premake demonstrates the bug: https://github.com/richard-sim/build-sys-eval/blob/248c0abae20a8509e0d8eb63e435fa3925e3cb06/foobar/src/premake5.lua#L62

postbuildcommands {
    "{ECHO} %{prj.name} cfg.buildtarget.directory: %[%{cfg.buildtarget.directory}]",
    "{ECHO} %{prj.name} cfg.buildtarget.relpath: %[%{cfg.buildtarget.relpath}]",
    "{ECHO} %{prj.name} !cfg.buildtarget.relpath: %[%{!cfg.buildtarget.relpath}]",
    "{ECHO} %{prj.name} cfg.buildtarget.abspath: %[%{cfg.buildtarget.abspath}]",
    "{ECHO} %{prj.name} !cfg.buildtarget.abspath: %[%{!cfg.buildtarget.abspath}]",
    "{ECHO} %{prj.name} cfg.buildtarget.name: %[%{cfg.buildtarget.name}]",
    "{ECHO} %{prj.name} cfg.buildtarget.basename: %[%{cfg.buildtarget.basename}]",
    "{ECHO} %{prj.name} cfg.buildtarget.extension: %[%{cfg.buildtarget.extension}]"
}

output:

L3a.vcxproj -> D:\dev\build-sys-eval\foobar\src\.build\bin\windows-x86_64-debug\L3a\L3a.exe
L3a cfg.buildtarget.directory: "D:\dev\build-sys-eval\foobar\src\.build\bin\windows-x86_64-debug\L3a\"
L3a cfg.buildtarget.relpath: "..\bin\windows-x86_64-debug\L3a\L3a.exe"
L3a !cfg.buildtarget.relpath: "..\bin\windows-x86_64-debug\L3a\L3a.exe"
L3a cfg.buildtarget.abspath: "..\bin\windows-x86_64-debug\L3a\L3a.exe"
L3a !cfg.buildtarget.abspath: "bin\windows-x86_64-debug\L3a\L3a.exe"
L3a cfg.buildtarget.name: "L3a.exe"
L3a cfg.buildtarget.basename: "L3a"
L3a cfg.buildtarget.extension: "..\.exe"

Partial directory structure:

foobar/
    src/
        .build/ <-- workspace location
            bin/ <-- workspace targetdir
                <per-config name>/
                    L3a/ <-- project's outputs
            obj/ <-- workspace objdir
                <per-config name>/
                    L3a/ <-- project's object files
        foobar/
            L3a/
                premake5.lua
        premake5.lua

What did you expect to happen?

What have you tried so far? I'm using %[%{cfg.buildtarget.directory}%{cfg.buildtarget.basename}.ext], which while is an absolute path, is fine for my needs.

How can we reproduce this? This bare-bones repo can be cloned: https://github.com/richard-sim/build-sys-eval/blob/248c0abae20a8509e0d8eb63e435fa3925e3cb06/foobar/src/premake5.lua#L62

What version of Premake are you using? Latest master branch.

Anything else we should know? I'm new here. :)

Jarod42 commented 2 months ago

%[..] makes path relative and usable for generated solution, so generally make the path relative to generated project. %{!cfg.buildtarget.abspath} (without enclosing %[..]) would be shown absolute.

Even some relative paths are returned as absolute and transformed into relative path "later" (as in includedirs "%{cfg.xx}/{cfg.yy}") So %{cfg.buildtarget.relpath} might show relative or absolute path (I don't remember) Even for some paths and some generators, there are transformed into special token (as $(SolutionDir)).

I'm using %[%{cfg.buildtarget.directory}%{cfg.buildtarget.basename}.ext], which while is an absolute path, is fine for my needs.

I'm expecting resulting path is relative. But at least it is working :-) as explained in path in commands

richard-sim commented 2 months ago

as explained in path in commands

I read that, which is why I was using %[]. To quote that page (ouch, spelling):

When you specify a path inside a commands, you have to wrap path insice %[] to allow correct trnasformation for the generator.

That, to me, says that the %[] is necessary, period - not necessary for only some desired outcome.

I've expanded the postbuildcommands to this:

"{ECHO} %{prj.name} [cfg.buildtarget.directory]: %[%{cfg.buildtarget.directory}]",
"{ECHO} %{prj.name} cfg.buildtarget.directory: %{cfg.buildtarget.directory}",
"{ECHO} %{prj.name} [cfg.buildtarget.relpath]: %[%{cfg.buildtarget.relpath}]",
"{ECHO} %{prj.name} cfg.buildtarget.relpath: %{cfg.buildtarget.relpath}",
"{ECHO} %{prj.name} [!cfg.buildtarget.relpath]: %[%{!cfg.buildtarget.relpath}]",
"{ECHO} %{prj.name} !cfg.buildtarget.relpath: %{!cfg.buildtarget.relpath}",
"{ECHO} %{prj.name} [cfg.buildtarget.abspath]: %[%{cfg.buildtarget.abspath}]",
"{ECHO} %{prj.name} cfg.buildtarget.abspath: %{cfg.buildtarget.abspath}",
"{ECHO} %{prj.name} [!cfg.buildtarget.abspath]: %[%{!cfg.buildtarget.abspath}]",
"{ECHO} %{prj.name} !cfg.buildtarget.abspath: %{!cfg.buildtarget.abspath}",
"{ECHO} %{prj.name} [cfg.buildtarget.name]: %[%{cfg.buildtarget.name}]",
"{ECHO} %{prj.name} cfg.buildtarget.name: %{cfg.buildtarget.name}",
"{ECHO} %{prj.name} [cfg.buildtarget.basename]: %[%{cfg.buildtarget.basename}]",
"{ECHO} %{prj.name} cfg.buildtarget.basename: %{cfg.buildtarget.basename}",
"{ECHO} %{prj.name} [cfg.buildtarget.extension]: %[%{cfg.buildtarget.extension}]",
"{ECHO} %{prj.name} cfg.buildtarget.extension: %{cfg.buildtarget.extension}",

which results in this in the generated vcxproj file:

echo $(ProjectName) [cfg.buildtarget.directory]: "$(TargetDir)"
echo $(ProjectName) cfg.buildtarget.directory: $(TargetDir)
echo $(ProjectName) [cfg.buildtarget.relpath]: "..\bin\windows-x86_64-release\L0a\L0a.dll"
echo $(ProjectName) cfg.buildtarget.relpath: bin/windows-x86_64-release/L0a/L0a.dll
echo $(ProjectName) [!cfg.buildtarget.relpath]: "..\bin\windows-x86_64-release\L0a\L0a.dll"
echo $(ProjectName) !cfg.buildtarget.relpath: bin/windows-x86_64-release/L0a/L0a.dll
echo $(ProjectName) [cfg.buildtarget.abspath]: "..\bin\windows-x86_64-release\L0a\L0a.dll"
echo $(ProjectName) cfg.buildtarget.abspath: bin/windows-x86_64-release/L0a/L0a.dll
echo $(ProjectName) [!cfg.buildtarget.abspath]: "bin\windows-x86_64-release\L0a\L0a.dll"
echo $(ProjectName) !cfg.buildtarget.abspath: D:/dev/build-sys-eval/foobar/src/.build/bin/windows-x86_64-release/L0a/L0a.dll
echo $(ProjectName) [cfg.buildtarget.name]: "$(TargetFileName)"
echo $(ProjectName) cfg.buildtarget.name: $(TargetFileName)
echo $(ProjectName) [cfg.buildtarget.basename]: "$(TargetName)"
echo $(ProjectName) cfg.buildtarget.basename: $(TargetName)
echo $(ProjectName) [cfg.buildtarget.extension]: "..\.dll"
echo $(ProjectName) cfg.buildtarget.extension: .dll

Without %[] relpath and abspath are indeed much more correct, though I'd still expect both %{!cfg.buildtarget.relpath} and %{cfg.buildtarget.abspath} to be absolute paths like %{!cfg.buildtarget.abspath} is.

So the docs stating that %[] is required for paths appears to be entirely incorrect? Even without the %[] the generator transformed %{cfg.buildtarget.directory} into $(TargetDir). 😕

Jarod42 commented 1 month ago

I'd still expect both %{!cfg.buildtarget.relpath} and %{cfg.buildtarget.abspath} to be absolute paths like %{!cfg.buildtarget.abspath} is.

IMO, having relpath/abspath is wrong from premake API perspective as confusing... I think it comes from time before we have %[..] and %{!..}.

So the docs stating that %[] is required for paths appears to be entirely incorrect? Even without the %[] the generator transformed %{cfg.buildtarget.directory} into $(TargetDir).

I won't say doc is incorrect in that concern. As omit %[..] might work with visual generators, but some other generators won't works. %[..] would make path relative to project; Some generator has replacement table for %{..} transforming in their own variable name (which is then considered as absolute, so not replaced by %[..]).

"{ECHO} %{prj.name} [cfg.buildtarget.name]: %[%{cfg.buildtarget.name}]",
"{ECHO} %{prj.name} [cfg.buildtarget.basename]: %[%{cfg.buildtarget.basename}]",
"{ECHO} %{prj.name} [cfg.buildtarget.extension]: %[%{cfg.buildtarget.extension}]",

Those are not paths, so should not be enclosed by %[] (even if name/basename (seems to) works, related to above comment).