configuration use with files

Hi there !

I finally had some spare time to dedicate to one thing I'd really like to be handled by premake : per-file configurations.
For the moment, I'm just trying to add the NoPCH flag to a few files since that is the most important thing for me. Here is a piece of the configuration file I'm using :

files { "source/test/**.c"
        "source/test/**.cpp"
        "source/test/**.h"
        "source/PVRT/**.cpp",
        "include/PVRT/**.h" }
 
-- test
configuration { "source/PVRT/PVRTDecompress.cpp" }
    flags { "NoPCH" }
 
-- test 2
configuration { "**.c" }
    flags { "NoPCH" }

Thanks to a graphical debugger, I could check that this was correctly saved and added to the premake data. It's added in a "prj.project.blocks"
If I understand correctly, the first "prj" project is the vs project, the second is the original premake project as defined in the premake4.lua script.
Then blocks seem to hold all the configurations ...
For each one, I have a terms and a keywords string, and then a list of flags.

(I just want to make sure everything is working as intended and I understand correctly how it works, so feel free to correct me if I wrote something wrong ^^)

Now I'm in the vs2010 project generator, where the ClCompile are written. The last thing I have to do is add support for the NoPCH flag here. So, I need to get the block which is corresponding the current file I'm writting, and this is where I don't know how to do : I think I should parse the blocks and try to watch fro the one who's "keywords" match the file name, but I don't know if there is a premake function that does just that, or if I have to write my own ?

Sorry for the big post, and thanks in advance for any help ^^

>If I understand correctly, the first "prj" project is the vs project, the second is the original premake project as defined in the premake4.lua script.

No, you don't. Premake has exactly one project object per "project" defined in premake4.lua

About flags: you probably need cfg.flags.NoPCH (search for it across source files to get an idea about it's usage and how to get cfg)

Ok, but if I set a breakpoint in vc2010.compilerfilesgroup, the prj object received in parameter contains lots of stuff (build options, pch, files, kind, etc.) and amongst those stuff, there is another "project" object, which contains the "blocks" table I'm interested in. See this : http://uploads.pcitron.fr/decoda_premake.png

This is a bit confusing, especially with the lack of developer's documentation ... functions might be commented, if the types/objects are not, it's hard to figure out what's where :)

Anyway, I checked the premake.getconfig, and it won't return the value for the file configuration. As I said, this value is stored in an element of the prj.project.blocks table, and the premake.getconfig only checks the prj.project.__configs (or prj.__configs if there is no "project" member)

I could hack what I want to do, but I want to do it properly so that I can submit this as a patch afterward (or at least do things the way they should) I can think of 2 solutions here : create a "getfileconfig" that would search for a block matching the file's name, and use this, or ensure that when I add a "file configuration" (e.g. configuration { "some_file.cpp" }) it will be added to the __configs table (and then I can use the existing premake.getconfig function)

Any idea, suggestion ?

Look at bake.lua:698-715.

I think you should ensure that flags get into __fileconfigs, and create a function premake.getconfig(fname, prj, cfgname, pltname)

Thanks for your help, I'll definitely check this.

Search for "buildaction". This is a per-file property, so you should be able to follow the same approach.

Hi,

I've been debugging the postprocess function to check that file configuration was correctly handled and I realized this :

files { "source/test/**.cpp" }
configuration { "source/test/file.cpp" }
    flags { "NoPCH" }

When doing this, the actual file path which is saved by premake (in my case) is not "source/test/..." but "../../../source/test/...". I guess file paths are made relative to their project when they're added ?

e.g. in bake.lua, in the following test :

for _, blk in ipairs(cfg.project.blocks) do
	if (premake.iskeywordsmatch(blk.keywords, cfg.terms)) then
		mergeobject(fcfg, blk)

will always fail since blk.keywords points to "source/test/file.cpp" (the path I used in configuration {}) and cfg.terms corresponds to the filename, which is "../../../source/test/file.cpp" (or whatever other relative path)

What do you think would be the best way to fix this problem ? I thought of creating a "fileconfiguration" function which would just convert the file path, and then call the configuration function, but I think it would be best to make configuration handle any type of configuration ...
But I can't think of any way of making configuration function know that it should convert a file path or not (there's nothing preventing you to add a "debug - .cpp" configuration name, so obviously configuration function can't use premake.iscpp/c/header* functions ...)

Thinking off the top of my head here, without look at the code — Can we move the "convert to project relative" step later in the process? Allow the configurations to get built first? I suppose I tried to do it early, before the paths got copied into all the different configurations.

Long term, perhaps the list of files should get replaced with a list of file configurations, with a proper API to access file paths in different forms.

>Long term, perhaps the list of files should get replaced with a list of file configurations

Oops... That will break a lot of my code

Actually, it won't be so much code. I've just used to rely on iteration through configuration().files