chaning to use my imgui-sfml-premake repo as a submodule

This commit is contained in:
Joseph Aquino 2025-12-30 20:05:29 -05:00
parent 2e4ecb7d24
commit 30beef3f2a
28 changed files with 7 additions and 1652 deletions

View File

@ -14,7 +14,13 @@ local snake = require("project")
workspace "snake"
architecture "x64"
startproject"snake"
staticruntime"off"
filter"system:linux"
staticruntime"Off"
filter"system:windows"
staticruntime"On"
filter""
location "build"

1
vendor/SFML vendored

@ -1 +0,0 @@
Subproject commit 0fa201c969e48ecc253581c5841ce73f44d42f49

66
vendor/build-flac.lua vendored
View File

@ -1,66 +0,0 @@
local m = {}
local scriptdir = path.getabsolute(path.getdirectory(_SCRIPT))
local ogg = require("build-ogg")
function m.generateproject(liboutdir, intdir)
project"flac"
language"C" -- c++ will mangle names and sfml wont build
kind"staticLib"
targetdir (liboutdir)
objdir(intdir)
warnings"Off"
ogg.link()
defines
{
"FLAC__NO_DLL",
"CPU_IS_BIG_ENDIAN=0",
"FLAC__HAS_OGG=1",
"PACKAGE_VERSION=\"\"",
}
filter"system:linux"
defines
{
"HAVE_LROUND",--fix error in lpc.c <Static declaration of 'lround' follows non-static declaration>
"HAVE_STDINT_H", --fix error in alloc.h <# error>
}
includedirs
{
path.join(scriptdir, "flac/include"),
path.join(scriptdir, "flac/src/libFLAC/include"),
}
files
{
path.join(scriptdir, "flac/src/libFLAC/**.c"),
}
removefiles
{
path.join(scriptdir, "flac/src/libFLAC/deduplication/**"),
}
filter"system:windows"
files
{
path.join(scriptdir, "flac/src/share/win_utf8_io/**.c"),
}
filter""
end
function m.link()
externalincludedirs
{
path.join(scriptdir, "flac/include"),
path.join(scriptdir, "flac/src/libFLAC/include"),
}
links {"flac"}
ogg.link()
end
return m

View File

@ -1,96 +0,0 @@
local m = {}
local scriptdir = path.getabsolute(path.getdirectory(_SCRIPT))
function m.generateproject(liboutdir, intdir)
project"freetype"
kind"staticLib"
language"C" -- c++ will mangle names and sfml wont build
targetdir (liboutdir)
objdir(intdir)
warnings"Off"
includedirs {path.join(scriptdir, "freetype/include")}
defines
{
"FT2_BUILD_LIBRARY",
"NDEBUG", -- have freetype always be in release mode
"FT_DEBUG_LEVEL_ERROR=0", -- fix linking errors <undefined reference...>
"FT_DEBUG_LEVEL_TRACE=0" -- fix linking errors <undefined reference...>
}
files
{
path.join(scriptdir, "freetype/src/autofit/autofit.c"),
path.join(scriptdir, "freetype/src/base/ftbase.c"),
path.join(scriptdir, "freetype/src/base/ftbbox.c"),
path.join(scriptdir, "freetype/src/base/ftbdf.c"),
path.join(scriptdir, "freetype/src/base/ftbitmap.c"),
path.join(scriptdir, "freetype/src/base/ftcid.c"),
path.join(scriptdir, "freetype/src/base/ftfstype.c"),
path.join(scriptdir, "freetype/src/base/ftgasp.c"),
path.join(scriptdir, "freetype/src/base/ftglyph.c"),
path.join(scriptdir, "freetype/src/base/ftgxval.c"),
path.join(scriptdir, "freetype/src/base/ftinit.c"),
path.join(scriptdir, "freetype/src/base/ftmm.c"),
path.join(scriptdir, "freetype/src/base/ftotval.c"),
path.join(scriptdir, "freetype/src/base/ftpatent.c"),
path.join(scriptdir, "freetype/src/base/ftpfr.c"),
path.join(scriptdir, "freetype/src/base/ftstroke.c"),
path.join(scriptdir, "freetype/src/base/ftsynth.c"),
path.join(scriptdir, "freetype/src/base/fttype1.c"),
path.join(scriptdir, "freetype/src/base/ftwinfnt.c"),
path.join(scriptdir, "freetype/src/bdf/bdf.c"),
path.join(scriptdir, "freetype/src/bzip2/ftbzip2.c"),
path.join(scriptdir, "freetype/src/cache/ftcache.c"),
path.join(scriptdir, "freetype/src/cff/cff.c"),
path.join(scriptdir, "freetype/src/cid/type1cid.c"),
path.join(scriptdir, "freetype/src/gzip/ftgzip.c"),
path.join(scriptdir, "freetype/src/lzw/ftlzw.c"),
path.join(scriptdir, "freetype/src/pcf/pcf.c"),
path.join(scriptdir, "freetype/src/pfr/pfr.c"),
path.join(scriptdir, "freetype/src/psaux/psaux.c"),
path.join(scriptdir, "freetype/src/pshinter/pshinter.c"),
path.join(scriptdir, "freetype/src/psnames/psnames.c"),
path.join(scriptdir, "freetype/src/raster/raster.c"),
path.join(scriptdir, "freetype/src/sdf/sdf.c"),
path.join(scriptdir, "freetype/src/sfnt/sfnt.c"),
path.join(scriptdir, "freetype/src/smooth/smooth.c"),
path.join(scriptdir, "freetype/src/svg/svg.c"),
path.join(scriptdir, "freetype/src/truetype/truetype.c"),
path.join(scriptdir, "freetype/src/type1/type1.c"),
path.join(scriptdir, "freetype/src/type42/type42.c"),
path.join(scriptdir, "freetype/src/winfonts/winfnt.c"),
path.join(scriptdir, "freetype/src/base/ftdebug.c"), --fix linking errors related to FT_THROW, et)c
}
filter "system:linux"
defines
{
"HAVE_FCNTL_H",--fix error in ftsystem.c <implicit declaration of function open>
"HAVE_UNISTD_H" --fix error in ftsystem.c <implicit declaration of function read>
}
filter"system:windows"
files
{
path.join(scriptdir, "freetype/builds/windows/ftsystem.c"),
path.join(scriptdir, "freetype/builds/windows/ftdebug.c"),
}
filter"system:linux"
files{path.join(scriptdir, "freetype/builds/unix/ftsystem.c")}
filter "configurations:Debug"
optimize"Speed"
filter""
end
function m.link()
externalincludedirs{path.join(scriptdir, "freetype/include")}
links {"freetype"}
end
return m

View File

@ -1,43 +0,0 @@
local m = {}
local scriptdir = path.getabsolute(path.getdirectory(_SCRIPT))
local sfml = require("build-sfml")
function m.generateproject(liboutdir, intdir)
project"imgui-sfml"
cppdialect"c++17"
kind"staticLib"
targetdir (liboutdir)
objdir(intdir)
warnings"Off"
defines{"IMGUI_USER_CONFIG=\"imconfig-SFML.h\""}
sfml.link()
includedirs
{
path.join(scriptdir, "imgui-sfml"),
path.join(scriptdir, "imgui"),
}
files
{
path.join(scriptdir, "imgui-sfml/imgui-SFML.cpp"),
}
end
function m.config() -- use this in build imgui instead of link() to avoid circular dependency
defines { "IMGUI_USER_CONFIG=\"imconfig-SFML.h\"" }
externalincludedirs { path.join(scriptdir, "imgui-sfml") }
sfml.link()
end
function m.link()
links {"imgui-sfml"}
m.config()
end
return m

View File

@ -1,36 +0,0 @@
local m = {}
local scriptdir = path.getabsolute(path.getdirectory(_SCRIPT))
local imguisfml = require("build-imgui-sfml")
function m.generateproject(liboutdir, intdir)
project"imgui"
cppdialect"c++17"
kind"staticLib"
targetdir (liboutdir)
objdir(intdir)
warnings"Off"
imguisfml.config() -- needed so imgui can be aware of imconfig-sfml.h
includedirs
{
path.join(scriptdir, "imgui"),
}
files
{
path.join(scriptdir, "imgui/imgui.cpp"),
path.join(scriptdir, "imgui/imgui_draw.cpp"),
path.join(scriptdir, "imgui/imgui_tables.cpp"),
path.join(scriptdir, "imgui/imgui_widgets.cpp"),
}
end
function m.link()
links {"imgui"}
externalincludedirs { path.join(scriptdir, "imgui") }
end
return m

28
vendor/build-ogg.lua vendored
View File

@ -1,28 +0,0 @@
local m = {}
local scriptdir = path.getabsolute(path.getdirectory(_SCRIPT))
function m.generateproject(liboutdir, intdir)
project"ogg"
language"C" -- c++ will mangle names and sfml wont build
kind"staticLib"
targetdir (liboutdir)
objdir(intdir)
warnings"Off"
includedirs {path.join(scriptdir, "ogg/include")}
files
{
path.join(scriptdir, "ogg/src/**.h"),
path.join(scriptdir, "ogg/src/**.c"),
}
end
function m.link()
links{"ogg"}
externalincludedirs{path.join(scriptdir, "ogg/include")}
end
return m

118
vendor/build-sfml.lua vendored
View File

@ -1,118 +0,0 @@
local m = {}
local scriptdir = path.getabsolute(path.getdirectory(_SCRIPT))
local ogg = require("build-ogg")
local flac = require("build-flac")
local vorbis = require("build-vorbis")
local freetype = require("build-freetype")
function m.generateproject(liboutdir, intdir)
project"sfml"
cppdialect"c++17"
kind "staticLib"
targetdir (liboutdir)
objdir(intdir)
warnings"Off"
freetype.link()
ogg.link()
flac.link()
vorbis.link()
defines
{
"SFML_STATIC",
"MA_NO_MP3",
"MA_NO_FLAC",
"MA_NO_ENCODING",
"MA_NO_RESOURCE_MANAGER",
"MA_NO_GENERATION",
"MA_USE_STDINT",
"STBI_FAILURE_USERMSG",
"SFML_IS_BIG_ENDIAN=0",
"FT2_BUILD_LIBRARY",
"FLAC__NO_DLL",
"OV_EXCLUDE_STATIC_CALLBACKS",
}
includedirs
{
path.join(scriptdir, "SFML/include"),
path.join(scriptdir, "SFML/src"),
path.join(scriptdir, "SFML/extlibs/headers/glad/include"),
path.join(scriptdir, "SFML/extlibs/headers/mingw"),
path.join(scriptdir, "SFML/extlibs/headers/miniaudio"),
path.join(scriptdir, "SFML/extlibs/headers/minimp3"),
path.join(scriptdir, "SFML/extlibs/headers/stb_image"),
path.join(scriptdir, "SFML/extlibs/headers/vulkan"),
}
files
{
path.join(scriptdir, "SFML/include/SFML/**.hpp"),
path.join(scriptdir, "SFML/include/SFML/**.inl"),
path.join(scriptdir, "SFML/src/SFML/**.hpp"),
path.join(scriptdir, "SFML/src/SFML/**.cpp"),
}
filter"system:windows"
removefiles
{
path.join(scriptdir, "SFML/src/SFML/System/Unix/**"),
path.join(scriptdir, "SFML/src/SFML/System/Andriod/**"),
path.join(scriptdir, "SFML/src/SFML/Window/Unix/**"),
path.join(scriptdir, "SFML/src/SFML/Network/Unix/**"),
path.join(scriptdir, "SFML/src/SFML/Window/OpenBSD/**"),
path.join(scriptdir, "SFML/src/SFML/Window/NetBSD/**"),
path.join(scriptdir, "SFML/src/SFML/Window/macOS/**"),
path.join(scriptdir, "SFML/src/SFML/Window/iOS/**"),
path.join(scriptdir, "SFML/src/SFML/Window/FreeBSD/**"),
path.join(scriptdir, "SFML/src/SFML/Window/DRM/**"),
path.join(scriptdir, "SFML/src/SFML/Window/Android/**"),
path.join(scriptdir, "SFML/src/SFML/System/Android/**"),
}
filter"system:linux"
removefiles
{
path.join(scriptdir, "SFML/src/SFML/System/Android/**"),
path.join(scriptdir, "SFML/src/SFML/System/Win32/**"),
path.join(scriptdir, "SFML/src/SFML/Network/Win32/**"),
path.join(scriptdir, "SFML/src/SFML/Window/Win32/**"),
path.join(scriptdir, "SFML/src/SFML/Window/OpenBSD/**"),
path.join(scriptdir, "SFML/src/SFML/Window/NetBSD/**"),
path.join(scriptdir, "SFML/src/SFML/Window/macOS/**"),
path.join(scriptdir, "SFML/src/SFML/Window/iOS/**"),
path.join(scriptdir, "SFML/src/SFML/Window/FreeBSD/**"),
path.join(scriptdir, "SFML/src/SFML/Window/DRM/**"),
path.join(scriptdir, "SFML/src/SFML/Window/Android/**"),
path.join(scriptdir, "SFML/src/SFML/Main/**"),
}
filter""
end
function m.link()
defines{"SFML_STATIC"}
externalincludedirs
{
path.join(scriptdir, "SFML/include"),
}
links{"sfml"}
freetype.link()
flac.link()
vorbis.link()
ogg.link()
filter"system:windows"
links{"legacy_stdio_definitions", "opengl32", "gdi32", "winmm", "ws2_32"}
filter"system:linux"
links{"Xi", "Xrandr", "Xcursor", "X11", "udev", "pthread", "OpenGL"}
end
return m

View File

