Skip to content

Instantly share code, notes, and snippets.

@icebreaker
Forked from annulen/qt-support.lua
Created December 17, 2011 10:47
Show Gist options
  • Select an option

  • Save icebreaker/1489925 to your computer and use it in GitHub Desktop.

Select an option

Save icebreaker/1489925 to your computer and use it in GitHub Desktop.
Support for Qt Framework for Premake
--
-- qt-support.lua
-- Support for Qt Framework for Premake
-- Copyright (c) 2011 Konstantin Tokarev
--
-- Known limitations:
-- don't support static Qt builds yet (private links, lib order, plugins)
-- no support for Qt debug libs (Mac, Win)
-- only gmake
-- no Windows support yet
-- no support for building Qt plugins
-- the next Qt modules are not supported:
-- ActiveQt
-- QtDBus
-- QtDesigner
-- Phonon
--
local _s = string.format
premake.qt = {}
-- New dirs needed for intermediate files
premake.qt.artifactdirs = {}
premake.qt.mocexcludefromsources = {}
--
-- Helper functions
--
function premake.qt.massinsert(t, ...)
t = t or {}
for _,v in ipairs {...} do
table.insert(t, v)
end
end
function premake.qt.joinTables(t1, t2)
for k,v in ipairs(t2) do
table.insert(t1, v)
end
return t1
end
function premake.qt.dedup(t)
unique = {}
for _, v in ipairs(t) do
if not table.contains(unique, v) then
table.insert(unique, v)
end
end
t = nil
return unique
end
function premake.qt.concatif(predicate, list, sep)
local t = {}
for _,v in ipairs(list) do
if predicate(v) then
table.insert(t, v)
end
end
return table.concat(t, sep)
end
function premake.qt.gettoolname(cfg)
if _OPTIONS.cc then
return _OPTIONS.cc
end
local action = premake.action.current()
if action.valid_tools then
return action.valid_tools.cc[1]
end
return "gcc"
end
-- function premake.qt.isstaticlibrary(fname)
-- local ext = path.getextension(fname):lower()
-- if os.is("windows") and ext == ".lib" then
-- return true
-- end
-- return ext == ".a"
-- end
--
-- function premake.qt.issharedlibrary(fname)
-- local ext = path.getextension(fname):lower()
-- if os.is("windows") and ext == ".dll" then -- Not sure if it will work for Qt
-- return true
-- end
-- if os.is("macosx") and ext == ".dylib" then
-- return true
-- end
-- return ext == ".so"
-- end
function premake.qt.safeopen(fname, mode)
local f, err = io.open(fname, mode)
if not f then
error(err, 2)
end
return f
end
--
-- This table contains "type detector" functions as keys,
-- and lists of code generation callbacks as values
--
premake.qt.codegencallbacks = {}
function premake.qt.registercodegenerator(typedetector, generator)
if not premake.qt.codegencallbacks[typedetector] then
premake.qt.codegencallbacks[typedetector] = {}
end
table.insert(premake.qt.codegencallbacks[typedetector], generator)
end
--
-- Type detectors
--
function premake.qt.ismocableheader(fname)
if not path.iscppheader(fname) then
return false
end
local f = premake.qt.safeopen(fname)
for line in f:lines(fname) do
if line:find("Q_OBJECT") then
print("Mocable: "..fname)
io.close(f)
return true
end
end
io.close(f)
return false
end
function premake.qt.ismocablecppfile(fname)
if not path.iscppfile(fname) then
return false
end
local f = premake.qt.safeopen(fname)
for line in f:lines(fname) do
if line:find("#%s*include%s*\""..path.getbasename(fname).."%.moc\"") then
print("Mocable: "..fname)
io.close(f)
return true
end
end
io.close(f)
return false
end
-- Workaround for dirty trick, need to private slots working:
-- C++ file includes moc_xxx.cpp, generated for its header
function premake.qt.cppincludesmoc(fname)
if not path.iscppfile(fname) then
return false
end
local f = premake.qt.safeopen(fname)
local cpp = f:read("*a")
-- TODO: Don't hardcode "moc_", ".cpp", "$(MOCDIR)/"
-- TODO: Don't open the same file twice
for mocfile in cpp:gmatch("#%s-include%s-\"(moc_%w-.cpp)") do
print(fname .. " includes " .. mocfile)
table.insert(premake.qt.mocexcludefromsources, "$(MOCDIR)/" .. mocfile)
end
io.close(f)
return false
end
--Test
--local lines = { "#include \"abc.moc\"", "# include \"abc.moc\"", "#include abc.moc", "#include \"abc_moc\"" }
--for _,v in ipairs(lines) do
-- if v:find("#%s*include%s*\""..path.getbasename("src/abc.cpp").."%.moc\"") then
-- print "Mocable"
-- else
-- print "Not mocable"
-- end
--end
--
function premake.qt.typematcher(extension)
return function(fname)
local ext = path.getextension(fname):lower()
return ext == extension
end
end
premake.qt.isuifile = premake.qt.typematcher(".ui")
premake.qt.isqrcfile = premake.qt.typematcher(".qrc")
premake.qt.istsfile = premake.qt.typematcher(".ts")
-- Callbacks for code generation
-- @param footer Table containing generated lines of Makefile
-- @param file Current file from project for which code should be generated
function premake.qt.moc(footer, fileprj, filepath)
local moc_source = _s('$(MOCDIR)/moc_%s.cpp', _MAKE.esc(path.getbasename(fileprj)))
table.insert(footer, _s('%s: %s', moc_source, _MAKE.esc(fileprj)))
table.insert(footer, '\t@echo moc '..path.getname(fileprj))
table.insert(footer, '\t$(SILENT) $(QTMOC) $(MOCFLAGS) -nw -o "$@" "$<"')
return moc_source
end
function premake.qt.moc_i(footer, fileprj, filepath)
local moc_source = _s('$(MOCDIR)/%s.moc', _MAKE.esc(path.getbasename(fileprj)))
table.insert(footer, _s('%s: %s', moc_source, _MAKE.esc(fileprj)))
table.insert(footer, '\t@echo moc '..path.getname(fileprj))
table.insert(footer, '\t$(SILENT) $(QTMOC) $(MOCFLAGS) -i -o "$@" "$<"')
return moc_source
end
function premake.qt.ui_depends(filepath)
-- Iterator splits output of uic -d line by line
return string.gmatch(os.outputof("uic -d " .. filepath), "(.-)\n")
end
function premake.qt.uic(footer, fileprj, filepath)
local ui_header = _s('$(UIDIR)/ui_%s.h', _MAKE.esc(path.getbasename(fileprj)))
local target = { _s('%s: %s', ui_header, _MAKE.esc(fileprj)) }
for dep in premake.qt.ui_depends(filepath) do
table.insert(target, " \\\n "..path.join(path.getdirectory(fileprj), dep))
end
table.insert(footer, table.concat(target))
table.insert(footer, '\t@echo uic '..path.getbasename(fileprj))
table.insert(footer, '\t$(SILENT) $(QTUIC) "$<" -o "$@"')
return ui_header
end
function premake.qt.qrc_depends(filepath)
local qrcfile = premake.qt.safeopen(filepath)
local qrc = qrcfile:read("*a")
return string.gmatch(qrc, "<file[^>]*>([^<]+)</file>")
end
function premake.qt.rcc(footer, fileprj, filepath)
local qrc_source = _s('$(RCCDIR)/qrc_%s.cpp', _MAKE.esc(path.getbasename(fileprj)))
local target = { _s('%s: %s', qrc_source, _MAKE.esc(fileprj)) }
for dep in premake.qt.qrc_depends(filepath) do
table.insert(target, " \\\n "..path.join(path.getdirectory(fileprj), dep))
end
table.insert(footer, table.concat(target))
table.insert(footer, '\t@echo rcc '..path.getname(fileprj))
table.insert(footer, '\t$(SILENT) $(QTRCC) -name '.._MAKE.esc(path.getbasename(fileprj))..' -o "$@" "$<"')
return qrc_source
end
function premake.qt.lrelease(footer, fileprj, filepath)
local qm_file = _s('$(QMDIR)/%s.qm', _MAKE.esc(path.getbasename(fileprj)))
table.insert(footer, _s('%s: %s', qm_file, _MAKE.esc(fileprj)))
table.insert(footer, '\t@echo lrelease '..path.getbasename(fileprj))
table.insert(footer, '\t$(SILENT) $(QTLRELEASE) "$<" -qm "$@"')
return qm_file
end
-- Register callbacks
premake.qt.registercodegenerator(premake.qt.ismocableheader, premake.qt.moc)
premake.qt.registercodegenerator(premake.qt.ismocablecppfile, premake.qt.moc_i)
premake.qt.registercodegenerator(premake.qt.cppincludesmoc, function() end)
premake.qt.registercodegenerator(premake.qt.isuifile, premake.qt.uic)
premake.qt.registercodegenerator(premake.qt.isqrcfile, premake.qt.rcc)
premake.qt.registercodegenerator(premake.qt.istsfile, premake.qt.lrelease)
-- Write Makefile rules for code generation
function premake.qt.writecodegenrules(prj)
print ("Found Qt project " .. prj.name)
local footer = {}
if not prj.qt_generated_files then
prj.qt_generated_files = {}
end
for _,file in ipairs(prj.files) do
-- Exclude generated files from code generation
if not table.contains(prj.qt_generated_files, file) then
-- Iterate over premake.qt.codegencallbacks
-- If some of registered type detectors returns true on the file,
-- run all associated callbacks
local filewithpath = path.rebase(file, prj.location, os.getcwd())
for typedetector,generators in pairs(premake.qt.codegencallbacks) do
if typedetector(filewithpath) then
for _,generator in ipairs(generators) do
local outfilename = generator(footer, file, filewithpath)
table.insert(prj.files, outfilename)
table.insert(prj.qt_generated_files, outfilename)
end
end
end
end
end
table.insert(footer, "\n")
table.insert(footer, "prebuild: $(QT_DIRS) "
.. table.concat(prj.qt_generated_files, " \\\n "))
premake.qt.joinTables(prj.makeprjfooter, footer)
end
-- Find Qt4 and set up additional Makefile rules
function premake.qt.useqt(prj)
if prj.use_qt_guard then
return
end
prj.use_qt_guard = true
--
--We use the next Qt search strategy:
--1. qtdir in project configuration
--2. first $(QMAKE) executable in PATH
--Maybe we should allow using of pkg-config for it.
--
premake.qt.massinsert(prj.makeprjheader,
"QMAKE ?= qmake",
"QT_BIN_DEFAULT := $(shell $(QMAKE) -query QT_INSTALL_BINS)",
"QT_LIB_DEFAULT := $(shell $(QMAKE) -query QT_INSTALL_LIBS)",
"QT_INCLUDE_DEFAULT := $(shell $(QMAKE) -query QT_INSTALL_HEADERS)"
-- Do we need mkspecs, plugins, other stuff?
)
premake.qt.artifactdirs = premake.qt.dedup(premake.qt.artifactdirs)
table.insert(prj.makeprjfooter, "$(QT_DIRS):")
table.insert(prj.makeprjfooter, "ifeq (posix,$(SHELLTYPE))")
for _, dir in ipairs(premake.qt.artifactdirs) do
table.insert(prj.makeprjfooter, "\t$(SILENT) mkdir -p " .. dir)
end
table.insert(prj.makeprjfooter, "else")
for _, dir in ipairs(premake.qt.artifactdirs) do
table.insert(prj.makeprjfooter, _s('\t$(SILENT) mkdir $(subst /,\\\\,%s)', dir))
end
table.insert(prj.makeprjfooter, "endif")
table.insert(prj.makeprjfooter, "")
table.insert(prj.makeprjfooter, ".PHONY: lupdate")
table.insert(prj.makeprjfooter, "lupdate:")
if premake.qt.concatif(premake.qt.istsfile, prj.files, "") ~= "" then
premake.qt.massinsert(prj.makeprjfooter,
_s("\t$(QTLUPDATE) $(INCLUDES) \\\n %s \\\n -ts \\\n %s",
premake.qt.concatif(function(f)
return path.iscppfile(f) or path.iscppheader(f) or premake.qt.isuifile(f)
end,
prj.files, " \\\n "),
premake.qt.concatif(premake.qt.istsfile, prj.files, " \\\n "))
)
end
table.insert(prj.makeprjfooter, "")
prj.makeprjclean = prj.makeprjclean or {}
-- QMDIR may be equal TARGETDIR which is not removed
table.insert(prj.makeprjclean, 'ifeq (posix,$(SHELLTYPE))')
table.insert(prj.makeprjclean, '\t$(SILENT) rm -rf $(QT_DIRS)')
table.insert(prj.makeprjclean, 'else')
-- Probably will fail on Widows - foreach?
table.insert(prj.makeprjclean, '\t$(SILENT) if exist $(subst /,\\\\,$(QT_DIRS)) rmdir /s /q $(subst /,\\\\,$(QT_DIRS))')
table.insert(prj.makeprjclean, 'endif')
print("Uses Qt!")
end
--
-- Adds variable @a varname with value @value to Makefile
--
function premake.qt.makevariable(cfg, varname, value)
cfg.qt_vars = cfg.qt_vars or {}
if not table.contains(cfg.qt_vars, varname) then
table.insert(cfg.makeprjconfig, varname.. " = "..value)
table.insert(cfg.qt_vars, varname)
end
end
-- Merge with useqt?
function premake.qt.useqtcore(cfg)
if cfg.use_qt_core_guard then
return
end
cfg.use_qt_core_guard = true
-- Typically, Qt is installed in the next layout:
-- "QTDIR"/
-- bin/
-- include/
-- lib/
-- mkspecs/
-- ...
-- Linux distros can shuffle stuff randomly, but QTDIR with
-- proper symlinks usually exists.
--
-- AFAIK single exception is Qt Mac installation done by installer
--
if cfg.qtdir then
premake.qt.makevariable(cfg, "QTDIR", cfg.qtdir)
premake.qt.makevariable(cfg, "QT_BIN", "$(QTDIR)/bin")
premake.qt.makevariable(cfg, "QT_INCLUDE", "$(QTDIR)/include")
premake.qt.makevariable(cfg, "QT_LIB", "$(QTDIR)/lib")
else
premake.qt.makevariable(cfg, "QT_BIN", "$(QT_BIN_DEFAULT)")
premake.qt.makevariable(cfg, "QT_INCLUDE", "$(QT_INCLUDE_DEFAULT)")
premake.qt.makevariable(cfg, "QT_LIB", "$(QT_LIB_DEFAULT)")
end
premake.qt.makevariable(cfg, "QTMOC", "$(QT_BIN)/moc")
premake.qt.makevariable(cfg, "QTUIC", "$(QT_BIN)/uic")
premake.qt.makevariable(cfg, "QTRCC", "$(QT_BIN)/rcc")
premake.qt.makevariable(cfg, "QTLUPDATE", "$(QT_BIN)/lupdate")
premake.qt.makevariable(cfg, "QTLRELEASE", "$(QT_BIN)/lrelease")
premake.qt.makevariable(cfg, "MOCDIR", cfg.mocdir or "$(OBJDIR)")
premake.qt.makevariable(cfg, "UIDIR", cfg.uidir or "$(OBJDIR)")
premake.qt.makevariable(cfg, "RCCDIR", cfg.rccdir or "$(OBJDIR)")
premake.qt.makevariable(cfg, "QMDIR", cfg.qmdir or "$(TARGETDIR)")
if cfg.mocdir then
table.insert(premake.qt.artifactdirs, "$(MOCDIR)")
table.insert(cfg.makeprjconfig, "QT_DIRS += $(MOCDIR)")
end
if cfg.uidir then
table.insert(premake.qt.artifactdirs, "$(UIDIR)")
table.insert(cfg.makeprjconfig, "QT_DIRS += $(UIDIR)")
end
if cfg.rccdir then
table.insert(premake.qt.artifactdirs, "$(RCCDIR)")
table.insert(cfg.makeprjconfig, "QT_DIRS += $(RCCDIR)")
end
if cfg.qmdir then
table.insert(premake.qt.artifactdirs, "$(QMDIR)")
table.insert(cfg.makeprjconfig, "QT_DIRS += $(QMDIR)")
end
if os.is("macosx") then
premake.qt.makevariable(cfg, "MOCFLAGS", "$(INCLUDES) $(DEFINES) -D__APPLE__ -D__GNUC__")
else
premake.qt.makevariable(cfg, "MOCFLAGS", "$(INCLUDES) $(DEFINES)")
end
premake.qt.massinsert(cfg.includedirs,
"$(QT_INCLUDE)",
"$(UIDIR)",
"$(MOCDIR)"
)
table.insert(cfg.libdirs, "$(QT_LIB)")
-- Add rpath
if not os.is("windows") and not os.is("macosx") then
table.insert(cfg.defines, "_REENTRANT")
premake.qt.massinsert(cfg.linkoptions, "-Wl,-rpath,$(QT_LIB)", "-lpthread")
end
-- if QtCore is shared
-- Waiting for proper os.findlib to search custom paths and static libs
-- if cfg.qtdir and os.findlib("QtCore", path.join(cfg.qtdir, "lib") ...
if os.is("windows") then
premake.qt.massinsert(cfg.defines,
"UNICODE",
"WIN32",
"QT_LARGEFILE_SUPPORT",
"QT_THREAD_SUPPORT"
)
table.insert(cfg.defines, "QT_DLL")
-- From QMake spec win32-g++:
--
-- QMAKE_LFLAGS = -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
-- QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads -Wl
-- QMAKE_LFLAGS_EXCEPTIONS_OFF =
-- QMAKE_LINK_OBJECT_MAX = 10
-- QMAKE_LINK_OBJECT_SCRIPT= object_script
-- QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
--
if premake.qt.gettoolname(cfg) == "gcc" then
premake.qt.massinsert(cfg.linkoptions,
"-enable-stdcall-fixup",
"-Wl,-enable-auto-import",
"-Wl,-enable-runtime-pseudo-reloc"
)
-- QtMain
if cfg.kind == "ConsoleApp" or cfg.kind == "WindowedApp" then
table.insert(cfg.defines, "QT_NEEDS_QMAIN")
premake.qt.massinsert(cfg.linkoptions, "-lmingw32", "-lqtmain")
end
if not cfg.flags.NoExceptions then
table.insert(cfg.linkoptions, "-mthreads")
end
end
else
table.insert(cfg.defines, "QT_SHARED")
end
-- else
-- defines("QT_STATIC")
-- end
-- QT_NO_DEBUG
if premake.config.isoptimizedbuild(cfg.flags) then
table.insert(cfg.defines, "QT_NO_DEBUG")
end
end
--
-- Qt modules
--
local qt_modules = {
Qt =
{
depends = { }
},
QtCore =
{
define = "QT_CORE_LIB",
winlinks = { "kernel32", "user32", "shell32", "uuid", "ole32", "advapi32", "ws2_32" }
},
QtGui =
{
depends = { "QtCore" },
define = "QT_GUI_LIB",
winlinks = { "gdi32", "comdlg32", "oleaut32", "imm32", "winmm", "winspool",
"ws2_32", "ole32", "uuid", "user32", "advapi32" }
},
QtDeclarative =
{
depends = { "QtCore", "QtGui" },
define = "QT_DECLARATIVE_LIB",
},
QtHelp =
{
depends = { "QtCore", "QtSql", "QtXml" }
},
QtMultimedia =
{
depends = { "QtCore", "QtGui" },
define = "QT_MULTIMEDIA_LIB",
},
QtNetwork =
{
depends = { "QtCore" },
define = "QT_NETWORK_LIB"
},
QtOpenGL =
{
depends = { "QtCore", "QtGui" },
define = "QT_OPENGL_LIB",
-- Should OpenGL libs be a part of platform configuration?
links = { "GLU", "GL" }, -- GL ES?
maclinks = { "OpenGL.framework", "AGL.framework" },
winlinks = { "glu32", "opengl32", "gdi32", "user32" }
},
QtOpenVG =
{
-- Untested, may require something else
depends = { "QtCore", "QtGui" },
define = "QT_OPENVG_LIB",
links = { "OpenVG" }
},
QtScript =
{
depends = { "QtCore" },
define = "QT_SCRIPT_LIB",
},
QtScriptTools =
{
depends = { "QtCore", "QtGui", "QtScript" },
define = "QT_SCRIPTTOOLS_LIB",
},
QtSql =
{
depends = { "QtCore" },
define = "QT_SQL_LIB",
},
QtSvg =
{
depends = { "QtCore", "QtGui" },
define = "QT_SVG_LIB",
},
QtTest =
{
depends = { "QtCore" }
},
QtUiTools =
{
depends = { "QtCore", "QtXml" }
},
QtXml =
{
depends = { "QtCore" },
define = "QT_XML_LIB"
},
QtXmlPatterns =
{
depends = { "QtCore" },
define = "QT_XMLPATTERNS_LIB"
},
QtWebKit =
{
depends = { "QtCore", "QtGui", "QtNetwork" },
define = "QT_WEBKIT_LIB"
},
Qt3Support =
{
depends = { "QtCore" },
define = "QT_QT3SUPPORT_LIB"
}
}
--local qt_modules_lower = {}
--for name, _ in pairs(qt_modules) do
-- local lowername = name:lower()
-- table.insert(qt_modules_lower, lowername)
--end
--
-- Add necessary includedirs, defines, and links for used Qt modules
--
function premake.qt.usemodule(cfg, moduleName, moduleDefines)
if os.is("macosx") then
local fwname = moduleName..".framework"
local fwheaders = path.join(fwname, "Headers")
table.insert(cfg.links, fwname)
table.insert(cfg.includedirs, path.join("$(QT_LIB)", fwheaders))
elseif os.is("windows") then
if premake.config.isdebugbuild(cfg) then
table.insert(cfg.links, moduleName .. "d4")
else
table.insert(cfg.links, moduleName .. "4")
end
else
table.insert(cfg.links, moduleName)
end
table.insert(cfg.includedirs, "$(QT_INCLUDE)/" .. moduleName)
if moduleDefines then
table.insert(cfg.defines, moduleDefines)
end
if moduleName == "QtCore" then
premake.qt.useqtcore(cfg)
end
print("Uses "..moduleName.."!")
end
function premake.qt.checkmodulename(value)
local lowervalue = value:lower()
for v, _ in pairs(qt_modules) do
if lowervalue == v:lower() then
return v
end
end
if lowervalue:startswith("qt") then
return nil, "Invalid Qt module " .. value
end
-- 3rd party use - give back as is
return value
end
function premake.qt.runuses(cfg)
for _,u in ipairs(cfg.uses) do
local mod = qt_modules[u]
if mod then
premake.qt.usemodule(cfg, u, mod.define)
if os.is("windows") and mod.winlinks then
premake.qt.joinTables(cfg.links, mod.winlinks)
elseif os.is("macosx") and mod.maclinks then
premake.qt.joinTables(cfg.links, mod.maclinks)
elseif mod.links then
premake.qt.joinTables(cfg.links, mod.links)
end
end
end
end
--
-- Inject our code after baking but before gmake action
--
-- Rename gmake action into _gmake
assert(premake.action.list.gmake, "Your Premake does not have gmake action!")
premake.action.list.gmake, premake.action.list._gmake = nil, premake.action.list.gmake
premake.action.list._gmake.trigger = "_gmake"
-- Add new gmake action
newaction {
trigger = "gmake",
description = premake.action.get("_gmake").description,
shortname = premake.action.get("_gmake").shortname,
valid_kinds = premake.action.get("_gmake").valid_kinds,
valid_languages = premake.action.get("_gmake").valid_languages,
valid_tools = premake.action.get("_gmake").valid_tools,
onsolution = function(sln)
-- lupdate proxy-target
sln.makeslnfooter = sln.makeslnfooter or {}
table.insert(sln.makeslnfooter, "lupdate:")
for _ ,prj in ipairs(sln.projects) do
table.insert(sln.makeslnfooter,
_s('\t@${MAKE} --no-print-directory -C %s -f %s lupdate',
_MAKE.esc(path.getrelative(sln.location, prj.location)),
_MAKE.esc(_MAKE.getmakefilename(prj, true))))
end
table.insert(sln.makeslnfooter, "")
end,
onproject = function(prj)
local cc = premake.gettool(prj)
local platforms = premake.filterplatforms(prj.solution, cc.platforms, "Native")
local isQtProject = false
for _, platform in ipairs(platforms) do
for cfg in premake.eachconfig(prj, platform) do
cfg.links = cfg.links or {}
cfg.includedirs = cfg.includedirs or {}
cfg.defines = cfg.defines or {}
cfg.linkoptions = cfg.linkoptions or {}
-- Detect Qt use, insert module dependencies
local canonicUses = {}
for _, use in ipairs(cfg.uses) do
local u, err = premake.checkvalue(use, premake.qt.checkmodulename)
if u then
local m = qt_modules[u]
if m then
isQtProject = true
for _, dep in ipairs(m.depends) do
table.insert(canonicUses, dep)
end
end
if u ~= "Qt" then
table.insert(canonicUses, u)
end
else
error(err)
end
end
cfg.uses = canonicUses
end
-- Configuration block of Makefile
if isQtProject then
for cfg in premake.eachconfig(prj, platform) do
table.insert(cfg.uses, "QtCore")
if prj.kind == "WindowedApp" then
table.insert(cfg.uses, "QtGui")
end
cfg.uses = premake.qt.dedup(cfg.uses)
premake.qt.runuses(cfg)
cfg.includedirs = premake.qt.dedup(cfg.includedirs)
cfg.defines = premake.qt.dedup(cfg.defines)
cfg.links = premake.qt.dedup(cfg.links)
cfg.linkoptions = premake.qt.dedup(cfg.linkoptions)
end
premake.qt.useqt(prj)
end
end
-- Makefile footer
premake.qt.writecodegenrules(prj)
-- TODO: Think how to do this post-exclude properly (and when)
local files = {}
for _, fname in ipairs(prj.files) do
local excluded = false
for _, exclude in ipairs(premake.qt.mocexcludefromsources) do
print(fname)
excluded = (fname == exclude)
if excluded then
print("Excluding " .. fname .. " from sources")
break
end
--prj.sources
end
if not excluded then
table.insert(files, fname)
end
end
prj.files = files
end,
execute = function()
premake.action.call("_gmake")
end
}
--
-- Public Qt-specific API (tries to be consistent with QMake)
--
newapis {
-- Root of Qt installation
qtdir =
{
kind = "path",
scope = "config"
},
-- Directory where moc_*.cpp and *.moc files are written (by default objdir)
mocdir =
{
kind = "path",
scope = "config"
},
-- Directory where ui_*.h files are written (by default objdir)
uidir =
{
kind = "path",
scope = "config"
},
-- Directory where qrc_*.cpp files are written (by default objdir)
rccdir =
{
kind = "path",
scope = "config"
},
-- Directory where *.qm files are written (by default targetdir)
qmdir =
{
kind = "path",
scope = "config"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment