From f1f6304e9ba162758d73a8956ebfae8eab9200e4 Mon Sep 17 00:00:00 2001 From: Jason Perkins Date: Wed, 14 Mar 2012 18:20:01 -0400 Subject: [PATCH] Added support for file configurations to oven; full file configurations now available to actions --- src/_manifest.lua | 2 +- src/project/config.lua | 50 +++++++----- src/project/oven.lua | 85 ++++++++++++++++++++- tests/actions/vstudio/vc200x/test_files.lua | 34 +++++++++ tests/config/test_fileconfig.lua | 16 +++- 5 files changed, 164 insertions(+), 23 deletions(-) diff --git a/src/_manifest.lua b/src/_manifest.lua index 3ae72029..42cbe2cb 100644 --- a/src/_manifest.lua +++ b/src/_manifest.lua @@ -29,9 +29,9 @@ "base/premake.lua", -- project APIs + "project/oven.lua", "project/project.lua", "project/config.lua", - "project/oven.lua", "base/solution.lua", -- tool APIs diff --git a/src/project/config.lua b/src/project/config.lua index 0aa3dc14..d31e3b4a 100755 --- a/src/project/config.lua +++ b/src/project/config.lua @@ -7,6 +7,7 @@ premake5.config = { } local project = premake5.project local config = premake5.config + local oven = premake5.oven -- @@ -86,6 +87,36 @@ end +-- +-- Retrieve the configuration settings for a specific file. +-- +-- @param cfg +-- The configuration object to query. +-- @param filename +-- The full, absolute path of the file to query. +-- @return +-- A configuration object for the file, or nil if the file is +-- not included in this configuration. +-- + + function config.getfileconfig(cfg, filename) + -- if there is no entry, then this file is not part of the config + local fcfg = cfg.files[filename] + if not fcfg then + return nil + end + + -- initially this value will be a string (the file name); replace + -- it with the full file configuration + if type(fcfg) ~= "table" then + fcfg = oven.bakefile(cfg, filename) + cfg.files[filename] = fcfg + end + + return fcfg + end + + -- -- Retrieve linking information for a specific configuration. That is, -- the path information that is required to link against the library @@ -129,25 +160,6 @@ end --- --- Retrieve the configuration settings for a specific file. --- --- @param cfg --- The configuration object to query. --- @param filename --- The full, absolute path of the file to query. --- @return --- A configuration object for the file, or nil if the file is --- not included in this configuration. --- - - function config.getfileconfig(cfg, filename) - if cfg.files[filename] then - return {} - end - end - - -- -- Retrieve a list of link targets from a configuration. -- diff --git a/src/project/oven.lua b/src/project/oven.lua index 2b0073ac..593002f8 100755 --- a/src/project/oven.lua +++ b/src/project/oven.lua @@ -1,7 +1,7 @@ -- -- src/project/oven.lua -- Premake next-generation configuration "baking" API. --- Copyright (c) 2011 Jason Perkins and the Premake project +-- Copyright (c) 2011-2012 Jason Perkins and the Premake project -- premake5.oven = { } @@ -64,10 +64,46 @@ end end + -- Remember the list of terms used to create this config + cfg.terms = filterTerms + return cfg end +-- +-- Retrieve the settings for a specific file within a configuration. Files +-- have special rules: they only return those values from blocks that +-- explicitly match the filename. +-- +-- @param cfg +-- The base configuration to query. +-- @param filename +-- The name of the file to query. +-- @return +-- A file configuration object, which may be empty. +-- + + function oven.bakefile(cfg, filename) + local fcfg = {} + filename = { filename } + + for _, block in ipairs(cfg.solution.blocks) do + if oven.filter(block, cfg.terms, filename) then + oven.mergefile(fcfg, cfg, block) + end + end + + for _, block in ipairs(cfg.project.blocks) do + if oven.filter(block, cfg.terms, filename) then + oven.mergefile(fcfg, cfg, block) + end + end + + return fcfg + end + + -- -- Compare a list of block keywords against a set of filter terms. Keywords -- are Lua patterns applied to the block when it is specified in the script @@ -90,12 +126,31 @@ -- function oven.filter(block, anyOfThese, allOfThese) + allOfThese = allOfThese or {} + + -- All of these terms must match at least one block keyword + for _, term in ipairs(allOfThese) do + local matched = false + + for _, keyword in ipairs(block.keywords) do + if oven.testkeyword(keyword, { term }) then + matched = true + break + end + end + + if not matched then + return false + end + end + -- All block keywords must match at least one term for _, keyword in ipairs(block.keywords) do - if not oven.testkeyword(keyword, anyOfThese) then + if not oven.testkeyword(keyword, anyOfThese) and not oven.testkeyword(keyword, allOfThese) then return false end end + return true end @@ -164,6 +219,32 @@ end +-- +-- Merge from an individual block into a file configuration object, using the +-- provided configuration as a basis. +-- +-- @param fcfg +-- The file configuration being built; will contain the new values. +-- @param cfg +-- The base configuration. +-- @param block +-- The block containing the values to merge. +-- + + function oven.mergefile(fcfg, cfg, block) + for key, value in pairs(block) do + -- if this is the first appearance of this field, start by + -- copying over the basis values from the configuration + if not fcfg[key] then + oven.merge(fcfg, cfg, key) + end + + -- then merge the file specific values over that + oven.merge(fcfg, block, key) + end + end + + -- -- Merges a single field from a configuration block into a baked -- configuration object. diff --git a/tests/actions/vstudio/vc200x/test_files.lua b/tests/actions/vstudio/vc200x/test_files.lua index f79df572..426698fc 100644 --- a/tests/actions/vstudio/vc200x/test_files.lua +++ b/tests/actions/vstudio/vc200x/test_files.lua @@ -215,3 +215,37 @@ ]] end + + +-- +-- If a custom build rule is supplied, the custom build tool settings should be used. +-- + + function suite.customBuildTool_onBuildRule() + files { "hello.x" } + configuration "**.x" + buildrule { + description = "Compiling $(InputFile)", + commands = { + 'cxc -c "$(InputFile)" -o "$(IntDir)/$(InputName).xo"', + 'c2o -c "$(IntDir)/$(InputName).xo" -o "$(IntDir)/$(InputName).obj"' + }, + outputs = "$(IntDir)/$(InputName).obj" + } + prepare() + test.capture [[ + + + + + + ]] + end diff --git a/tests/config/test_fileconfig.lua b/tests/config/test_fileconfig.lua index 338219b1..44e088b8 100644 --- a/tests/config/test_fileconfig.lua +++ b/tests/config/test_fileconfig.lua @@ -86,4 +86,18 @@ excludes "hello.c" prepare() test.isnotnil(fcfg) - end \ No newline at end of file + end + + +-- +-- A build option specified on a specific set of files should appear in the +-- file configuration +-- + + function suite.settingIsPresent_onFileSpecificFilter() + files "hello.c" + configuration "**.c" + buildoptions "-Xc" + prepare() + test.isequal({ "-Xc" }, fcfg.buildoptions) + end