premake5 добавить сгенерированные файлы в проект vstudio

Я переопределил функцию onProject для действия vs2012, которое генерирует некоторые файлы cpp, а затем пытается включить их в проект.

--cant override the generateProject directly
--so have to override at the action level
premake.override( premake.action._list.vs2012, 'onProject', function(base, prj)
      
    if premake.project.iscpp(prj) then
        
        --generate files  
        --print( "Generating extra files ...")
        local extraFiles = mine.getExtraFiles(prj)

        for _,file in ipairs( extraFiles ) do
            p.generate( file, nil, mine.generateExtraFile )                
            mine.addFileToSources(file)
        end                            
    end

    --Generate regular stuff
    base(prj)      
end)


function mine.getExtraFiles(prj)
    local extraFiles = {}
    --works out what files to generate and add relevant info to table
    
    return extraFiles
end

--this function is passed as a callback to premake.generate
function mine.generateExtraFile(extraFile)
    --write contents of file
end

Это функция, которая пытается добавить каждый сгенерированный файл в проект.

function mine.addFileToSources(extraFile)
    local prj = extraFile.prj
    local cfg = extraFile.cfg

    local groups  = premake.vstudio.vc2010.categorizeSources(prj)       
    local compiledFiles = groups.ClCompile or {} 
    
    --create a new file config for generated file
    local filename = path.join(extraFile.location, extraFile.filename)
    local fcfg = premake.fileconfig.new( filename, prj)

    premake.fileconfig.addconfig(fcfg, cfg)
       
    --add the config to the project's sources
    table.insert(compiledFiles, fcfg)
    compiledFiles[filename] = fcfg

    --add to the projects source tree
    --this bit is copied from premake.project.getsourcetree
 
        -- The tree represents the logical source code tree to be displayed
        -- in the IDE, not the physical organization of the file system. So
        -- virtual paths are used when adding nodes.

        -- If the project script specifies a virtual path for a file, disable
        -- the logic that could trim out empty root nodes from that path. If
        -- the script writer wants an empty root node they should get it.

        local flags
        if fcfg.vpath ~= fcfg.relpath then
            flags = { trim = false }
        end
          
        -- Virtual paths can overlap, potentially putting files with the same
        -- name in the same folder, even though they have different paths on
        -- the underlying filesystem. The tree.add() call won't overwrite
        -- existing nodes, so provide the extra logic here. Start by getting
        -- the parent folder node, creating it if necessary.
        
        local tr = premake.project.getsourcetree(prj)
        local parent = premake.tree.add(tr, path.getdirectory(fcfg.vpath), flags)
        
        local node = premake.tree.insert(parent, premake.tree.new(path.getname(fcfg.vpath)))

        -- Pass through value fetches to the file configuration
        setmetatable(node, { __index = fcfg })                        
end

По большей части - это все работает: Файлы генерируются правильно и в правильном месте Файлы также правильно включаются в файл vcxproj

Моя проблема в том, что файл vcxproj.filters не создается. Когда я запускаю premake, я получаю эту ошибку:

Generating myproject.vcxproj.filters...Error: [string "src/actions/vstudio/vs2010_vcxproj_filters...."]:82: attempt to index field 'parent' (a nil value)

что соответствует функции premake.vstudio.vc2010.filterGroup(prj, groups, group) Я понимаю, что новый fcfg, который я создал, должен иметь родителя, но я не могу понять, куда и к чему я должен его добавить.

Кто-нибудь может помочь?

ИЗМЕНИТЬ 1

У меня все работает, добавляя эту строку в конец функции mine.addFileToSources(extraFile)

fcfg.parent = parent

Это дает конфигурации файла родительский узел, так что все работает, но я чувствую себя немного грязным, делая это, поэтому я рассмотрю совет Цитрона.

ИЗМЕНИТЬ 2

Переопределение файлов выпечки было намного чище и аккуратнее. Это было не так просто, как код Citron, поскольку мне нужна была информация из запеченных файлов, чтобы выполнить генерацию файлов, но теперь я уверен, что мой код правильный и, возможно, будет работать с другими экспортерами, кроме vstudio.

Вот мой новый код:

premake.override( premake.oven, 'bakeFiles', function(base, prj)

    --bake the files as normal
    local bakedFiles = base(prj)

    if premake.project.iscpp(prj) then
    
        --gather information about what files to generate and how
        local extraFiles = mine.getExtraFiles(prj, bakedFiles)
                              
        for _,file in ipairs( extraFiles ) do
        
            --do the generation
            premake.generate( file, file.extension, mine.generateExtraFile )                            
             
            --add the new files 
            local filename = premake.filename(file, file.extension)
            table.insert(file.cfg.files, filename)
       
            -- This should be the first time I've seen this file, start a new
            -- file configuration for it. Track both by key for quick lookups
            -- and indexed for ordered iteration.
            assert( bakedFiles[filename] == nil )
                                                                       
            local fcfg = premake.fileconfig.new(filename, file.prj)
            bakedFiles[filename] = fcfg
            table.insert(bakedFiles, fcfg)
       
            premake.fileconfig.addconfig( bakedFiles[filename], file.cfg)                                       
        end 

        --sort the baked files again - since we have added to them
        table.sort(bakedFiles, function(a,b)
            return a.vpath < b.vpath
        end)
               
    end 
    return bakedFiles
end)

person David Woo    schedule 27.05.2015    source источник


Ответы (1)


Я не знаю, в чем проблема с вашим кодом (слишком много читать и не хватает времени: p), но если вы просто хотите добавить некоторые сгенерированные файлы в дерево вашего проекта, я бы посоветовал вам вместо этого переопределить premake.oven.bakeFiles .

Это то, что я использовал для добавления файлов, сгенерированных Qt, в свой аддон. См. premake.extensions.qt.customBakeFiles на https://github.com/dcourtois/premake-qt/blob/master/qt.lua

По сути, в переопределении bakeFiles вы можете просто просматривать свои проекты и легко вставлять файлы в список. Затем, если эти добавленные файлы нуждаются в некоторой пользовательской конфигурации, вы можете переопределить premake.fileconfig.addconfig. См. premake.extensions.qt.customAddFileConfig в вышеупомянутом дополнении.

В этом переопределении addconfig у вас будет доступ к файлам, и вы сможете изменить их объект конфигурации: вы можете добавить собственные правила сборки, специальные параметры и т. д.

Это не прямой ответ на ваш конкретный вопрос, но я надеюсь, что он поможет вам достичь того, что вам нужно.

person Citron    schedule 28.05.2015
comment
Спасибо - это хороший совет. Вместо этого я рассмотрю переопределение файлов выпечки. На самом деле у меня это работает по-моему, но это кажется немного хакерским, поэтому я не уверен - person David Woo; 28.05.2015
comment
Да, я прочитал скопированный из premake.project.getsourcetree комментарий в вашем коде, и вообще говоря, если вам нужно это сделать, это неправильный путь :) - person Citron; 28.05.2015