summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/genie/src/actions/cmake/cmake_project.lua
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/genie/src/actions/cmake/cmake_project.lua')
-rw-r--r--3rdparty/genie/src/actions/cmake/cmake_project.lua309
1 files changed, 257 insertions, 52 deletions
diff --git a/3rdparty/genie/src/actions/cmake/cmake_project.lua b/3rdparty/genie/src/actions/cmake/cmake_project.lua
index b98a20c65a8..bc123eabeb2 100644
--- a/3rdparty/genie/src/actions/cmake/cmake_project.lua
+++ b/3rdparty/genie/src/actions/cmake/cmake_project.lua
@@ -2,64 +2,269 @@
-- _cmake.lua
-- Define the CMake action(s).
-- Copyright (c) 2015 Miodrag Milanovic
+-- Modifications and additions in 2017 by Maurizio Petrarota
--
local cmake = premake.cmake
local tree = premake.tree
+local includestr = 'include_directories(../%s)'
+local definestr = 'add_definitions(-D%s)'
+
+
+local function is_excluded(prj, cfg, file)
+ if table.icontains(prj.excludes, file) then
+ return true
+ end
+
+ if table.icontains(cfg.excludes, file) then
+ return true
+ end
+
+ return false
+end
+
+function cmake.excludedFiles(prj, cfg, src)
+ for _, v in ipairs(src) do
+ if (is_excluded(prj, cfg, v)) then
+ _p(1, 'list(REMOVE_ITEM source_list ../%s)', v)
+ end
+
+ end
+end
+
+function cmake.list(value)
+ if #value > 0 then
+ return " " .. table.concat(value, " ")
+ else
+ return ""
+ end
+end
+
function cmake.files(prj)
- local tr = premake.project.buildsourcetree(prj)
- tree.traverse(tr, {
- onbranchenter = function(node, depth)
- end,
- onbranchexit = function(node, depth)
- end,
- onleaf = function(node, depth)
- _p(1, '../%s', node.cfg.name)
- end,
- }, true, 1)
+ local ret = {}
+ local tr = premake.project.buildsourcetree(prj)
+ tree.traverse(tr, {
+ onbranchenter = function(node, depth)
+ end,
+ onbranchexit = function(node, depth)
+ end,
+ onleaf = function(node, depth)
+ table.insert(ret, node.cfg.name)
+ _p(1, '../%s', node.cfg.name)
+ end,
+ }, true, 1)
+
+ return ret
end
-function premake.cmake.project(prj)
- io.indent = " "
- _p('cmake_minimum_required(VERSION 2.8.4)')
- _p('')
- _p('project(%s)', premake.esc(prj.name))
- _p('set(')
- _p('source_list')
- cmake.files(prj)
- _p(')')
-
- local platforms = premake.filterplatforms(prj.solution, premake[_OPTIONS.cc].platforms, "Native")
- for i = #platforms, 1, -1 do
- if premake.platforms[platforms[i]].iscrosscompiler then
- table.remove(platforms, i)
- end
- end
-
- for _, platform in ipairs(platforms) do
- for cfg in premake.eachconfig(prj, platform) do
- for _,v in ipairs(cfg.includedirs) do
- _p('include_directories(../%s)', premake.esc(v))
- end
- for _,v in ipairs(cfg.defines) do
- _p('add_definitions(-D%s)', premake.esc(v))
- end
- break
- end
- break
- end
-
- if (prj.kind=='StaticLib') then
- _p('add_library(%s STATIC ${source_list})',premake.esc(prj.name))
- end
- if (prj.kind=='SharedLib') then
- _p('add_library(%s SHARED ${source_list})',premake.esc(prj.name))
- end
- if (prj.kind=='ConsoleApp') then
- _p('add_executable(%s ${source_list})',premake.esc(prj.name))
- end
- if (prj.kind=='WindowedApp') then
- _p('add_executable(%s ${source_list})',premake.esc(prj.name))
- end
+function cmake.header(prj)
+ _p('# %s project autogenerated by GENie', premake.action.current().shortname)
+ _p('cmake_minimum_required(VERSION 2.8.4)')
+ _p('')
+ _p('project(%s)', premake.esc(prj.name))
end
+
+function cmake.customtasks(prj)
+ local dirs = {}
+ local tasks = {}
+ for _, custombuildtask in ipairs(prj.custombuildtask or {}) do
+ for _, buildtask in ipairs(custombuildtask or {}) do
+ table.insert(tasks, buildtask)
+ local d = string.format("${CMAKE_CURRENT_SOURCE_DIR}/../%s", path.getdirectory(path.getrelative(prj.location, buildtask[2])))
+ if not table.contains(dirs, d) then
+ table.insert(dirs, d)
+ _p('file(MAKE_DIRECTORY \"%s\")', d)
+ end
+ end
+ end
+ _p('')
+
+ for _, buildtask in ipairs(tasks) do
+ local deps = string.format("${CMAKE_CURRENT_SOURCE_DIR}/../%s ", path.getrelative(prj.location, buildtask[1]))
+ local outputs = string.format("${CMAKE_CURRENT_SOURCE_DIR}/../%s ", path.getrelative(prj.location, buildtask[2]))
+ local msg = ""
+
+ for _, depdata in ipairs(buildtask[3] or {}) do
+ deps = deps .. string.format("${CMAKE_CURRENT_SOURCE_DIR}/../%s ", path.getrelative(prj.location, depdata))
+ end
+
+ _p('add_custom_command(')
+ _p(1, 'OUTPUT %s', outputs)
+ _p(1, 'DEPENDS %s', deps)
+
+ for _, cmdline in ipairs(buildtask[4] or {}) do
+ if (cmdline:sub(1, 1) ~= "@") then
+ local cmd = cmdline
+ local num = 1
+ for _, depdata in ipairs(buildtask[3] or {}) do
+ cmd = string.gsub(cmd, "%$%(" .. num .. "%)", string.format("${CMAKE_CURRENT_SOURCE_DIR}/../%s ", path.getrelative(prj.location, depdata)))
+ num = num + 1
+ end
+
+ cmd = string.gsub(cmd, "%$%(<%)", string.format("${CMAKE_CURRENT_SOURCE_DIR}/../%s ", path.getrelative(prj.location, buildtask[1])))
+ cmd = string.gsub(cmd, "%$%(@%)", outputs)
+
+ _p(1, 'COMMAND %s', cmd)
+ else
+ msg = cmdline
+ end
+ end
+ _p(1, 'COMMENT \"%s\"', msg)
+ _p(')')
+ _p('')
+ end
+end
+
+function cmake.depRules(prj)
+ local maintable = {}
+ for _, dependency in ipairs(prj.dependency) do
+ for _, dep in ipairs(dependency) do
+ if path.issourcefile(dep[1]) then
+ local dep1 = premake.esc(path.getrelative(prj.location, dep[1]))
+ local dep2 = premake.esc(path.getrelative(prj.location, dep[2]))
+ if not maintable[dep1] then maintable[dep1] = {} end
+ table.insert(maintable[dep1], dep2)
+ end
+ end
+ end
+
+ for key, _ in pairs(maintable) do
+ local deplist = {}
+ local depsname = string.format('%s_deps', path.getname(key))
+
+ for _, d2 in pairs(maintable[key]) do
+ table.insert(deplist, d2)
+ end
+ _p('set(')
+ _p(1, depsname)
+ for _, v in pairs(deplist) do
+ _p(1, '${CMAKE_CURRENT_SOURCE_DIR}/../%s', v)
+ end
+ _p(')')
+ _p('')
+ _p('set_source_files_properties(')
+ _p(1, '\"${CMAKE_CURRENT_SOURCE_DIR}/../%s\"', key)
+ _p(1, 'PROPERTIES OBJECT_DEPENDS \"${%s}\"', depsname)
+ _p(')')
+ _p('')
+ end
+end
+
+function cmake.commonRules(conf, str)
+ local Dupes = {}
+ local t2 = {}
+ for _, cfg in ipairs(conf) do
+ local cfgd = iif(str == includestr, cfg.includedirs, cfg.defines)
+ for _, v in ipairs(cfgd) do
+ if(t2[v] == #conf - 1) then
+ _p(str, v)
+ table.insert(Dupes, v)
+ end
+ if not t2[v] then
+ t2[v] = 1
+ else
+ t2[v] = t2[v] + 1
+ end
+ end
+ end
+ return Dupes
+end
+
+function cmake.cfgRules(cfg, dupes, str)
+ for _, v in ipairs(cfg) do
+ if (not table.icontains(dupes, v)) then
+ _p(1, str, v)
+ end
+ end
+end
+
+function cmake.removeCrosscompiler(platforms)
+ for i = #platforms, 1, -1 do
+ if premake.platforms[platforms[i]].iscrosscompiler then
+ table.remove(platforms, i)
+ end
+ end
+end
+
+function cmake.project(prj)
+ io.indent = " "
+ cmake.header(prj)
+ _p('set(')
+ _p('source_list')
+ local source_files = cmake.files(prj)
+ _p(')')
+ _p('')
+
+ local nativeplatform = iif(os.is64bit(), "x64", "x32")
+ local cc = premake.gettool(prj)
+ local platforms = premake.filterplatforms(prj.solution, cc.platforms, "Native")
+
+ cmake.removeCrosscompiler(platforms)
+
+ local configurations = {}
+
+ for _, platform in ipairs(platforms) do
+ for cfg in premake.eachconfig(prj, platform) do
+ -- TODO: Extend support for 32-bit targets on 64-bit hosts
+ if cfg.platform == nativeplatform then
+ table.insert(configurations, cfg)
+ end
+ end
+ end
+
+ local commonIncludes = cmake.commonRules(configurations, includestr)
+ local commonDefines = cmake.commonRules(configurations, definestr)
+ _p('')
+
+ for _, cfg in ipairs(configurations) do
+ _p('if(CMAKE_BUILD_TYPE MATCHES \"%s\")', cfg.name)
+
+ -- list excluded files
+ cmake.excludedFiles(prj, cfg, source_files)
+
+ -- add includes directories
+ cmake.cfgRules(cfg.includedirs, commonIncludes, includestr)
+
+ -- add build defines
+ cmake.cfgRules(cfg.defines, commonDefines, definestr)
+
+ -- set CXX flags
+ _p(1, 'set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} %s\")', cmake.list(table.join(cc.getcppflags(cfg), cc.getcflags(cfg), cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_cpp)))
+
+ -- set C flags
+ _p(1, 'set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} %s\")', cmake.list(table.join(cc.getcppflags(cfg), cc.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_c)))
+
+ _p('endif()')
+ _p('')
+ end
+
+ -- force CPP if needed
+ if (prj.options.ForceCPP) then
+ _p('set_source_files_properties(${source_list} PROPERTIES LANGUAGE CXX)')
+ end
+
+ -- add custom tasks
+ cmake.customtasks(prj)
+
+ -- per-dependency build rules
+ cmake.depRules(prj)
+
+ for _, cfg in ipairs(configurations) do
+ _p('if(CMAKE_BUILD_TYPE MATCHES \"%s\")', cfg.name)
+
+ if (prj.kind == 'StaticLib') then
+ _p(1, 'add_library(%s STATIC ${source_list})', premake.esc(cfg.buildtarget.basename))
+ end
+
+ if (prj.kind == 'SharedLib') then
+ _p(1, 'add_library(%s SHARED ${source_list})', premake.esc(cfg.buildtarget.basename))
+ end
+ if (prj.kind == 'ConsoleApp' or prj.kind == 'WindowedApp') then
+ _p(1, 'add_executable(%s ${source_list})', premake.esc(cfg.buildtarget.basename))
+ _p(1, 'target_link_libraries(%s%s%s)', premake.esc(cfg.buildtarget.basename), cmake.list(premake.esc(premake.getlinks(cfg, "siblings", "basename"))), cmake.list(cc.getlinkflags(cfg)))
+ end
+ _p('endif()')
+ _p('')
+ end
+end \ No newline at end of file