Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workspace vpaths overriding project ones #2293

Open
UAVXP opened this issue Oct 11, 2024 · 11 comments
Open

Workspace vpaths overriding project ones #2293

UAVXP opened this issue Oct 11, 2024 · 11 comments
Labels

Comments

@UAVXP
Copy link
Contributor

UAVXP commented Oct 11, 2024

Hello. I have a question about vpaths inheritance.

I want to make a separate (or rather additional) set of vpaths in my project.

This is the project tree:

src_main
    appframework/
...
    public/
        appframework/
            AppFramework.h
            IAppSystem.h
    premake5.lua

src_main/premake5.lua:

workspace "everything"
...
    vpaths {
        ["Header Files"] = { "**.h", "**.hpp" },
        ["Source Files"] = { "**.c", "**.cpp" },
        ["Shaders"] = { "**.fxc", "**.psh", "**.vsh" },
    }
...
    group "Common"
    include "appframework"

And this is what I have in src_main/appframework/premake5.lua:

local prj = project("appframework")
...
    files {
        ...
    }
    vpaths {
        ["Interface"] = "../public/appframework/**.h"
    }

Seems like Premake only considers the main vpaths (from workspace), but not the vpaths from "appframework" project.
It puts headers from src_main/public/appframework to a "Header Files" filter in the final ".vcxproj.filters" file, but not "Interface".

How can I accomplish the desired functionality?

@UAVXP UAVXP added the question label Oct 11, 2024
@UAVXP
Copy link
Contributor Author

UAVXP commented Nov 7, 2024

Here's the example project I made to show an issue:
premake_vpaths_inheritance.zip

Archive hierarchy:

premake_vpaths_inheritance
    myproject/ - example project folder
    premake5/ - compiled premake-core binaries from https://github.com/premake/premake-core/commit/1a804088d6062814d79f22b292a3f471786d9fe7
    public/ - custom headers for myproject
    premake5.lua

If you want - you can use the latest official Premake build.

premake5.lua:

workspace "everything"

	configurations { "Debug", "Release" }

	vpaths {
		["Header Files"] = { "**.h", "**.hpp" },
		["Source Files"] = { "**.c", "**.cpp" },
	}

	group "Common"
	include "myproject"

myproject/premake.lua:

project "myproject"

	language "C++"
	kind "StaticLib"
	targetname "%{prj.name}"
	targetdir "%{cfg.buildcfg}"

	includedirs { "%{wks.location}/public" }

	files {
		"main.cpp",
		"main.h",

		"%{wks.location}/public/public_header.h",
	}

	vpaths {
		["Interface"] = {

			-- These three does not work
			"%{wks.location}/public/**.h",
			"public/**.h",
			"**.h",

		},
	}

To run: premake5\premake5.exe vs2022

In the resulted myproject/myproject.vcxproj.filters you would see this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{E9C7FDCE-D52A-8D73-7EB0-C5296AF258F6}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{21EB8090-0D4E-1035-B6D3-48EBA215DCB7}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="..\public\public_header.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="main.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
</Project>

as opposed to vpaths settings from myproject/premake5.lua

@UAVXP UAVXP changed the title vpaths inheritance (project over workspace) question Workspace vpaths overriding project ones Nov 10, 2024
@UAVXP
Copy link
Contributor Author

UAVXP commented Nov 11, 2024

No one knows what's going on here? Really? A month has been passed, and not one person replied to this issue

@UAVXP
Copy link
Contributor Author

UAVXP commented Nov 11, 2024

Also, if I cheat a little and do this in premake5.lua:

function defaultVpaths()
	vpaths {
		["Header Files"] = { "**.h", "**.hpp" },
		["Source Files"] = { "**.c", "**.cpp" },
	}
end

workspace "everything"

	configurations { "Debug", "Release" }

	-- vpaths {
		-- ["Header Files"] = { "**.h", "**.hpp" },
		-- ["Source Files"] = { "**.c", "**.cpp" },
	-- }

	group "Common"
	include "myproject"

and this in myproject/premake5.lua:

project "myproject"

	language "C++"
	kind "StaticLib"
	targetname "%{prj.name}"
	targetdir "%{cfg.buildcfg}"

	includedirs { "%{wks.location}/public" }

	files {
		"main.cpp",
		"main.h",

		"%{wks.location}/public/public_header.h",
	}

	defaultVpaths()
	vpaths {
		["Interface"] = {

			-- These three does not work
			"%{wks.location}/public/**.h",
		--	"public/**.h",
		--	"**.h",

		},
	}

then, for some reason, public/public_header.h filter becomes public and not Interface:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{E9C7FDCE-D52A-8D73-7EB0-C5296AF258F6}</UniqueIdentifier>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{21EB8090-0D4E-1035-B6D3-48EBA215DCB7}</UniqueIdentifier>
    </Filter>
    <Filter Include="public">
      <UniqueIdentifier>{A4949D15-9036-C8EB-79F1-DB3F65324F3C}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="..\public\public_header.h">
      <Filter>public</Filter>
    </ClInclude>
    <ClInclude Include="main.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
</Project>

I don't even know what's going on with vpaths anymore...

@UAVXP
Copy link
Contributor Author

