mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
Expose export-compile-commands in premake5 project.
Minor fix in Sys::getOSArchitecture.
This commit is contained in:
44
premake/export-compile-commands/README.md
Normal file
44
premake/export-compile-commands/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
## Generate compile_commands.json for premake projects
|
||||
|
||||
This module implements [JSON Compilation Database Format
|
||||
Specification](http://clang.llvm.org/docs/JSONCompilationDatabase.html) for
|
||||
premake projects.
|
||||
|
||||
Install this module somewhere premake can find it, for example:
|
||||
|
||||
```
|
||||
git clone https://github.com/tarruda/premake-export-compile-commands export-compile-commands
|
||||
```
|
||||
|
||||
Then put this at the top of your system script(eg: ~/.premake/premake-system.lua):
|
||||
|
||||
```lua
|
||||
require "export-compile-commands"
|
||||
```
|
||||
|
||||
Note that while possible, it is not recommended to put the `require` line in
|
||||
project-specific premake configuration because the "export-compile-commands"
|
||||
module will need to be installed everywhere your project is built.
|
||||
|
||||
After the above steps, the "export-compile-commands" action will be available
|
||||
for your projects:
|
||||
|
||||
```
|
||||
premake5 export-compile-commands
|
||||
```
|
||||
|
||||
The `export-compile-commands` action will generate one json file per
|
||||
config/platform combination in each workspace, all under the `compile_commands`
|
||||
subdirectory. For example, say you have defined `debug` and `release`
|
||||
configurations with `x32` and `x64` platforms, the output will be something
|
||||
like:
|
||||
|
||||
```
|
||||
Generated WORKSPACE_BUILD_DIR/compile_commands/debug_x32.json...
|
||||
Generated WORKSPACE_BUILD_DIR/compile_commands/debug_x64.json...
|
||||
Generated WORKSPACE_BUILD_DIR/compile_commands/release_x32.json...
|
||||
Generated WORKSPACE_BUILD_DIR/compile_commands/release_x64.json...
|
||||
```
|
||||
|
||||
where each file contain the compilation commands for the corresponding
|
||||
config/platform combo.
|
||||
4
premake/export-compile-commands/_manifest.lua
Normal file
4
premake/export-compile-commands/_manifest.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
return {
|
||||
'_preload.lua',
|
||||
'export-compile-commands.lua',
|
||||
}
|
||||
3
premake/export-compile-commands/_preload.lua
Normal file
3
premake/export-compile-commands/_preload.lua
Normal file
@@ -0,0 +1,3 @@
|
||||
return function(cfg)
|
||||
return _ACTION == 'export-compile-commands'
|
||||
end
|
||||
210
premake/export-compile-commands/export-compile-commands.lua
Normal file
210
premake/export-compile-commands/export-compile-commands.lua
Normal file
@@ -0,0 +1,210 @@
|
||||
local p = premake
|
||||
|
||||
p.modules.export_compile_commands = {}
|
||||
local m = p.modules.export_compile_commands
|
||||
|
||||
local workspace = p.workspace
|
||||
local project = p.project
|
||||
|
||||
local function esc(s)
|
||||
s = s:gsub('\\', '\\\\')
|
||||
s = s:gsub('"', '\\"')
|
||||
return s
|
||||
end
|
||||
|
||||
local function esc_table(t)
|
||||
local res = {}
|
||||
for k, v in pairs(t) do
|
||||
table.insert(res, esc(v))
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
local function quote(s)
|
||||
return '"' .. esc(s) .. '"'
|
||||
end
|
||||
|
||||
function m.getToolset(cfg)
|
||||
return p.tools[cfg.toolset or 'gcc']
|
||||
end
|
||||
|
||||
function m.getCommonFlags(prj, cfg)
|
||||
-- some tools that consumes compile_commands.json have problems with relative include paths
|
||||
relative = project.getrelative
|
||||
project.getrelative = function(prj, dir) return dir end
|
||||
|
||||
local toolset = m.getToolset(cfg)
|
||||
local flags = toolset.getcppflags(cfg)
|
||||
flags = table.join(flags, toolset.getdefines(cfg.defines))
|
||||
flags = table.join(flags, toolset.getundefines(cfg.undefines))
|
||||
flags = table.join(flags, toolset.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs))
|
||||
flags = table.join(flags, toolset.getforceincludes(cfg))
|
||||
if project.iscpp(prj) then
|
||||
flags = table.join(flags, toolset.getcxxflags(cfg))
|
||||
elseif project.isc(prj) then
|
||||
flags = table.join(flags, toolset.getcflags(cfg))
|
||||
end
|
||||
flags = table.join(flags, cfg.buildoptions)
|
||||
project.getrelative = relative
|
||||
return flags
|
||||
end
|
||||
|
||||
function m.getObjectPath(prj, cfg, node)
|
||||
return path.join(cfg.objdir, path.appendExtension(node.objname, '.o'))
|
||||
end
|
||||
|
||||
function m.getDependenciesPath(prj, cfg, node)
|
||||
return path.join(cfg.objdir, path.appendExtension(node.objname, '.d'))
|
||||
end
|
||||
|
||||
function m.getFileFlags(prj, cfg, node)
|
||||
return table.join(m.getCommonFlags(prj, cfg), {
|
||||
'-o', quote(m.getObjectPath(prj, cfg, node)),
|
||||
'-MF', quote(m.getDependenciesPath(prj, cfg, node)),
|
||||
'-c', quote(node.abspath)
|
||||
})
|
||||
end
|
||||
|
||||
local function computesystemincludepaths(tool, iscfile)
|
||||
local cmd = tool .. " -E -v -fsyntax-only " .. (iscfile and '-x c' or '-x c++') .. ' "' .. _MAIN_SCRIPT .. '"' -- Use script as dummy "c" file
|
||||
local s,e = os.outputof(cmd, "both")
|
||||
if not s or not e then return {} end
|
||||
local s = string.match(s, "#include <...> search starts here:\n(.*)End of search list.\n")
|
||||
local includepaths = {}
|
||||
for w in string.gmatch(s, " *([^\n]+) *") do
|
||||
table.insert(includepaths, path.normalize(w))
|
||||
end
|
||||
return includepaths
|
||||
end
|
||||
|
||||
local systemincludepathscache = {}
|
||||
|
||||
local function getsystemincludepaths(tool, iscfile)
|
||||
if not systemincludepathscache[tool] then systemincludepathscache[tool] = {} end
|
||||
local toolcache = systemincludepathscache[tool]
|
||||
if not toolcache[iscfile] then toolcache[iscfile] = computesystemincludepaths(tool, iscfile) end
|
||||
return toolcache[iscfile]
|
||||
end
|
||||
|
||||
local function getsystemflags(tool, iscfile)
|
||||
return table.implode(getsystemincludepaths(tool, iscfile), ' -isystem \\"', '\\"', '')
|
||||
end
|
||||
|
||||
local function getlanguageflags(cfg)
|
||||
local toolset = m.getToolset(cfg)
|
||||
local compileas = toolset.shared and toolset.shared.compileas
|
||||
if compileas then
|
||||
return compileas[cfg.language] or ""
|
||||
end
|
||||
end
|
||||
|
||||
function m.generateCompileCommand(prj, cfg, node)
|
||||
local toolset = m.getToolset(cfg)
|
||||
local tool = path.iscfile(node.abspath) and 'cc' or 'cxx'
|
||||
cfg.gccprefix = cfg.gccprefix or "" -- hack to have gcc.gettoolname return non-nil
|
||||
local tool = toolset.gettoolname(cfg, tool) or tool
|
||||
local system_flag = getsystemflags(tool, path.iscfile(node.abspath))
|
||||
local language_flag = getlanguageflags(cfg) .. " "
|
||||
return {
|
||||
directory = prj.location,
|
||||
file = node.abspath,
|
||||
command = (tool .. system_flag .. " " .. language_flag .. table.concat(esc_table(m.getFileFlags(prj, cfg, node)), ' '))
|
||||
}
|
||||
end
|
||||
|
||||
function m.includeFile(prj, node, depth)
|
||||
return path.iscppfile(node.abspath) or path.iscfile(node.abspath) or path.iscppheader(node.abspath)
|
||||
end
|
||||
|
||||
function m.getProjectCommands(prj, cfg)
|
||||
local tr = project.getsourcetree(prj)
|
||||
local cmds = {}
|
||||
p.tree.traverse(tr, {
|
||||
onleaf = function(node, depth)
|
||||
if m.includeFile(prj, node, depth) then
|
||||
table.insert(cmds, m.generateCompileCommand(prj, cfg, node))
|
||||
end
|
||||
end
|
||||
})
|
||||
return cmds
|
||||
end
|
||||
|
||||
local function get_architecture()
|
||||
if jit then
|
||||
return jit.arch
|
||||
end
|
||||
|
||||
local handle = io.popen("uname -m 2>/dev/null")
|
||||
if handle then
|
||||
local arch = handle:read("*l")
|
||||
handle:close()
|
||||
if arch then return arch end
|
||||
end
|
||||
|
||||
local arch = os.getenv("PROCESSOR_ARCHITECTURE")
|
||||
if arch then
|
||||
if arch == "AMD64" or arch == "IA64" then
|
||||
return "x86_64"
|
||||
end
|
||||
return string.lower(arch)
|
||||
end
|
||||
|
||||
return "x86_64"
|
||||
end
|
||||
|
||||
function m.onWorkspace(wks)
|
||||
local cfgCmds = {}
|
||||
local prjLocs = {}
|
||||
for prj in workspace.eachproject(wks) do
|
||||
for cfg in project.eachconfig(prj) do
|
||||
local cfgKey = string.format('%s', cfg.shortname)
|
||||
if not cfgCmds[cfgKey] then
|
||||
cfgCmds[cfgKey] = {}
|
||||
end
|
||||
cfgCmds[cfgKey] = table.join(cfgCmds[cfgKey], m.getProjectCommands(prj, cfg))
|
||||
if not prjLocs[cfgKey] then
|
||||
prjLocs[cfgKey] = {}
|
||||
end
|
||||
prjLocs[cfgKey].location = prj.location
|
||||
end
|
||||
end
|
||||
for cfgKey,cmds in pairs(cfgCmds) do
|
||||
local outfile = string.format('%s/compile_commands.json', cfgKey)
|
||||
p.generate(wks, outfile, function(wks)
|
||||
p.push('[')
|
||||
for i = 1, #cmds do
|
||||
local item = cmds[i]
|
||||
p.push('{')
|
||||
p.x('"directory": "%s",', item.directory)
|
||||
p.x('"file": "%s",', item.file)
|
||||
p.w('"command": "%s"', item.command)
|
||||
if i ~= #cmds then
|
||||
p.pop('},')
|
||||
else
|
||||
p.pop('}')
|
||||
end
|
||||
end
|
||||
p.pop(']')
|
||||
end)
|
||||
|
||||
if cfgKey == "release_" .. get_architecture() then
|
||||
local source = path.join(prjLocs[cfgKey].location, outfile)
|
||||
local destination = path.join(os.getcwd(), "compile_commands.json")
|
||||
os.copyfile(source, destination)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newaction {
|
||||
trigger = 'export-compile-commands',
|
||||
description = 'Export compiler commands in JSON Compilation Database Format',
|
||||
onWorkspace = m.onWorkspace,
|
||||
toolset = "clang",
|
||||
valid_kinds = { "ConsoleApp", "WindowedApp", "Makefile", "SharedLib", "StaticLib", "Utility" },
|
||||
valid_languages = { "C", "C++" },
|
||||
valid_tools = {
|
||||
cc = { "gcc", "clang" }
|
||||
}
|
||||
}
|
||||
|
||||
return m
|
||||
@@ -587,6 +587,10 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
end
|
||||
end
|
||||
|
||||
if _OPTIONS["with-text-shaper"] then
|
||||
defines { "EE_TEXT_SHAPER_ENABLED" }
|
||||
end
|
||||
|
||||
set_ios_config()
|
||||
set_apple_config()
|
||||
build_arch_configuration()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require "premake.export-compile-commands.export-compile-commands"
|
||||
|
||||
newoption { trigger = "with-openssl", description = "Enables OpenSSL support ( and disables mbedtls backend )." }
|
||||
newoption { trigger = "with-dynamic-freetype", description = "Dynamic link against freetype." }
|
||||
newoption { trigger = "with-static-eepp", description = "Force to build the demos and tests with eepp compiled statically" }
|
||||
@@ -330,6 +332,10 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
end
|
||||
end
|
||||
|
||||
if _OPTIONS["with-text-shaper"] then
|
||||
defines { "EE_TEXT_SHAPER_ENABLED" }
|
||||
end
|
||||
|
||||
cppdialect "C++17"
|
||||
set_ios_config()
|
||||
set_apple_config()
|
||||
|
||||
@@ -211,14 +211,15 @@ static std::string GetWindowsArch() {
|
||||
GetSystemInfo( &si );
|
||||
}
|
||||
|
||||
if ( osvi.dwMajorVersion >= 6 ) {
|
||||
if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ) {
|
||||
arch = "x64";
|
||||
} else if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ) {
|
||||
arch = "x86";
|
||||
}
|
||||
} else {
|
||||
if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
|
||||
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 ) {
|
||||
arch = "x86_64";
|
||||
} else if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ) {
|
||||
arch = "x86";
|
||||
} else if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64 ) {
|
||||
arch = "arm64";
|
||||
} else if ( si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM ) {
|
||||
arch = "arm";
|
||||
}
|
||||
|
||||
return arch;
|
||||
|
||||
Reference in New Issue
Block a user