--
-- codeblocks_cbp.lua
-- Generate a Code::Blocks C/C++ project.
-- Copyright (c) 2009, 2011 Jason Perkins and the Premake project
--
local p = premake
local project = p.project
local config = p.config
local tree = p.tree
local codeblocks = p.modules.codeblocks
codeblocks.project = {}
local m = codeblocks.project
m.elements = {}
m.ctools = {
gcc = "gcc",
msc = "Visual C++",
}
function m.getcompilername(cfg)
local tool = _OPTIONS.cc or cfg.toolset or p.GCC
local toolset = p.tools[tool]
if not toolset then
error("Invalid toolset '" + (_OPTIONS.cc or cfg.toolset) + "'")
end
return m.ctools[tool]
end
function m.getcompiler(cfg)
local toolset = p.tools[_OPTIONS.cc or cfg.toolset or p.GCC]
if not toolset then
error("Invalid toolset '" + (_OPTIONS.cc or cfg.toolset) + "'")
end
return toolset
end
function m.header(prj)
_p('')
_p('')
_p(1,'')
-- write project block header
_p(1,'')
_p(2,'', prj.name)
_p(2,'')
end
function m.footer(prj)
-- write project block footer
_p(1,'')
_p('')
end
m.elements.project = function(prj)
return {
m.header,
m.configurations,
m.files,
m.extensions,
m.footer
}
end
--
-- Project: Generate the CodeBlocks project file.
--
function m.generate(prj)
p.utf8()
p.callArray(m.elements.project, prj)
end
function m.configurations(prj)
-- write configuration blocks
_p(2,'')
local platforms = {}
for cfg in project.eachconfig(prj) do
local found = false
for k,v in pairs(platforms) do
if (v.platform == cfg.platform) then
table.insert(v.configs, cfg)
found = true
break
end
end
if (not found) then
table.insert(platforms, {platform = cfg.platform, configs = {cfg}})
end
end
for k,platform in pairs(platforms) do
for k,cfg in pairs(platform.configs) do
local compiler = m.getcompiler(cfg)
_p(3,'', cfg.longname)
_p(4,'', p.esc(cfg.buildtarget.relpath))
if cfg.debugdir then
_p(4,'', p.esc(path.getrelative(prj.location, cfg.debugdir)))
end
_p(4,'', p.esc(path.getrelative(prj.location, cfg.objdir)))
-- identify the type of binary
local types = { WindowedApp = 0, ConsoleApp = 1, StaticLib = 2, SharedLib = 3 }
_p(4,'', types[cfg.kind])
_p(4,'', m.getcompilername(cfg))
if (cfg.kind == "SharedLib") then
_p(4,'')
_p(4,'', iif(cfg.flags.NoImportLib, 0, 1))
end
-- begin compiler block --
_p(4,'')
for _,flag in ipairs(table.join(compiler.getcflags(cfg), compiler.getcxxflags(cfg), compiler.getdefines(cfg.defines), cfg.buildoptions)) do
_p(5,'', p.esc(flag))
end
if not cfg.flags.NoPCH and cfg.pchheader then
_p(5,'')
_p(5,'', p.esc(cfg.pchheader))
end
for _,v in ipairs(cfg.includedirs) do
_p(5,'', p.esc(path.getrelative(prj.location, v)))
end
_p(4,'')
-- end compiler block --
-- begin linker block --
_p(4,'')
for _,flag in ipairs(table.join(compiler.getldflags(cfg), cfg.linkoptions)) do
_p(5,'', p.esc(flag))
end
for _,v in ipairs(config.getlinks(cfg, "all", "directory")) do
_p(5,'', p.esc(v))
end
for _,v in ipairs(config.getlinks(cfg, "all", "basename")) do
_p(5,'', p.esc(v))
end
_p(4,'')
-- end linker block --
-- begin resource compiler block --
if config.findfile(cfg, ".rc") then
_p(4,'')
for _,v in ipairs(cfg.includedirs) do
_p(5,'', p.esc(v))
end
for _,v in ipairs(cfg.resincludedirs) do
_p(5,'', p.esc(v))
end
_p(4,'')
end
-- end resource compiler block --
-- begin build steps --
if #cfg.prebuildcommands > 0 or #cfg.postbuildcommands > 0 then
_p(4,'')
for _,v in ipairs(cfg.prebuildcommands) do
_p(5,'', p.esc(v))
end
for _,v in ipairs(cfg.postbuildcommands) do
_p(5,'', p.esc(v))
end
_p(4,'')
end
-- end build steps --
_p(3,'')
end
end
_p(2,'')
end
--
-- Write out a list of the source code files in the project.
--
function m.files(prj)
local pchheader
if (prj.pchheader) then
pchheader = path.getrelative(prj.location, prj.pchheader)
end
local tr = project.getsourcetree(prj)
tree.traverse(tr, {
-- source files are handled at the leaves
onleaf = function(node, depth)
if node.relpath == node.vpath then
_p(2,'', node.relpath)
else
_p(2,'', node.name)
_p(3,'', path.getdirectory(node.vpath))
end
if path.isresourcefile(node.name) then
_p(3,'')
elseif path.iscfile(node.name) and prj.language == "C++" then
_p(3,'')
end
if not prj.flags.NoPCH and node.name == pchheader then
_p(3,'', iif(prj.language == "C", "CC", "CPP"))
_p(3,'')
_p(3,'')
_p(3,'')
end
_p(2,'')
end,
}, false, 1)
end
function m.extensions(prj)
for cfg in project.eachconfig(prj) do
if cfg.debugenvs and #cfg.debugenvs > 0 then
--Assumption: if gcc is being used then so is gdb although this section will be ignored by
--other debuggers. If using gcc and not gdb it will silently not pass the
--environment arguments to the debugger
if m.getcompilername(cfg) == "gcc" then
_p(3,'')
_p(4,'', p.esc(cfg.longname))
local args = ''
local sz = #cfg.debugenvs
for idx, v in ipairs(cfg.debugenvs) do
args = args .. 'set env ' .. v
if sz ~= idx then args = args .. '
' end
end
_p(5,'',args)
_p(4,'')
_p(3,'')
else
error('Sorry at this moment there is no support for debug environment variables with this debugger and codeblocks')
end
end
end
end