UAVXP commented Nov 11, 2024

This:

defaultVpaths = {
	["Header Files"] = { "**.h", "**.hpp" },
	["Source Files"] = { "**.c", "**.cpp" },
}

workspace "everything"

	configurations { "Debug", "Release" }

	-- vpaths {
		-- ["Header Files"] = { "**.h", "**.hpp" },
		-- ["Source Files"] = { "**.c", "**.cpp" },
	-- }

	group "Common"
	include "myproject"
project "myproject"

	language "C++"
	kind "StaticLib"
	targetname "%{prj.name}"
	targetdir "%{cfg.buildcfg}"

	includedirs { "%{wks.location}/public" }

	files {
		"main.cpp",
		"main.h",

		"%{wks.location}/public/public_header.h",
	}

	vpaths {
		defaultVpaths,
		["Interface"] = {

			-- These three does not work
			"%{wks.location}/public/**.h",
			"%{wks.location}/public/*.h",
			"public/**.h",
			"public/*.h",
			"**.h",
			"*.h",

		},
	}

didn't work either

@UAVXP
Copy link
Contributor Author

UAVXP commented Nov 11, 2024

function test()
	local arr = {}
	arr["Header Files"] = { "**.h", "**.hpp" }
	arr["Source Files"] = { "**.c", "**.cpp" }
	return arr
end


workspace "everything"

	configurations { "Debug", "Release" }

	-- vpaths {
		-- ["Header Files"] = { "**.h", "**.hpp" },
		-- ["Source Files"] = { "**.c", "**.cpp" },
	-- }

	group "Common"
	include "myproject"
project "myproject"

	language "C++"
	kind "StaticLib"
	targetname "%{prj.name}"
	targetdir "%{cfg.buildcfg}"

	includedirs { "%{wks.location}/public" }

	files {
		"main.cpp",
		"main.h",

		"%{wks.location}/public/public_header.h",
	}

	vpaths {
		test(),
		
		["Interface"] = {

			"%{wks.location}/public/**.h",
			"%{wks.location}/public/*.h",
			"public/**.h",
			"public/*.h",
			"**.h",
			"*.h",

		},
		
		["Interface/*"] = {

			"%{wks.location}/public/**.h",
			"%{wks.location}/public/*.h",
			"public/**.h",
			"public/*.h",
			"**.h",
			"*.h",

		},
		
	}

It doesn't work. The myproject.vcxproj.filters file is still the same. I don't even fucking know, and this behavior (and the fact no one actually replied to me) drives me insane.

@UAVXP
Copy link
Contributor Author

UAVXP commented Nov 11, 2024

@starkos @samsinsane @nickclark2016 Please?

@nickclark2016
Copy link
Member

I don't have an answer for you, as I'm not terribly familiar with vpaths in Premake (hence why I didn't answer).

@nickclark2016
Copy link
Member

Looking further into your described behavior, this may be a bug.

@samsinsane
Copy link
Member

samsinsane commented Nov 16, 2024

No one knows what's going on here? Really? A month has been passed, and not one person replied to this issue

I don't even fucking know, and this behavior (and the fact no one actually replied to me) drives me insane.

You're not entitled to anything from any of us, you need to calm down and be patient. Your urgency is not our priority.


Looking further into your described behavior, this may be a bug.

Not sure I agree, but I'm also not really sure what behaviour you're referring to.

There's two issues that I have seen:

  1. vpaths returns on the first match, which implicitly prioritises a workspace-level vpaths over a project-level one. Given that it's handled like any other API, I would suggest that this is not something that can be fixed without some weird hacks and breaking existing projects that rely on the current functionality.
  2. vpaths "handles" tokens but doesn't actually handle them - %{wks.location} will expand to the action tokens, which in this case is $(SolutionDir) which prevents path matching. Not sure this can be fixed without breaking existing projects that rely on the tokens to be expanded when they are, maybe one of the random token hacks that people keep littering throughout the codebase might work here?

So, to resolve the original issue you can either fix the pathing problems in the function that provides Header Files and Source Files, or move the vpaths to each project. (Edit: I made a mistake in my testing and thought specifying the vpaths after the projects would fix the issue, but it doesn't and I didn't notice that I had the vpaths around the wrong way, my apologies).

@UAVXP
Copy link
Contributor Author

UAVXP commented Nov 17, 2024

I was not and am not in any rush, I was just sad and demoralized cause no answers were given, neither positive nor negative or neutral ones. Just emptiness and silence in response for about 1 whole month.

move the vpaths to each project

That's why I used this:

function test()
	local arr = {}
	arr["Header Files"] = { "**.h", "**.hpp" }
	arr["Source Files"] = { "**.c", "**.cpp" }
	return arr
end
	vpaths {
		test(),
		
		["Interface"] = {
				...

This workaround above cannot produce adequate results, even though the "global" vpaths are in the project now (I suppose?).

@samsinsane
Copy link
Member

**.h won't match the public directory because the public directory is not inside the myproject directory. The current working directory is changed based on which file is being executed.

Putting the most inclusive patterns first will prevent ["Interface"] from matching anything - you need to put ["Interface"] first as I explained above already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants