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

Filter projects and other "container" commands

Open Zylann opened this issue 8 years ago • 14 comments

StackOverflow thread: http://stackoverflow.com/questions/31675324/how-to-prevent-a-project-from-being-generated

It would be nice to be able to tell premake to generate a project or solution under certain conditions. Those condition could be specified just like filters.

For example, a project could have a "containerfilter" command above it, and every following premake command would be ignored until a new "project" or "containerfilter" command comes up (pseudo names, just to get the idea).

On my side, I had a solution for an application and a lot of projects, some of them being modules only present under certain OSes. Currently I'm forced to implement some kind of big if blocks / hardcoding to prevent them from being generated, but it's not as pretty as it could be with Premake IMHO :)

Zylann avatar Aug 12 '15 18:08 Zylann

Interested by this request too. It helps when you have hundreds of project and not all of them supported by every platform.

Avtom avatar Dec 08 '15 22:12 Avtom

Great idea, would also be useful for some of my projects. Right now I work around it by putting an if block wrapping the entire project definition.

tritao avatar Dec 08 '15 23:12 tritao

why is lua not enough?

if (condition) then
    project 'bla'
end

tvandijck avatar Dec 09 '15 16:12 tvandijck

Because an if test is not the same as a filter, we don't have access to the same expressions/vars. We use filters everywhere else, why not there? Also: if blocks wrapping entire files is not pretty, but that's my personal opinion.

Zylann avatar Dec 09 '15 18:12 Zylann

Oh, I understand that they are different, but the conditions you have access to outside of the "project" scope, is very limitted in itself... basically something like:

solution 'bla'
    platforms { 'x86', 'x86_64' }

    filter { 'platforms:x86' }
         project 'foo'

what should premake do? generate the project? or not? if not, then why did you define the platform in the first place? a visual studio solution will contain both platforms, so it must also contain the project, since it will have x86_64 as well...

within the solution/workspace scope you already and currently only have access to the following filters:

context.addFilter(self, "_ACTION", _ACTION)
context.addFilter(self, "action", _ACTION)

self.system = self.system or p.action.current().os or os.get()
context.addFilter(self, "system", self.system)

context.addFilter(self, "_OPTIONS", options)
context.addFilter(self, "options", options)

and well... correct me if I'm wrong, but that already works perfectly fine today.

The thing is, the _ACTION is available during the execution of the script, so an "if _ACTION == 'vs2015'' works perfectly fine, a filter would just be redundant and more complex. The same is true for the "system" and "_OPTIONS"... so really within the workspace scope there is no reason to use filters since everything to filter on is alreadly readily available.

So my question is then, what else would you want to filter on?

tvandijck avatar Dec 09 '15 18:12 tvandijck

The example of my current solution:

I have one workspace with 150~200 projects in it and about 10 platforms/systems.

What could do right now is :

workspace "My Solution"
    configurations "Release"
    platforms { 
                "Platform 1",
                "Platform 2", 
                "Platform 3",
                "Platform 4", 
                "Platform 5", 
                "Platform 6", 
                "Platform 7", 
                "Platform 8", 
                "Platform 9", 
                "Platform 10" 
              } 

    filter "platforms:Platform 1"
      system "Platform1"

    filter "platforms:Platform 2"
      system "Platform2"

    --  ... Up to Platform 10

    project "Core Module"
        kind "SharedLib"
        language "C++"

    project "Platform 5 Specific Module"
        kind "SharedLib"
        language "C++"
        removeplatforms { 
                "Platform 1",
                "Platform 2", 
                "Platform 3",
                "Platform 4", 
                "Platform 6", 
                "Platform 7", 
                "Platform 8", 
                "Platform 9", 
                "Platform 10" 
              }

And the generated solution will contain dozen of useless modules, depending of the platform. (I don't care about macosx specific modules in a visual solution for example).

As you suggest, I could use Lua conditional statements instead:

workspace "My Solution"
    configurations "Release"

    project "Core Module"
        kind "SharedLib"
        language "C++"

    if (system == platform5) then

        project "Platform 5 Specific Module"
            kind "SharedLib"
            language "C++"

    end

This generate a cleaner solution, and the possibility to select the system you want with --os directly on the command line. (premake5.exe --os=macosx xcode4)

But it doesn't really describe the project in the "project" declaration, because some information information are in the "if" condition.

A cleaner declaration could be something like :

workspace "My Solution"
    configurations "Release"

    project "Core Module"
        kind "SharedLib"
        language "C++"

    project "Platform 5 Specific Module"
        kind "SharedLib"
        language "C++"
        supportedsystem "system5"

And make sure the project is generated for this system only.

I'm not sure my example help with the original request, but it's a case of " generate a project or solution under certain conditions"

Avtom avatar Dec 10 '15 23:12 Avtom

Right, I understand I think... that said though... I still don't see what the difference is between

 if (system == platform5) then
        project "Platform 5 Specific Module"
            kind "SharedLib"
            language "C++"
    end

and

project "Platform 5 Specific Module"
        kind "SharedLib"
        language "C++"
        supportedsystem "system5"

Except for the fact that now premake knows about the project, but at time of generation it needs to ignore it anyway... So what is the use of declaring the project, if premake is then required to ignore it? The "if" block will completely eliminate all code in there, and hence not burden premake with extra definition it is not going to need anyway...

It really feels like this is just syntax sugar to make it look cool, but is otherwise entirely pointless. besides, you should already be able to do this:

filter { 'system:system5' }
    project "Platform 5 Specific Module"
            kind "SharedLib"
            language "C++"

which is already more consistent then the introduction of a new keyword.

tvandijck avatar Dec 10 '15 23:12 tvandijck

besides, you should already be able to do this:

You can't actually filter projects (or any other kind of container) currently, because containers contain the filters and not the other way around. I can kind of understand why people want it, but I also feel it falls into the "syntactic sugar" category right now as the workaround is so easy.

starkos avatar Dec 11 '15 00:12 starkos

Ah, but isn't the workspace a container? so in that scope it would contain that filter right? or is the project because it is a container itself not subject to the filters of it's parent?

tvandijck avatar Dec 11 '15 00:12 tvandijck

Yes, it's probably more a syntactic sugar but when you have an if statement above every of your 150 projects, if feels like a hack/workaround because the grammar itself doesn't really let you describe what your project is.

Also yes, filter system doesn't work on project.

But it's probably more a specific need for my solution. I probably should write a module to add the "supported" (and removesupported) keywords instead. Is this possible to do it in a separate module or should I modify locally the sources of premake instead ?

Avtom avatar Dec 11 '15 08:12 Avtom

or is the project because it is a container itself not subject to the filters of it's parent?

This. Containers hold other containers (i.e. solutions hold projects) and blocks of configuration settings. A filter represents a block of configuration settings. Blocks of configuration settings do not hold containers. As you (@tvandijck) mentioned, that's kind of a slippery slope.

Also note that creating a new container (solution/project) clears the filter. So you would still have to specify a filter above every project to make this work.

If someone does decide to attempt this, you might want to consider a mechanism other than filter() to make this work, for the issues raised in this thread.

when you have an if statement above every of your 150 projects, if feels like a hack/workaround because the grammar itself doesn't really let you describe what your project is.

You could associate the project and the condition with a small helper:

function conditional_project(name, condition)
    if condition then
        project (name)
    end
    return condition
end


if conditional_project("Platform 5 Specific Module", system == "platform5") then
    kind "SharedLib"
    language "C++"
end

I could probably think of a better name if I'd had my cup of coffee...

starkos avatar Dec 11 '15 13:12 starkos

Any update on this? This is a crucial function when working on cross platform projects where some projects are platform dependent. (Think glfw on windows/macOS)

Note: Above function doesn't work unfortunately, since "system" needs to be one of the available values, listed: https://premake.github.io/docs/system/

nepp95 avatar Feb 09 '22 18:02 nepp95

Above function doesn't work unfortunately, since "system" needs to be one of the available values, listed:

Not entirely sure which function you're referring to, but os.target() is likely what you're after.

samsinsane avatar Feb 10 '22 12:02 samsinsane

Above function doesn't work unfortunately, since "system" needs to be one of the available values, listed:

Not entirely sure which function you're referring to, but os.target() is likely what you're after.

I was referring to the function I posted a link to ;) While both the one you suggest and system work in a hackish workaround, there is still no real solution to having platform dependent dependencies. Having to wrap a project in an if statement isn't really a solution.

nepp95 avatar Dec 01 '23 14:12 nepp95