@ -1,79 +0,0 @@
local m = {}
local scriptdir = path.getabsolute(path.getdirectory(_SCRIPT))
local ogg = require("build-ogg")
function m.generateproject(liboutdir, intdir)
project"vorbis"
language"C" -- c++ will mangle names and sfml wont build
kind"staticLib"
targetdir (liboutdir)
objdir(intdir)
warnings"Off"
ogg.link()
includedirs
{
path.join(scriptdir, "vorbis/include"),
path.join(scriptdir, "vorbis/lib"),
}
files
{
path.join(scriptdir, "vorbis/lib/envelope.h"),
path.join(scriptdir, "vorbis/lib/lpc.h"),
path.join(scriptdir, "vorbis/lib/lsp.h"),
path.join(scriptdir, "vorbis/lib/codebook.h"),
path.join(scriptdir, "vorbis/lib/misc.h"),
path.join(scriptdir, "vorbis/lib/psy.h"),
path.join(scriptdir, "vorbis/lib/masking.h"),
path.join(scriptdir, "vorbis/lib/os.h"),
path.join(scriptdir, "vorbis/lib/mdct.h"),
path.join(scriptdir, "vorbis/lib/smallft.h"),
path.join(scriptdir, "vorbis/lib/highlevel.h"),
path.join(scriptdir, "vorbis/lib/registry.h"),
path.join(scriptdir, "vorbis/lib/scales.h"),
path.join(scriptdir, "vorbis/lib/window.h"),
path.join(scriptdir, "vorbis/lib/lookup.h"),
path.join(scriptdir, "vorbis/lib/lookup_data.h"),
path.join(scriptdir, "vorbis/lib/codec_internal.h"),
path.join(scriptdir, "vorbis/lib/backends.h"),
path.join(scriptdir, "vorbis/lib/bitrate.h"),
path.join(scriptdir, "vorbis/lib/mdct.c"),
path.join(scriptdir, "vorbis/lib/smallft.c"),
path.join(scriptdir, "vorbis/lib/block.c"),
path.join(scriptdir, "vorbis/lib/envelope.c"),
path.join(scriptdir, "vorbis/lib/window.c"),
path.join(scriptdir, "vorbis/lib/lsp.c"),
path.join(scriptdir, "vorbis/lib/lpc.c"),
path.join(scriptdir, "vorbis/lib/analysis.c"),
path.join(scriptdir, "vorbis/lib/synthesis.c"),
path.join(scriptdir, "vorbis/lib/psy.c"),
path.join(scriptdir, "vorbis/lib/info.c"),
path.join(scriptdir, "vorbis/lib/floor1.c"),
path.join(scriptdir, "vorbis/lib/floor0.c"),
path.join(scriptdir, "vorbis/lib/res0.c"),
path.join(scriptdir, "vorbis/lib/mapping0.c"),
path.join(scriptdir, "vorbis/lib/registry.c"),
path.join(scriptdir, "vorbis/lib/codebook.c"),
path.join(scriptdir, "vorbis/lib/sharedbook.c"),
path.join(scriptdir, "vorbis/lib/lookup.c"),
path.join(scriptdir, "vorbis/lib/bitrate.c"),
path.join(scriptdir, "vorbis/lib/vorbisfile.c"),
path.join(scriptdir, "vorbis/lib/vorbisenc.c"),
}
filter""
end
function m.link()
links {"vorbis"}
ogg.link()
externalincludedirs
{
path.join(scriptdir, "vorbis/include"),
}
end
return m

1
vendor/flac vendored

@ -1 +0,0 @@
Subproject commit 28e4f0528c76b296c561e922ba67d43751990599

1
vendor/freetype vendored

@ -1 +0,0 @@
Subproject commit 920c5502cc3ddda88f6c7d85ee834ac611bb11cc

1
vendor/imgui vendored

@ -1 +0,0 @@
Subproject commit 97428e8ac99e339ce05eee531cf55b77b29ea709

1
vendor/imgui-sfml vendored

@ -1 +0,0 @@
Subproject commit 5e8f8fb857c8f3cff1096bf3e4402c64e3bcf6af

1
vendor/ogg vendored

@ -1 +0,0 @@
Subproject commit e1774cd77f471443541596e09078e78fdc342e4f

View File

