1-- 2-- Name: ninja_base.lua 3-- Purpose: Define the ninja action. 4-- Author: Stuart Carnie (stuart.carnie at gmail.com) 5-- 6 7local ninja = premake.ninja 8 9function ninja.esc(value) 10 if value then 11 value = string.gsub(value, "%$", "$$") -- TODO maybe there is better way 12 value = string.gsub(value, ":", "$:") 13 value = string.gsub(value, "\n", "$\n") 14 value = string.gsub(value, " ", "$ ") 15 end 16 return value 17end 18 19-- in some cases we write file names in rule commands directly 20-- so we need to propely escape them 21function ninja.shesc(value) 22 if type(value) == "table" then 23 local result = {} 24 local n = #value 25 for i = 1, n do 26 table.insert(result, ninja.shesc(value[i])) 27 end 28 return result 29 end 30 31 if value:find(" ") then 32 return "\"" .. value .. "\"" 33 end 34 35 return value 36end 37 38function ninja.list(value) 39 if #value > 0 then 40 return " " .. table.concat(value, " ") 41 else 42 return "" 43 end 44end 45 46function ninja.arglist(arg, value) 47 if #value > 0 then 48 local args = {} 49 for _, val in ipairs(value) do 50 table.insert(args, string.format("%s %s", arg, val)) 51 end 52 return table.concat(args, " ") 53 else 54 return "" 55 end 56end 57 58-- generate all build files for every project configuration 59function ninja.generate_project(prj) 60 if prj.language == "Swift" then 61 ninja.generate_swift(prj) 62 else 63 ninja.generate_cpp(prj) 64 end 65end 66 67local function innerget(self, key) 68 return rawget(getmetatable(self), key) or self.__inner[key] 69end 70 71local prj_proxy = { __index = innerget } 72 73local cfg_proxy = { __index = innerget } 74 75function new_prj_proxy(prj) 76 prj = prj.project or prj 77 78 local v = { __inner = prj } 79 80 local __configs = {} 81 for key, cfg in pairs(prj.__configs) do 82 if key ~= "" then 83 __configs[key] = ninja.get_proxy("cfg", cfg) 84 else 85 __configs[key] = cfg 86 end 87 end 88 v.__configs = __configs 89 90 return setmetatable(v, prj_proxy) 91end 92 93local function rebasekeys(t, keys, old, new) 94 for _,key in ipairs(keys) do 95 t[key] = path.rebase(t[key], old, new) 96 end 97 return t 98end 99 100local function rebasearray(t, old, new) 101 local res = { } 102 for _,f in ipairs(t) do 103 table.insert(res, path.rebase(f, old, new)) 104 end 105 return res 106end 107 108function new_cfg_proxy(cfg) 109 local keys = { "directory", "fullpath", "bundlepath" } 110 111 local old = cfg.location 112 local new = path.join(cfg.location, cfg.shortname) 113 local v = { 114 __inner = cfg, 115 location = new, 116 objectsdir = path.rebase(cfg.objectsdir, old, new), 117 buildtarget = rebasekeys(table.deepcopy(cfg.buildtarget), keys, old, new), 118 linktarget = rebasekeys(table.deepcopy(cfg.linktarget), keys, old, new), 119 } 120 121 v.files = rebasearray(cfg.files, old, new) 122 v.includedirs = rebasearray(cfg.includedirs, old, new) 123 v.libdirs = rebasearray(cfg.libdirs, old, new) 124 v.userincludedirs = rebasearray(cfg.userincludedirs, old, new) 125 v.systemincludedirs = rebasearray(cfg.systemincludedirs, old, new) 126 v.swiftmodulemaps = rebasearray(cfg.swiftmodulemaps, old, new) 127 128 return setmetatable(v, cfg_proxy) 129end 130 131function cfg_proxy:getprojectfilename(fullpath) 132 local name = self.project.name .. ".ninja" 133 134 if fullpath ~= nil then 135 return path.join(self.location, name) 136 end 137 138 return name 139end 140 141function cfg_proxy:getoutputfilename() 142 return path.join(self.buildtarget.directory, self.buildtarget.name) 143end 144 145local proxy_cache = { 146 prj = { new = new_prj_proxy }, 147 cfg = { new = new_cfg_proxy }, 148} 149 150function get_proxy(cache, obj) 151 if not cache[obj] then 152 cache[obj] = cache.new(obj) 153 end 154 return cache[obj] 155end 156 157function ninja.get_proxy(typ, obj) 158 if not proxy_cache[typ] then 159 error("invalid proxy type") 160 end 161 162 return get_proxy(proxy_cache[typ], obj) 163end 164 165