|
| 1 | +-- |
| 2 | +-- ninja.lua |
| 3 | +-- Utilities for generating Ninja build files |
| 4 | +-- Author: Nick Clark |
| 5 | +-- Copyright (c) 2025 Jess Perkins and the Premake project |
| 6 | +-- |
| 7 | + |
| 8 | +local p = premake |
| 9 | + |
| 10 | +p.modules.ninja = {} |
| 11 | +p.modules.ninja._VERSION = p._VERSION |
| 12 | + |
| 13 | +local ninja = p.modules.ninja |
| 14 | + |
| 15 | +function ninja.esc(value) |
| 16 | + value = value:gsub("%$", "$$") |
| 17 | + value = value:gsub(":", "$:") |
| 18 | + value = value:gsub("\n", "$\n") |
| 19 | + value = value:gsub('%(', '\\(') |
| 20 | + value = value:gsub('%)', '\\)') |
| 21 | + value = value:gsub('"', '\\"') |
| 22 | + value = value:gsub(" ", "\\ ") |
| 23 | + |
| 24 | + return value |
| 25 | +end |
| 26 | + |
| 27 | +function ninja.header(target) |
| 28 | + local kind = iif(target.project, "project", "workspace") |
| 29 | + _p("# %s %s Ninja build file generated by Premake", target.name, kind) |
| 30 | + _p('ninja_required_version = 1.6') |
| 31 | + _p('') |
| 32 | +end |
| 33 | + |
| 34 | +function ninja.key(cfg) |
| 35 | + local name = cfg.project.name |
| 36 | + local buildcfg = cfg.buildcfg |
| 37 | + if cfg.platform then |
| 38 | + return name .. "_" .. (buildcfg or "") .. "_" .. cfg.platform |
| 39 | + else |
| 40 | + return name .. (buildcfg and ("_" .. buildcfg) or "") |
| 41 | + end |
| 42 | +end |
| 43 | + |
| 44 | +function ninja.getprjconfigfilename(prj) |
| 45 | + return prj.name .. ".ninja" |
| 46 | +end |
| 47 | + |
| 48 | +function ninja.getninjafilename(target, searchprjs) |
| 49 | + local count = 0 |
| 50 | + for wks in p.global.eachWorkspace() do |
| 51 | + if wks.location == target.location then |
| 52 | + count = count + 1 |
| 53 | + end |
| 54 | + |
| 55 | + if searchprjs then |
| 56 | + for _, prj in ipairs(wks.projects) do |
| 57 | + if prj.location == target.location then |
| 58 | + count = count + 1 |
| 59 | + end |
| 60 | + end |
| 61 | + end |
| 62 | + end |
| 63 | + |
| 64 | + if count == 1 then |
| 65 | + return "build.ninja" |
| 66 | + else |
| 67 | + return target.name .. ".ninja" |
| 68 | + end |
| 69 | +end |
| 70 | + |
| 71 | +function ninja.gettoolset(cfg) |
| 72 | + local default = p.action.current().toolset |
| 73 | + local toolset, version = p.tools.canonical(cfg.toolset or default) |
| 74 | + if not toolset then |
| 75 | + error("No toolset found for '" .. tostring(cfg.toolset) .. "'") |
| 76 | + end |
| 77 | + return toolset |
| 78 | +end |
| 79 | + |
| 80 | +function ninja.list(value) |
| 81 | + if #value > 0 then |
| 82 | + return " " .. table.concat(value, " ") |
| 83 | + else |
| 84 | + return "" |
| 85 | + end |
| 86 | +end |
| 87 | + |
| 88 | +-- Override tools.getrelative to use workspace-relative paths for Ninja |
| 89 | +-- Ninja builds are always executed from the workspace root, so all paths |
| 90 | +-- must be relative to the workspace, not the project |
| 91 | +function ninja.getrelative(prj, value) |
| 92 | + if type(value) == "table" then |
| 93 | + local result = {} |
| 94 | + for i, name in ipairs(value) do |
| 95 | + result[i] = ninja.getrelative(prj, name) |
| 96 | + end |
| 97 | + return result |
| 98 | + else |
| 99 | + if value then |
| 100 | + local result = value |
| 101 | + if path.hasdeferredjoin(result) then |
| 102 | + result = path.resolvedeferredjoin(result) |
| 103 | + end |
| 104 | + -- Use workspace location instead of project location for Ninja |
| 105 | + return path.getrelative(prj.workspace.location, result) |
| 106 | + end |
| 107 | + end |
| 108 | +end |
| 109 | + |
| 110 | +include("ninja_cpp.lua") |
| 111 | +include("ninja_workspace.lua") |
| 112 | + |
| 113 | +return ninja |
0 commit comments