@ -1,27 +0,0 @@
Copyright (c) 2003-2022 Jess Perkins and individual contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of Premake nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2022, Matvey Bystrin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,49 +0,0 @@
# Export Compile Commands - ECC
Module implementing support for [JSON Compilation Database Format
Specification](https://clang.llvm.org/docs/JSONCompilationDatabase.html).
This is an alternative to
[tarruda's](https://github.com/tarruda/premake-export-compile-commands) module,
which does one simple thing - generates one `compile_commands.json` file for
your project.
Tested with clangd-13.
## Requirements
Premake 5.0.0 or later.
## How to use
Download premake-ecc and place it near your premake5.lua script. Then require it
from your premake script
```lua
require "ecc/ecc"
```
After you simply can call:
```
premake5 ecc
```
Moldule will generate **one** `compile_commands.json` file near your main
premake script. During generation it will use the default config (the first one
you have specified in script). If you want to select specific config just pass
it's name with command line option:
```
premake5 --config=release ecc
```
Careful! `config` option case sensitive! If there is no config passed via
command line, module will choose the default one.
Note: if you want to embed this module into your premake build follow
the [manual](https://premake.github.io/docs/Embedding-Modules/)
## Future plans
- Add unit tests
## Alternatives
- [export-compile-commands](https://github.com/tarruda/premake-export-compile-commands)
- [bear](https://github.com/rizsotto/Bear)

View File

@ -1,4 +0,0 @@
return {
"_preload.lua",
"ecc.lua"
}

View File

@ -1,35 +0,0 @@
local p = premake
newoption {
trigger = "config",
value = "CFG",
description = "Select config for export compile_commands.json"
}
newaction {
trigger = "ecc",
shortname = "Export compile commands",
description = "Export compile_commands.json for language server",
toolset = "gcc",
valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" },
valid_languages = { "C", "C++" },
valid_tools = {
cc = { "clang", "gcc" }
},
onStart = function()
p.indent(" ")
end,
execute = function()
local dir = {}
dir.location = _MAIN_SCRIPT_DIR
p.generate(dir, "compile_commands.json", p.modules.ecc.generateFile)
end
}
return function(cfg)
return (_ACTION == "ecc")
end

View File

@ -1,122 +0,0 @@
-- Include module if it is not embedded
if premake.modules.ecc == nil then
include ( "_preload.lua" )
end
local p = premake
local project = p.project
p.modules.ecc = {}
local m = p.modules.ecc
m._VERSION = "1.0.1-alpha"
function m.generateFile()
p.push("[")
for wks in p.global.eachWorkspace() do
for prj in p.workspace.eachproject(wks) do
m.onProject(prj)
end
end
p.pop("]")
end
function m.onProject(prj)
if project.isc(prj) or project.iscpp(prj) then
local cfg = m.getConfig(prj)
local args = m.getArguments(prj, cfg)
local files = table.shallowcopy(prj._.files)
for i,node in ipairs(files) do
local output = cfg.objdir .. "/" .. node.objname .. ".o"
local obj = path.getrelative(prj.location, output)
p.push("{")
p.push("\"arguments\": [")
m.writeArgs(args, obj, node.relpath)
p.pop("],")
p.w("\"directory\": \"%s\",", prj.location)
p.w("\"file\": \"%s\",", node.abspath)
p.w("\"output\": \"%s\"", output)
p.pop("},")
end
end
end
function m.writeArgs(args, obj, src)
for _,arg in ipairs(args) do
-- Defines like the following will break JSON format, quotes need to be escaped
-- -DEXPORT_API=__attribute__((visibility("default")))
local escaped = arg:gsub("\"", "\\\"")
p.w("\"%s\",", escaped)
end
p.w("\"-c\",")
p.w("\"-o\",")
p.w("\"%s\",", obj)
p.w("\"%s\"", src)
end
function m.getConfig(prj)
local ocfg = _OPTIONS.config
local cfg = {}
if ocfg and prj.configs[ocfg] then
cfg = prj.configs[ocfg]
else
cfg = m.defaultconfig(prj)
end
return cfg
end
function m.getArguments(prj, cfg)
local toolset = m.getToolSet(cfg)
local args = {}
local tool = iif(project.iscpp(prj), "cxx", "cc")
local toolname = iif(cfg.prefix, toolset.gettoolname(cfg, tool), toolset.tools[tool])
args = table.join(args, toolname)
args = table.join(args, toolset.getcppflags(cfg)) -- Preprocessor
args = table.join(args, toolset.getdefines(cfg.defines))
args = table.join(args, toolset.getundefines(cfg.undefines))
args = table.join(args, toolset.getincludedirs(cfg, cfg.includedirs, cfg.sysincludedirs))
if project.iscpp(prj) then
args = table.join(args, toolset.getcxxflags(cfg))
else
args = table.join(args, toolset.getcflags(cfg))
end
args = table.join(args, cfg.buildoptions)
return args
end
-- Copied from gmake2 module
-- Return default toolset of given config or system default toolset
function m.getToolSet(cfg)
local default = iif(cfg.system == p.MACOSX, "clang", "gcc")
local toolset = p.tools[_OPTIONS.cc or cfg.toolset or default]
if not toolset then
error("Invalid toolset '" .. cfg.toolset .. "'")
end
return toolset
end
-- Copied from gmake2 module
function m.defaultconfig(target)
-- find the right configuration iterator function for this object
local eachconfig = iif(target.project, project.eachconfig, p.workspace.eachconfig)
local defaultconfig = nil
-- find the right default configuration platform, grab first configuration that matches
if target.defaultplatform then
for cfg in eachconfig(target) do
if cfg.platform == target.defaultplatform then
defaultconfig = cfg
break
end
end
end
-- grab the first configuration and write the block
if not defaultconfig then
local iter = eachconfig(target)
defaultconfig = iter()
end
return defaultconfig
end

View File

@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015 Dmitry Ivanov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,44 +0,0 @@
# premake-ninja
[Premake](https://github.com/premake/premake-core) module to support [Ninja](https://github.com/martine/ninja), because it's awesome.
Note recent version of premake handles ninja natively
## Usage (little reminder)
1. Put these files in a "premake-ninja" subdirectory of [Premake search paths](https://premake.github.io/docs/Locating-Scripts/).<br>
2. Adapt your premake5.lua script, or better: create/adapt your [premake-system.lua](https://premake.github.io/docs/System-Scripts/)
```lua
require "premake-ninja/ninja"
```
3. Generate ninja files
```sh
premake5 premake-ninja
```
On msys2 (mingw)
```sh
premake5 ninja --cc=gcc --shell=posix
```
4. Run ninja
For each project - configuration pair, we create separate .ninja file. For solution we create build.ninja file which imports other .ninja files with subninja command.
Build.ninja file sets phony targets for configuration names so you can build them from command line. And default target is the first configuration name in your project (usually default).
General from:
```sh
ninja $(YourProjectName)_$(ConfigName)
```
as example:
```sh
ninja myapp_Release
```
### Tested on ![ubuntu-badge](https://github.com/jimon/premake-ninja/actions/workflows/ubuntu.yml/badge.svg) ![windows-badge](https://github.com/jimon/premake-ninja/actions/workflows/windows.yml/badge.svg) ![macos-badge](https://github.com/jimon/premake-ninja/actions/workflows/macos.yml/badge.svg)
### Extra Tests
Part of integration tests of several generators in https://github.com/Jarod42/premake-sample-projects ![Premake5 ubuntu ninja badge](https://github.com/Jarod42/premake-sample-projects/actions/workflows/premake5-ubuntu-ninja.yml/badge.svg)![Premake5 window ninja badge](https://github.com/Jarod42/premake-sample-projects/actions/workflows/premake5-windows-ninja.yml/badge.svg)

View File

@ -1,4 +0,0 @@
return {
'_preload.lua',
'ninja.lua',
}

View File

@ -1,61 +0,0 @@
--
-- Name: premake-ninja/_preload.lua
-- Purpose: Define the ninja action.
-- Author: Dmitry Ivanov
-- Created: 2015/07/04
-- Copyright: (c) 2015 Dmitry Ivanov
--
local p = premake
newaction {
-- Metadata for the command line and help system
trigger = 'premake-ninja',
shortname = 'ninja',
description = 'Ninja is a small build system with a focus on speed',
-- The capabilities of this action
valid_kinds = { 'ConsoleApp', 'WindowedApp', 'SharedLib', 'StaticLib', 'None' }, -- Not supported: Makefile, Packaging, SharedItems, Utility
valid_languages = { 'C', 'C++' },
valid_tools = { cc = { 'gcc', 'clang', 'msc', 'emcc' } },
toolset = iif(
os.target() == 'windows',
'msc-v142', -- Visual Studio 2019
iif(os.target() == 'macosx', 'clang', 'gcc')
),
-- Workspace and project generation logic
onWorkspace = function(wks)
p.eol('\r\n')
p.indent(' ')
p.generate(wks, 'build.ninja', p.modules.ninja.generateWorkspace)
end,
onProject = function(prj)
p.eol('\r\n')
p.indent(' ')
p.modules.ninja.generateProject(prj)
end,
onBranch = function(prj)
p.eol('\r\n')
p.indent(' ')
p.modules.ninja.generateProject(prj)
end,
onCleanSolution = function(sln)
-- TODO
end,
onCleanProject = function(prj)
-- TODO
end,
onCleanTarget = function(prj)
-- TODO
end,
}
--
-- Decide when the full module should be loaded.
--
return function(cfg)
return (_ACTION == 'premake-ninja')
end

View File

@ -1,781 +0,0 @@
--
-- Name: premake-ninja/ninja.lua
-- Purpose: Define the ninja action.
-- Author: Dmitry Ivanov
-- Created: 2015/07/04
-- Copyright: (c) 2015 Dmitry Ivanov
--
local p = premake
local tree = p.tree
local project = p.project
local config = p.config
local fileconfig = p.fileconfig
-- Some toolset fixes/helper
p.tools.clang.objectextension = '.o'
p.tools.gcc.objectextension = '.o'
p.tools.msc.objectextension = '.obj'
p.tools.clang.tools.rc = p.tools.clang.tools.rc or 'windres'
p.tools.msc.gettoolname = function(cfg, name)
local map = { cc = 'cl', cxx = 'cl', ar = 'lib', rc = 'rc' }
return map[name]
end
-- Ninja module
premake.modules.ninja = {}
local ninja = p.modules.ninja
ninja.handlers = {}
function ninja.register_handler(kind, compilation_rules, target_rules)
ninja.handlers[kind] = { compilation_rules = compilation_rules, target_rules = target_rules }
end
local function get_key(cfg, name)
local name = name or cfg.project.name
if cfg.platform then
return name .. '_' .. cfg.buildcfg .. '_' .. cfg.platform
else
return name .. '_' .. cfg.buildcfg
end
end
local build_cache = {}
function ninja.add_build(cfg, out, implicit_outputs, command, inputs, implicit_inputs, dependencies, vars)
implicit_outputs = ninja.list(table.translate(implicit_outputs, ninja.esc))
if #implicit_outputs > 0 then
implicit_outputs = ' |' .. implicit_outputs
else
implicit_outputs = ''
end
inputs = ninja.list(table.translate(inputs, ninja.esc))
implicit_inputs = ninja.list(table.translate(implicit_inputs, ninja.esc))
if #implicit_inputs > 0 then
implicit_inputs = ' |' .. implicit_inputs
else
implicit_inputs = ''
end
dependencies = ninja.list(table.translate(dependencies, ninja.esc))
if #dependencies > 0 then
dependencies = ' ||' .. dependencies
else
dependencies = ''
end
build_line = 'build ' .. ninja.esc(out) .. implicit_outputs .. ': ' .. command .. inputs .. implicit_inputs .. dependencies
local cached = build_cache[out]
if cached ~= nil then
if build_line == cached.build_line and table.equals(vars or {}, cached.vars or {}) then
-- custom_command/copy rule are identical for each configuration (contrary to other rules)
-- So we can compare extra parameter
if command == 'custom_command' or command == 'copy' then
p.outln('# INFO: Rule ignored, same as ' .. cached.cfg_key)
else
local cfg_key = cfg and get_key(cfg) or 'Global scope'
p.warn(cached.cfg_key .. ' and ' .. cfg_key .. ' both generate (differently?) ' .. out .. '. Ignoring ' .. cfg_key)
p.outln('# WARNING: Rule ignored, using the one from ' .. cached.cfg_key)
end
else
local cfg_key = cfg and get_key(cfg) or 'Global scope'
p.warn(cached.cfg_key .. ' and ' .. cfg_key .. ' both generate differently ' .. out .. '. Ignoring ' .. cfg_key)
p.outln('# ERROR: Rule ignored, using the one from ' .. cached.cfg_key)
end
p.outln('# ' .. build_line)
for i, var in ipairs(vars or {}) do
p.outln('# ' .. var)
end
return
end
p.outln(build_line)
for i, var in ipairs(vars or {}) do
p.outln(' ' .. var)
end
build_cache[out] = {
cfg_key = cfg and get_key(cfg) or 'Global scope',
build_line = build_line,
vars = vars,
}
end
local function build_command(commands, command_sep)
command_sep = command_sep or '&&'
if #commands > 1 then
local command = iif(os.shell() == 'cmd', 'cmd /c ', 'sh -c ')
return command .. ninja.quote(table.implode(commands, '', '', ' ' .. command_sep .. '$\n '))
else
return commands[1]
end
end
function ninja.emit_rule(name, command, description, opts)
opts = opts or {}
p.outln('rule ' .. name)
p.outln(' command = ' .. command)
p.outln(' description = ' .. description)
for key, value in pairs(opts) do
p.outln(' ' .. key .. ' = ' .. value)
end
p.outln('')
end
function ninja.emit_flags(name, value)
p.outln(name .. '=' .. value)
end
function ninja.esc(value)
value = value:gsub('%$', '$$') -- TODO maybe there is better way
value = value:gsub(':', '$:')
value = value:gsub('\n', '$\n')
value = value:gsub(' ', '$ ')
return value
end
function ninja.quote(value)
value = value:gsub('\\', '\\\\')
value = value:gsub("'", "\\'")
value = value:gsub('"', '\\"')
return '"' .. value .. '"'
end
-- in some cases we write file names in rule commands directly
-- so we need to propely escape them
function ninja.shesc(value)
if type(value) == 'table' then
return table.translate(value, ninja.shesc)
end
if value:find(' ') or value:find('"') or value:find('(', 1, true) or value:find(')') or value:find('|') or value:find('&') then
return ninja.quote(value)
end
return value
end
function ninja.can_generate(prj)
return p.action.supports(prj.kind) and prj.kind ~= p.NONE
end
-- generate solution that will call ninja for projects
function ninja.generateWorkspace(wks)
local oldGetDefaultSeparator = path.getDefaultSeparator
path.getDefaultSeparator = function()
return '/'
end
p.outln('# solution build file')
p.outln('# generated with premake ninja')
p.outln('')
p.outln('# build projects')
local cfgs = {} -- key is concatenated name or variant name, value is string of outputs names
local key = ''
local cfg_first = nil
local cfg_first_lib = nil
local subninjas = {}
for prj in p.workspace.eachproject(wks) do
if ninja.can_generate(prj) then
for cfg in p.project.eachconfig(prj) do
key = get_key(cfg)
if not cfgs[cfg.buildcfg] then
cfgs[cfg.buildcfg] = {}
end
table.insert(cfgs[cfg.buildcfg], key)
-- set first configuration name
if wks.defaultplatform == nil then
if (cfg_first == nil) and (cfg.kind == p.CONSOLEAPP or cfg.kind == p.WINDOWEDAPP) then
cfg_first = key
end
end
if (cfg_first_lib == nil) and (cfg.kind == p.STATICLIB or cfg.kind == p.SHAREDLIB) then
cfg_first_lib = key
end
if prj.name == wks.startproject then
if wks.defaultplatform == nil then
cfg_first = key
elseif cfg.platform == wks.defaultplatform then
if cfg_first == nil then
cfg_first = key
end
end
end
-- include other ninja file
table.insert(subninjas, ninja.esc(ninja.projectCfgFilename(cfg, true)))
p.outln('subninja ' .. ninja.esc(ninja.projectCfgFilename(cfg, true)))
end
end
end
if cfg_first == nil then
cfg_first = cfg_first_lib
end
p.outln('')
p.outln('# targets')
for cfg, outputs in spairs(cfgs) do
p.outln('build ' .. ninja.esc(cfg) .. ': phony' .. ninja.list(table.translate(outputs, ninja.esc)))
end
p.outln('')
if wks.editorintegration then
-- we need to filter out the 'file' argument, since we already output
-- the script separately.
local args = {}
for _, arg in ipairs(_ARGV) do
if not (arg:startswith('--file') or arg:startswith('/file')) then
table.insert(args, arg)
end
end
table.sort(args)
p.outln('# Rule')
ninja.emit_rule('premake', ninja.shesc(p.workspace.getrelative(wks, _PREMAKE_COMMAND)) .. ' --file=$in ' .. table.concat(ninja.shesc(args), ' '), 'run premake', { generator = 'true', restat = 'true' })
ninja.add_build(nil, 'build.ninja', subninjas, 'premake', { p.workspace.getrelative(wks, _MAIN_SCRIPT) }, {}, {}, {})
p.outln('')
end
if cfg_first then
p.outln('# default target')
p.outln('default ' .. ninja.esc(cfg_first))
p.outln('')
end
path.getDefaultSeparator = oldGetDefaultSeparator
end
function ninja.list(value)
if #value > 0 then
return ' ' .. table.concat(value, ' ')
else
return ''
end
end
local function shouldcompileasc(filecfg)
if filecfg.compileas and filecfg.compileas ~= 'Default' then
return p.languages.isc(filecfg.compileas)
end
return path.iscfile(filecfg.abspath)
end
local function shouldcompileascpp(filecfg)
if filecfg.compileas and filecfg.compileas ~= 'Default' then
return p.languages.iscpp(filecfg.compileas)
end
return path.iscppfile(filecfg.abspath)
end
local function getFileDependencies(cfg)
local dependencies = {}
if #cfg.prebuildcommands > 0 or cfg.prebuildmessage then
dependencies = { 'prebuild_' .. get_key(cfg) }
end
for i = 1, #cfg.dependson do
local dependpostfix = ''
if cfg.platform then
dependpostfix = '_' .. cfg.platform
end
table.insert(dependencies, cfg.dependson[i] .. '_' .. cfg.buildcfg .. dependpostfix)
end
return dependencies
end
local function getcflags(toolset, cfg, filecfg)
p.escaper(ninja.shesc)
local buildopt = ninja.list(filecfg.buildoptions)
local cppflags = ninja.list(toolset.getcppflags(filecfg))
local cflags = ninja.list(toolset.getcflags(filecfg))
local defines = ninja.list(table.join(toolset.getdefines(filecfg.defines, filecfg), toolset.getundefines(filecfg.undefines)))
local includes = ninja.list(toolset.getincludedirs(cfg, filecfg.includedirs, filecfg.externalincludedirs, filecfg.frameworkdirs, filecfg.includedirsafter))
local forceincludes = ninja.list(toolset.getforceincludes(cfg))
p.escaper(nil)
return buildopt .. cppflags .. cflags .. defines .. includes .. forceincludes
end
local function getcxxflags(toolset, cfg, filecfg)
p.escaper(ninja.shesc)
local buildopt = ninja.list(filecfg.buildoptions)
local cppflags = ninja.list(toolset.getcppflags(filecfg))
local cxxflags = ninja.list(toolset.getcxxflags(filecfg))
local defines = ninja.list(table.join(toolset.getdefines(filecfg.defines, filecfg), toolset.getundefines(filecfg.undefines)))
local includes = ninja.list(toolset.getincludedirs(cfg, filecfg.includedirs, filecfg.externalincludedirs, filecfg.frameworkdirs, filecfg.includedirsafter))
local forceincludes = ninja.list(toolset.getforceincludes(cfg))
p.escaper(nil)
return buildopt .. cppflags .. cxxflags .. defines .. includes .. forceincludes
end
local function getldflags(toolset, cfg)
local ldflags = ninja.list(table.join(toolset.getLibraryDirectories(cfg), toolset.getrunpathdirs(cfg, table.join(cfg.runpathdirs, config.getsiblingtargetdirs(cfg))), toolset.getldflags(cfg), cfg.linkoptions))
-- experimental feature, change install_name of shared libs
--[[
if toolset == p.tools.clang and cfg.kind == p.SHAREDLIB and cfg.buildtarget.name:endswith('.dylib') then
ldflags = ldflags .. ' -install_name ' .. cfg.buildtarget.name
end
--]]
return ldflags
end
local function getresflags(toolset, cfg, filecfg)
p.escaper(ninja.shesc)
local defines = ninja.list(toolset.getdefines(table.join(filecfg.defines, filecfg.resdefines), filecfg))
local includes = ninja.list(toolset.getincludedirs(cfg, table.join(filecfg.externalincludedirs, filecfg.includedirsafter, filecfg.includedirs, filecfg.resincludedirs), {}, {}, {}))
local options = ninja.list(cfg.resoptions)
p.escaper(nil)
return defines .. includes .. options
end
local function prebuild_rule(cfg)
if #cfg.prebuildcommands > 0 or cfg.prebuildmessage then
local commands = {}
if cfg.prebuildmessage then
commands = { os.translateCommandsAndPaths('{ECHO} ' .. cfg.prebuildmessage, cfg.workspace.basedir, cfg.workspace.location) }
end
commands = table.join(commands, os.translateCommandsAndPaths(cfg.prebuildcommands, cfg.workspace.basedir, cfg.workspace.location))
ninja.emit_rule('run_prebuild', build_command(commands, ';'), 'prebuild')
end
end
local function prelink_rule(cfg)
if #cfg.prelinkcommands > 0 or cfg.prelinkmessage then
local commands = {}
if cfg.prelinkmessage then
commands = { os.translateCommandsAndPaths('{ECHO} ' .. cfg.prelinkmessage, cfg.workspace.basedir, cfg.workspace.location) }
end
commands = table.join(commands, os.translateCommandsAndPaths(cfg.prelinkcommands, cfg.workspace.basedir, cfg.workspace.location))
ninja.emit_rule('run_prelink', build_command(commands, ';'), 'prelink')
end
end
local function postbuild_rule(cfg)
if #cfg.postbuildcommands > 0 or cfg.postbuildmessage then
local commands = {}
if cfg.postbuildmessage then
commands = { os.translateCommandsAndPaths('{ECHO} ' .. cfg.postbuildmessage, cfg.workspace.basedir, cfg.workspace.location) }
end
commands = table.join(commands, os.translateCommandsAndPaths(cfg.postbuildcommands, cfg.workspace.basedir, cfg.workspace.location))
ninja.emit_rule('run_postbuild', build_command(commands, ';'), 'postbuild')
end
end
local function c_cpp_compilation_rules(cfg, toolset, pch)
---------------------------------------------------- figure out toolset executables
local cc = toolset.gettoolname(cfg, 'cc')
local cxx = toolset.gettoolname(cfg, 'cxx')
local ar = toolset.gettoolname(cfg, 'ar')
local link = toolset.gettoolname(cfg, iif(cfg.language == 'C', 'cc', 'cxx'))
local rc = toolset.gettoolname(cfg, 'rc')
-- all paths need to be relative to the workspace output location,
-- and not relative to the project output location.
-- override the toolset getrelative function to achieve this
local getrelative = p.tools.getrelative
p.tools.getrelative = function(cfg, value)
return p.workspace.getrelative(cfg.workspace, value)
end
local all_cflags = getcflags(toolset, cfg, cfg)
local all_cxxflags = getcxxflags(toolset, cfg, cfg)
local all_ldflags = getldflags(toolset, cfg)
local all_resflags = getresflags(toolset, cfg, cfg)
if toolset == p.tools.msc then
ninja.emit_flags('CFLAGS', all_cflags)
local cc_command = cc .. ' $CFLAGS /nologo /showIncludes -c /Tc$in /Fo$out'
ninja.emit_rule('cc', cc_command, 'cc $out', { deps = 'msvc' })
ninja.emit_flags('CXXFLAGS', all_cxxflags)
local cxx_command = cxx .. ' $CXXFLAGS /nologo /showIncludes -c /Tp$in /Fo$out'
ninja.emit_rule('cxx', cxx_command, 'cxx $out', { deps = 'msvc' })
ninja.emit_flags('CFLAGS', all_cflags)
ninja.emit_rule('clangtidy_cc', build_command({ 'clang-tidy $in -- -x c $CFLAGS', cc_command }, ';'), 'cc $out', { deps = 'msvc' }, ';')
ninja.emit_flags('CXXFLAGS', all_cxxflags)
ninja.emit_rule('clangtidy_cxx', build_command({ 'clang-tidy $in -- -x c++ $CFLAGS', cxx_command }, ';'), 'cxx $out', { deps = 'msvc' }, ';')
ninja.emit_flags('RESFLAGS', all_resflags)
ninja.emit_rule('rc', rc .. ' /nologo /fo$out $in $RESFLAGS', 'rc $out')
if cfg.kind == p.STATICLIB then
ninja.emit_rule('ar', ar .. ' $in /nologo -OUT:$out', 'ar $out')
else
ninja.emit_rule('link', link .. ' $in ' .. ninja.list(ninja.shesc(toolset.getlinks(cfg, true))) .. ' /link ' .. all_ldflags .. ' /nologo /out:$out', 'link $out')
end
elseif toolset == p.tools.clang or toolset == p.tools.gcc or toolset == p.tools.emcc then
local force_include = pch and (' -include ' .. ninja.shesc(pch.placeholder)) or ''
if pch then
ninja.emit_rule('build_pch', iif(cfg.language == 'C', cc .. all_cflags .. ' -x c-header', cxx .. all_cxxflags .. ' -x c++-header') .. ' -H -MF $out.d -c -o $out $in', 'build_pch $out', { depfile = '$out.d', deps = 'gcc' })
end
ninja.emit_flags('CFLAGS', all_cflags)
local cc_command = cc .. ' $CFLAGS' .. force_include .. ' -x c -MF $out.d -c -o $out $in'
ninja.emit_rule('cc', cc_command, 'cc $out', { depfile = '$out.d', deps = 'gcc' })
ninja.emit_flags('CXXFLAGS', all_cxxflags)
local cxx_command = cxx .. ' $CXXFLAGS' .. force_include .. ' -x c++ -MF $out.d -c -o $out $in'
ninja.emit_rule('cxx', cxx_command, 'cxx $out', { depfile = '$out.d', deps = 'gcc' })
ninja.emit_flags('CFLAGS', all_cflags)
ninja.emit_rule('clangtidy_cc', build_command({ 'clang-tidy $in -- -x c $CFLAGS' .. force_include, cc_command }, ';'), 'cc $out', { depfile = '$out.d', deps = 'gcc' }, ';')
ninja.emit_flags('CXXFLAGS', all_cxxflags)
ninja.emit_rule('clangtidy_cxx', build_command({ 'clang-tidy $in -- -x c++ $CFLAGS' .. force_include, cxx_command }, ';'), 'cxx $out', { depfile = '$out.d', deps = 'gcc' }, ';')
ninja.emit_flags('RESFLAGS', all_resflags)
if rc then
ninja.emit_rule('rc', rc .. ' -i $in -o $out $RESFLAGS', 'rc $out')
end
if ar and cfg.kind == p.STATICLIB then
ninja.emit_rule('ar', ar .. ' rcs $out $in', 'ar $out')
else
local groups = iif(cfg.linkgroups == premake.ON, { '-Wl,--start-group ', ' -Wl,--end-group' }, { '', '' })
ninja.emit_rule('link', link .. ' -o $out ' .. groups[1] .. '$in' .. ninja.list(ninja.shesc(toolset.getlinks(cfg, true, true))) .. all_ldflags .. groups[2], 'link $out')
end
end
p.tools.getrelative = getrelative
end
local function custom_command_rule()
ninja.emit_rule('custom_command', '$CUSTOM_COMMAND', '$CUSTOM_DESCRIPTION')
end
local function copy_rule()
ninja.emit_rule('copy', os.translateCommands('{COPYFILE} $in $out'), 'copy $in $out')
end
local function collect_generated_files(prj, cfg)
local generated_files = {}
tree.traverse(project.getsourcetree(prj), {
onleaf = function(node, depth)
function append_to_generated_files(filecfg)
local outputs = project.getrelative(prj.workspace, filecfg.buildoutputs)
generated_files = table.join(generated_files, outputs)
end
local filecfg = fileconfig.getconfig(node, cfg)
if not filecfg or filecfg.flags.ExcludeFromBuild then
return
end
local rule = p.global.getRuleForFile(node.name, prj.rules)
if fileconfig.hasCustomBuildRule(filecfg) then
append_to_generated_files(filecfg)
elseif rule then
local environ = table.shallowcopy(filecfg.environ)
if rule.propertydefinition then
p.rule.prepareEnvironment(rule, environ, cfg)
p.rule.prepareEnvironment(rule, environ, filecfg)
end
local rulecfg = p.context.extent(rule, environ)
append_to_generated_files(rulecfg)
end
end,
}, false, 1)
return generated_files
end
local function pch_build(cfg, pch)
local pch_dependency = {}
if pch then
pch_dependency = { pch.gch }
ninja.add_build(cfg, pch.gch, {}, 'build_pch', { pch.input }, {}, {}, {})
end
return pch_dependency
end
local function custom_command_build(prj, cfg, filecfg, filename, file_dependencies)
local outputs = project.getrelative(prj.workspace, filecfg.buildoutputs)
local output = outputs[1]
table.remove(outputs, 1)
local commands = {}
if filecfg.buildmessage then
commands = { os.translateCommandsAndPaths('{ECHO} ' .. filecfg.buildmessage, prj.workspace.basedir, prj.workspace.location) }
end
commands = table.join(commands, os.translateCommandsAndPaths(filecfg.buildcommands, prj.workspace.basedir, prj.workspace.location))
if #commands > 1 then
commands = 'sh -c ' .. ninja.quote(table.implode(commands, '', '', ';'))
else
commands = commands[1]
end
ninja.add_build(cfg, output, outputs, 'custom_command', { filename }, project.getrelative(prj.workspace, filecfg.buildinputs), file_dependencies, { 'CUSTOM_COMMAND = ' .. commands, 'CUSTOM_DESCRIPTION = custom build ' .. ninja.shesc(output) })
end
local function compile_file_build(cfg, filecfg, toolset, pch_dependency, regular_file_dependencies, objfiles, extrafiles)
local obj_file = filecfg.objname .. (toolset.objectextension or '.o')
local obj_dir = project.getrelative(cfg.workspace, cfg.objdir)
local filepath = project.getrelative(cfg.workspace, filecfg.abspath)
local has_custom_settings = fileconfig.hasFileSettings(filecfg)
local use_clangtidy = filecfg.clangtidy or (filecfg.clangtidy == nil and cfg.clangtidy)
if use_clangtidy and toolset == p.tools.msc then
premake.warnOnce('clang-tidy_msc', 'Turn off clang-tidy when using msc (flags might differ too much between the tools).')
use_clangtidy = false
end
if filecfg.buildaction == 'None' then
return
elseif filecfg.buildaction == 'Copy' then
local target = project.getrelative(cfg.workspace, path.join(cfg.targetdir, filecfg.name))
ninja.add_build(cfg, target, {}, 'copy', { filepath }, {}, {}, {})
extrafiles[#extrafiles + 1] = target
elseif shouldcompileasc(filecfg) then
local objfilename = obj_dir .. '/' .. obj_file
objfiles[#objfiles + 1] = objfilename
local vars = {}
if has_custom_settings then
vars = { 'CFLAGS = $CFLAGS ' .. getcflags(toolset, cfg, filecfg) }
end
ninja.add_build(cfg, objfilename, {}, iif(use_clangtidy, 'clangtidy_cc', 'cc'), { filepath }, pch_dependency, regular_file_dependencies, vars)
elseif shouldcompileascpp(filecfg) then
local objfilename = obj_dir .. '/' .. obj_file
objfiles[#objfiles + 1] = objfilename
local vars = {}
if has_custom_settings then
vars = { 'CXXFLAGS = $CXXFLAGS ' .. getcxxflags(toolset, cfg, filecfg) }
end
ninja.add_build(cfg, objfilename, {}, iif(use_clangtidy, 'clangtidy_cxx', 'cxx'), { filepath }, pch_dependency, regular_file_dependencies, vars)
elseif path.isresourcefile(filecfg.abspath) then
local objfilename = obj_dir .. '/' .. filecfg.basename .. '.res'
objfiles[#objfiles + 1] = objfilename
local resflags = {}
if has_custom_settings then
resflags = { 'RESFLAGS = $RESFLAGS ' .. getresflags(toolset, cfg, filecfg) }
end
local rc = toolset.gettoolname(cfg, 'rc')
if rc then
ninja.add_build(cfg, objfilename, {}, 'rc', { filepath }, {}, {}, resflags)
else
p.warnOnce(filepath, string.format('Ignored resource: "%s"', filepath))
end
end
end
local function files_build(prj, cfg, toolset, pch_dependency, regular_file_dependencies, file_dependencies)
local objfiles = {}
local extrafiles = {}
tree.traverse(project.getsourcetree(prj), {
onleaf = function(node, depth)
local filecfg = fileconfig.getconfig(node, cfg)
if not filecfg or filecfg.flags.ExcludeFromBuild then
return
end
local rule = p.global.getRuleForFile(node.name, prj.rules)
local filepath = project.getrelative(cfg.workspace, node.abspath)
if fileconfig.hasCustomBuildRule(filecfg) then
custom_command_build(prj, cfg, filecfg, filepath, file_dependencies)
elseif rule then
local environ = table.shallowcopy(filecfg.environ)
if rule.propertydefinition then
p.rule.prepareEnvironment(rule, environ, cfg)
p.rule.prepareEnvironment(rule, environ, filecfg)
end
local rulecfg = p.context.extent(rule, environ)
custom_command_build(prj, cfg, rulecfg, filepath, file_dependencies)
else
compile_file_build(cfg, filecfg, toolset, pch_dependency, regular_file_dependencies, objfiles, extrafiles)
end
end,
}, false, 1)
p.outln('')
return objfiles, extrafiles
end
local function generated_files_build(cfg, generated_files, key)
local final_dependency = {}
if #generated_files > 0 then
p.outln('# generated files')
ninja.add_build(cfg, 'generated_files_' .. key, {}, 'phony', generated_files, {}, {}, {})
final_dependency = { 'generated_files_' .. key }
end
return final_dependency
end
-- generate project + config build file
function ninja.generateProjectCfg(cfg)
local oldGetDefaultSeparator = path.getDefaultSeparator
path.getDefaultSeparator = function()
return '/'
end
local prj = cfg.project
local key = get_key(cfg)
local toolset, toolset_version = p.tools.canonical(cfg.toolset)
if not toolset then
p.error('Unknown toolset ' .. cfg.toolset)
end
-- Some toolset fixes
cfg.gccprefix = cfg.gccprefix or ''
p.outln('# project build file')
p.outln('# generated with premake ninja')
p.outln('')
-- premake-ninja relies on scoped rules
-- and they were added in ninja v1.6
p.outln('ninja_required_version = 1.6')
p.outln('')
local is_c_or_cpp = cfg.language == p.C or cfg.language == p.CPP
---------------------------------------------------- figure out settings
local pch = nil
if is_c_or_cpp and toolset ~= p.tools.msc then
pch = p.tools.gcc.getpch(cfg)
if pch then
pch = {
input = pch,
placeholder = project.getrelative(cfg.workspace, path.join(cfg.objdir, path.getname(pch))),
gch = project.getrelative(cfg.workspace, path.join(cfg.objdir, path.getname(pch) .. '.gch')),
}
end
end
---------------------------------------------------- write rules
p.outln('# core rules for ' .. cfg.name)
prebuild_rule(cfg)
prelink_rule(cfg)
postbuild_rule(cfg)
if is_c_or_cpp then
c_cpp_compilation_rules(cfg, toolset, pch)
else
local handler = ninja.handlers[cfg.language]
if not handler then
p.error('expected registered ninja handler action for target ' .. cfg.language)
end
handler.compilation_rules(cfg, toolset)
end
copy_rule()
custom_command_rule()
---------------------------------------------------- build all files
p.outln('# build files')
local pch_dependency = is_c_or_cpp and pch_build(cfg, pch) or {}
local generated_files = collect_generated_files(prj, cfg)
local file_dependencies = getFileDependencies(cfg)
local regular_file_dependencies = table.join(iif(#generated_files > 0, { 'generated_files_' .. key }, {}), file_dependencies)
local obj_dir = project.getrelative(cfg.workspace, cfg.objdir)
local objfiles, extrafiles = files_build(prj, cfg, toolset, pch_dependency, regular_file_dependencies, file_dependencies)
local final_dependency = generated_files_build(cfg, generated_files, key)
---------------------------------------------------- build final target
if #cfg.prebuildcommands > 0 or cfg.prebuildmessage then
p.outln('# prebuild')
ninja.add_build(cfg, 'prebuild_' .. get_key(cfg), {}, 'run_prebuild', {}, {}, {}, {})
end
local prelink_dependency = {}
if #cfg.prelinkcommands > 0 or cfg.prelinkmessage then
p.outln('# prelink')
ninja.add_build(cfg, 'prelink_' .. get_key(cfg), {}, 'run_prelink', {}, objfiles, final_dependency, {})
prelink_dependency = { 'prelink_' .. get_key(cfg) }
end
if #cfg.postbuildcommands > 0 or cfg.postbuildmessage then
p.outln('# postbuild')
ninja.add_build(cfg, 'postbuild_' .. get_key(cfg), {}, 'run_postbuild', {}, { ninja.outputFilename(cfg) }, {}, {})
end
if is_c_or_cpp then
-- we don't pass getlinks(cfg) through dependencies
-- because system libraries are often not in PATH so ninja can't find them
local libs = table.translate(config.getlinks(cfg, 'siblings', 'fullpath'), function(p)
return project.getrelative(cfg.workspace, path.join(cfg.project.location, p))
end)
local cfg_output = ninja.outputFilename(cfg)
local extra_outputs = {}
local command_rule = ''
if cfg.kind == p.STATICLIB then
p.outln('# link static lib')
command_rule = 'ar'
elseif cfg.kind == p.SHAREDLIB then
p.outln('# link shared lib')
command_rule = 'link'
extra_outputs = iif(os.target() == 'windows', { path.replaceextension(cfg_output, '.lib'), path.replaceextension(cfg_output, '.exp') }, {})
elseif (cfg.kind == p.CONSOLEAPP) or (cfg.kind == p.WINDOWEDAPP) then
p.outln('# link executable')
command_rule = 'link'
else
p.error("ninja action doesn't support this kind of target " .. cfg.kind)
end
local deps = table.join(final_dependency, extrafiles, prelink_dependency)
ninja.add_build(cfg, cfg_output, extra_outputs, command_rule, table.join(objfiles, libs), {}, deps, {})
outputs = { cfg_output }
else
local handler = ninja.handlers[cfg.language]
if not handler then
p.error('expected registered ninja handler action for target ' .. cfg.language)
end
outputs = handler.target_rules(cfg, toolset)
end
p.outln('')
if #cfg.postbuildcommands > 0 or cfg.postbuildmessage then
ninja.add_build(cfg, key, {}, 'phony', { 'postbuild_' .. get_key(cfg) }, {}, {}, {})
else
ninja.add_build(cfg, key, {}, 'phony', outputs, {}, {}, {})
end
p.outln('')
path.getDefaultSeparator = oldGetDefaultSeparator
end
-- return name of output binary relative to build folder
function ninja.outputFilename(cfg)
return project.getrelative(cfg.workspace, cfg.buildtarget.directory) .. '/' .. cfg.buildtarget.name
end
-- return name of build file for configuration
function ninja.projectCfgFilename(cfg, relative)
if relative ~= nil then
relative = project.getrelative(cfg.workspace, cfg.location) .. '/'
else
relative = ''
end
return relative .. get_key(cfg, cfg.project.filename) .. '.ninja'
end
-- generate all build files for every project configuration
function ninja.generateProject(prj)
if not ninja.can_generate(prj) then
return
end
for cfg in project.eachconfig(prj) do
p.generate(cfg, ninja.projectCfgFilename(cfg), ninja.generateProjectCfg)
end
end
include('_preload.lua')
return ninja

Binary file not shown.

Binary file not shown.

1
vendor/vorbis vendored

@ -1 +0,0 @@
Subproject commit 0657aee69dec8508a0011f47f3b69d7538e9d262