2008-10-31 18:38:05 +00:00
|
|
|
--
|
|
|
|
-- _make.lua
|
|
|
|
-- Define the makefile action(s).
|
2012-04-30 20:42:03 +00:00
|
|
|
-- Copyright (c) 2002-2012 Jason Perkins and the Premake project
|
2008-10-31 18:38:05 +00:00
|
|
|
--
|
|
|
|
|
2012-11-27 15:08:01 +00:00
|
|
|
premake.make = {}
|
2011-09-15 20:45:48 +00:00
|
|
|
local make = premake.make
|
2012-05-08 22:08:42 +00:00
|
|
|
local solution = premake.solution
|
2012-05-04 20:38:21 +00:00
|
|
|
local project = premake5.project
|
2008-10-31 18:38:05 +00:00
|
|
|
|
2012-04-30 20:42:03 +00:00
|
|
|
--
|
|
|
|
-- The GNU make action, with support for the new platforms API
|
|
|
|
--
|
|
|
|
|
|
|
|
newaction {
|
2012-11-27 15:08:01 +00:00
|
|
|
trigger = "gmake",
|
|
|
|
shortname = "GNU Make",
|
|
|
|
description = "Generate GNU makefiles for POSIX, MinGW, and Cygwin",
|
2012-04-30 20:42:03 +00:00
|
|
|
|
|
|
|
-- temporary, until I can phase out the legacy implementations
|
|
|
|
isnextgen = true,
|
|
|
|
|
|
|
|
valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" },
|
|
|
|
|
|
|
|
valid_languages = { "C", "C++", "C#" },
|
|
|
|
|
|
|
|
valid_tools = {
|
|
|
|
cc = { "gcc" },
|
|
|
|
dotnet = { "mono", "msnet", "pnet" }
|
|
|
|
},
|
|
|
|
|
|
|
|
onsolution = function(sln)
|
|
|
|
premake.generate(sln, make.getmakefilename(sln, false), make.generate_solution)
|
|
|
|
end,
|
|
|
|
|
|
|
|
onproject = function(prj)
|
|
|
|
local makefile = make.getmakefilename(prj, true)
|
|
|
|
if premake.isdotnetproject(prj) then
|
|
|
|
premake.generate(prj, makefile, make.generate_csharp)
|
|
|
|
else
|
2012-05-08 22:08:42 +00:00
|
|
|
premake.generate(prj, makefile, make.cpp.generate)
|
2012-04-30 20:42:03 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
oncleansolution = function(sln)
|
|
|
|
premake.clean.file(sln, make.getmakefilename(sln, false))
|
|
|
|
end,
|
|
|
|
|
|
|
|
oncleanproject = function(prj)
|
|
|
|
premake.clean.file(prj, make.getmakefilename(prj, true))
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-05-04 20:38:21 +00:00
|
|
|
--
|
2012-05-08 22:08:42 +00:00
|
|
|
-- Write out the default configuration rule for a solution or project.
|
|
|
|
-- @param target
|
|
|
|
-- The solution or project object for which a makefile is being generated.
|
2012-05-04 20:38:21 +00:00
|
|
|
--
|
|
|
|
|
2012-05-08 22:08:42 +00:00
|
|
|
function make.defaultconfig(target)
|
2012-09-27 14:16:42 +00:00
|
|
|
-- find the right configuration iterator function for this object
|
2012-05-08 22:08:42 +00:00
|
|
|
local eachconfig = iif(target.project, project.eachconfig, solution.eachconfig)
|
|
|
|
local iter = eachconfig(target)
|
|
|
|
|
|
|
|
-- grab the first configuration and write the block
|
|
|
|
local cfg = iter()
|
|
|
|
if cfg then
|
2012-05-04 20:38:21 +00:00
|
|
|
_p('ifndef config')
|
|
|
|
_p(' config=%s', make.esc(cfg.shortname))
|
|
|
|
_p('endif')
|
|
|
|
_p('')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-09-28 16:07:18 +00:00
|
|
|
--
|
|
|
|
-- Output logic to detect the shell type at runtime.
|
|
|
|
--
|
|
|
|
|
|
|
|
function make.detectshell()
|
|
|
|
_p('SHELLTYPE := msdos')
|
|
|
|
_p('ifeq (,$(ComSpec)$(COMSPEC))')
|
|
|
|
_p(' SHELLTYPE := posix')
|
|
|
|
_p('endif')
|
|
|
|
_p('ifeq (/bin,$(findstring /bin,$(SHELL)))')
|
|
|
|
_p(' SHELLTYPE := posix')
|
|
|
|
_p('endif')
|
|
|
|
_p('')
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-05-04 20:38:21 +00:00
|
|
|
--
|
|
|
|
-- Escape a string so it can be written to a makefile.
|
|
|
|
--
|
|
|
|
|
|
|
|
function make.esc(value)
|
|
|
|
local result
|
|
|
|
if (type(value) == "table") then
|
|
|
|
result = { }
|
|
|
|
for _,v in ipairs(value) do
|
2012-11-27 15:08:01 +00:00
|
|
|
table.insert(result, make.esc(v))
|
2012-05-04 20:38:21 +00:00
|
|
|
end
|
|
|
|
return result
|
|
|
|
else
|
|
|
|
-- handle simple replacements
|
|
|
|
result = value:gsub("\\", "\\\\")
|
|
|
|
result = result:gsub(" ", "\\ ")
|
|
|
|
result = result:gsub("%(", "\\%(")
|
|
|
|
result = result:gsub("%)", "\\%)")
|
|
|
|
|
|
|
|
-- leave $(...) shell replacement sequences alone
|
|
|
|
result = result:gsub("$\\%((.-)\\%)", "$%(%1%)")
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-04-30 20:42:03 +00:00
|
|
|
--
|
|
|
|
-- Get the makefile file name for a solution or a project. If this object is the
|
|
|
|
-- only one writing to a location then I can use "Makefile". If more than one object
|
|
|
|
-- writes to the same location I use name + ".make" to keep it unique.
|
|
|
|
--
|
|
|
|
|
|
|
|
function make.getmakefilename(this, searchprjs)
|
|
|
|
local count = 0
|
|
|
|
for sln in premake.solution.each() do
|
|
|
|
if sln.location == this.location then
|
|
|
|
count = count + 1
|
|
|
|
end
|
|
|
|
|
2012-05-08 22:08:42 +00:00
|
|
|
if searchprjs then
|
|
|
|
for _, prj in ipairs(sln.projects) do
|
2012-04-30 20:42:03 +00:00
|
|
|
if prj.location == this.location then
|
|
|
|
count = count + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if count == 1 then
|
|
|
|
return "Makefile"
|
|
|
|
else
|
|
|
|
return this.name .. ".make"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-09-27 14:16:42 +00:00
|
|
|
--
|
|
|
|
-- Output a makefile header.
|
|
|
|
--
|
|
|
|
-- @param target
|
|
|
|
-- The solution or project object for which the makefile is being generated.
|
|
|
|
--
|
|
|
|
|
|
|
|
function make.header(target)
|
|
|
|
-- find the right configuration iterator function for this object
|
|
|
|
local kind = iif(target.project, "project", "solution")
|
|
|
|
|
|
|
|
_p('# %s %s makefile autogenerated by Premake', premake.action.current().shortname, kind)
|
|
|
|
_p('')
|
|
|
|
|
|
|
|
make.defaultconfig(target)
|
|
|
|
|
|
|
|
_p('ifndef verbose')
|
|
|
|
_p(' SILENT = @')
|
|
|
|
_p('endif')
|
|
|
|
_p('')
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-06-22 21:15:17 +00:00
|
|
|
--
|
|
|
|
-- Rules for file ops based on the shell type. Can't use defines and $@ because
|
|
|
|
-- it screws up the escaping of spaces and parethesis (anyone know a solution?)
|
|
|
|
--
|
|
|
|
|
|
|
|
function make.copyrule(source, target)
|
|
|
|
_p('%s: %s', target, source)
|
|
|
|
_p('\t@echo Copying $(notdir %s)', target)
|
|
|
|
_p('ifeq (posix,$(SHELLTYPE))')
|
|
|
|
_p('\t$(SILENT) cp -fR %s %s', source, target)
|
|
|
|
_p('else')
|
|
|
|
_p('\t$(SILENT) copy /Y $(subst /,\\\\,%s) $(subst /,\\\\,%s)', source, target)
|
|
|
|
_p('endif')
|
|
|
|
end
|
|
|
|
|
|
|
|
function make.mkdirrule(dirname)
|
|
|
|
_p('%s:', dirname)
|
|
|
|
_p('\t@echo Creating %s', dirname)
|
|
|
|
_p('ifeq (posix,$(SHELLTYPE))')
|
|
|
|
_p('\t$(SILENT) mkdir -p %s', dirname)
|
|
|
|
_p('else')
|
|
|
|
_p('\t$(SILENT) mkdir $(subst /,\\\\,%s)', dirname)
|
|
|
|
_p('endif')
|
|
|
|
_p('')
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-06-13 22:29:51 +00:00
|
|
|
--
|
|
|
|
-- Write out raw makefile rules for a configuration.
|
|
|
|
--
|
|
|
|
|
|
|
|
function make.settings(cfg, toolset)
|
|
|
|
if #cfg.makesettings > 0 then
|
|
|
|
for _, value in ipairs(cfg.makesettings) do
|
|
|
|
_p(value)
|
|
|
|
end
|
|
|
|
end
|
2012-09-28 16:07:18 +00:00
|
|
|
|
|
|
|
local value = toolset.getmakesettings(cfg)
|
|
|
|
if value then
|
|
|
|
_p(value)
|
2012-06-13 22:29:51 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-04-30 20:42:03 +00:00
|
|
|
|
2012-09-28 14:35:13 +00:00
|
|
|
--
|
|
|
|
-- Output the main target variables: target directory, target name,
|
|
|
|
-- and objects (or intermediate files) directory. These values are
|
|
|
|
-- common across both C++ and C# projects.
|
|
|
|
--
|
|
|
|
|
|
|
|
function make.targetconfig(cfg)
|
2012-10-08 15:50:42 +00:00
|
|
|
local targetdir =
|
|
|
|
_p(' TARGETDIR = %s', make.esc(project.getrelative(cfg.project, cfg.buildtarget.directory)))
|
2012-09-28 14:35:13 +00:00
|
|
|
_p(' TARGET = $(TARGETDIR)/%s', make.esc(cfg.buildtarget.name))
|
|
|
|
_p(' OBJDIR = %s', make.esc(project.getrelative(cfg.project, cfg.objdir)))
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2012-07-24 20:54:11 +00:00
|
|
|
--
|
|
|
|
-- Convert an arbitrary string (project name) to a make variable name.
|
|
|
|
--
|
|
|
|
|
|
|
|
function make.tovar(value)
|
|
|
|
value = value:gsub("[ -]", "_")
|
|
|
|
value = value:gsub("[()]", "")
|
|
|
|
return value
|
|
|
|
end
|
|
|
|
|
2012-04-30 20:42:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- Everything below this point is a candidate for deprecation
|
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
_MAKE = { }
|
|
|
|
|
|
|
|
|
2008-10-31 18:38:05 +00:00
|
|
|
--
|
|
|
|
-- Escape a string so it can be written to a makefile.
|
|
|
|
--
|
|
|
|
|
2008-11-19 02:17:43 +00:00
|
|
|
function _MAKE.esc(value)
|
2010-10-04 10:43:19 +00:00
|
|
|
local result
|
2008-10-31 18:38:05 +00:00
|
|
|
if (type(value) == "table") then
|
2010-10-04 10:43:19 +00:00
|
|
|
result = { }
|
2008-10-31 18:38:05 +00:00
|
|
|
for _,v in ipairs(value) do
|
2008-11-19 02:17:43 +00:00
|
|
|
table.insert(result, _MAKE.esc(v))
|
2008-10-31 18:38:05 +00:00
|
|
|
end
|
|
|
|
return result
|
|
|
|
else
|
2010-10-04 10:43:19 +00:00
|
|
|
-- handle simple replacements
|
2009-05-29 17:45:37 +00:00
|
|
|
result = value:gsub("\\", "\\\\")
|
|
|
|
result = result:gsub(" ", "\\ ")
|
|
|
|
result = result:gsub("%(", "\\%(")
|
|
|
|
result = result:gsub("%)", "\\%)")
|
2010-10-04 10:43:19 +00:00
|
|
|
|
|
|
|
-- leave $(...) shell replacement sequences alone
|
|
|
|
result = result:gsub("$\\%((.-)\\%)", "$%(%1%)")
|
2008-10-31 18:38:05 +00:00
|
|
|
return result
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2008-11-21 16:37:24 +00:00
|
|
|
|
|
|
|
|
2009-05-29 17:45:37 +00:00
|
|
|
--
|
|
|
|
-- Rules for file ops based on the shell type. Can't use defines and $@ because
|
|
|
|
-- it screws up the escaping of spaces and parethesis (anyone know a solution?)
|
|
|
|
--
|
|
|
|
|
|
|
|
function premake.make_copyrule(source, target)
|
|
|
|
_p('%s: %s', target, source)
|
|
|
|
_p('\t@echo Copying $(notdir %s)', target)
|
|
|
|
_p('ifeq (posix,$(SHELLTYPE))')
|
|
|
|
_p('\t$(SILENT) cp -fR %s %s', source, target)
|
|
|
|
_p('else')
|
|
|
|
_p('\t$(SILENT) copy /Y $(subst /,\\\\,%s) $(subst /,\\\\,%s)', source, target)
|
|
|
|
_p('endif')
|
|
|
|
end
|
|
|
|
|
|
|
|
function premake.make_mkdirrule(var)
|
|
|
|
_p('\t@echo Creating %s', var)
|
|
|
|
_p('ifeq (posix,$(SHELLTYPE))')
|
|
|
|
_p('\t$(SILENT) mkdir -p %s', var)
|
|
|
|
_p('else')
|
|
|
|
_p('\t$(SILENT) mkdir $(subst /,\\\\,%s)', var)
|
|
|
|
_p('endif')
|
|
|
|
_p('')
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-31 18:38:05 +00:00
|
|
|
--
|
|
|
|
-- Returns a list of object names, properly escaped to be included in the makefile.
|
|
|
|
--
|
|
|
|
|
2008-11-19 02:17:43 +00:00
|
|
|
function _MAKE.getnames(tbl)
|
2008-10-31 18:38:05 +00:00
|
|
|
local result = table.extract(tbl, "name")
|
|
|
|
for k,v in pairs(result) do
|
2008-11-19 02:17:43 +00:00
|
|
|
result[k] = _MAKE.esc(v)
|
2008-10-31 18:38:05 +00:00
|
|
|
end
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
|
2011-09-15 20:45:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
--
|
|
|
|
-- Write out the raw settings blocks.
|
|
|
|
--
|
|
|
|
|
2012-06-13 22:29:51 +00:00
|
|
|
function make.settings_old(cfg, cc)
|
2011-09-15 20:45:48 +00:00
|
|
|
if #cfg.makesettings > 0 then
|
|
|
|
for _, value in ipairs(cfg.makesettings) do
|
|
|
|
_p(value)
|
|
|
|
end
|
|
|
|
end
|
2008-10-31 18:38:05 +00:00
|
|
|
|
2011-09-15 20:45:48 +00:00
|
|
|
local toolsettings = cc.platforms[cfg.platform].cfgsettings
|
|
|
|
if toolsettings then
|
|
|
|
_p(toolsettings)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2008-10-31 18:38:05 +00:00
|
|
|
--
|
|
|
|
-- Register the "gmake" action
|
|
|
|
--
|
|
|
|
|
2008-11-25 00:32:49 +00:00
|
|
|
newaction {
|
|
|
|
trigger = "gmake",
|
2008-10-31 18:38:05 +00:00
|
|
|
shortname = "GNU Make",
|
2009-09-29 20:06:06 +00:00
|
|
|
description = "Generate GNU makefiles for POSIX, MinGW, and Cygwin",
|
2008-10-31 18:38:05 +00:00
|
|
|
|
2008-11-13 00:54:41 +00:00
|
|
|
valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" },
|
2008-10-31 18:38:05 +00:00
|
|
|
|
2008-12-05 21:18:47 +00:00
|
|
|
valid_languages = { "C", "C++", "C#" },
|
2008-10-31 18:38:05 +00:00
|
|
|
|
|
|
|
valid_tools = {
|
2008-12-05 21:18:47 +00:00
|
|
|
cc = { "gcc" },
|
2009-05-08 20:18:47 +00:00
|
|
|
dotnet = { "mono", "msnet", "pnet" },
|
2008-10-31 18:38:05 +00:00
|
|
|
},
|
|
|
|
|
2009-08-12 01:16:15 +00:00
|
|
|
onsolution = function(sln)
|
2012-04-30 20:42:03 +00:00
|
|
|
premake.generate(sln, make.getmakefilename(sln, false), premake.make_solution)
|
2009-08-12 01:16:15 +00:00
|
|
|
end,
|
2008-10-31 18:38:05 +00:00
|
|
|
|
2009-08-12 01:16:15 +00:00
|
|
|
onproject = function(prj)
|
2012-04-30 20:42:03 +00:00
|
|
|
local makefile = make.getmakefilename(prj, true)
|
2009-08-12 01:16:15 +00:00
|
|
|
if premake.isdotnetproject(prj) then
|
|
|
|
premake.generate(prj, makefile, premake.make_csharp)
|
|
|
|
else
|
|
|
|
premake.generate(prj, makefile, premake.make_cpp)
|
|
|
|
end
|
|
|
|
end,
|
|
|
|
|
|
|
|
oncleansolution = function(sln)
|
2012-04-30 20:42:03 +00:00
|
|
|
premake.clean.file(sln, make.getmakefilename(sln, false))
|
2009-08-12 01:16:15 +00:00
|
|
|
end,
|
|
|
|
|
|
|
|
oncleanproject = function(prj)
|
2012-04-30 20:42:03 +00:00
|
|
|
premake.clean.file(prj, make.getmakefilename(prj, true))
|
2009-08-12 01:16:15 +00:00
|
|
|
end
|
2008-10-31 18:38:05 +00:00
|
|
|
}
|