gmake.lua 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. --
  2. -- gmake.lua
  3. -- Define the makefile action(s).
  4. -- Copyright (c) 2002-2015 Jason Perkins and the Premake project
  5. --
  6. local p = premake
  7. p.modules.gmake = {}
  8. p.modules.gmake._VERSION = p._VERSION
  9. -- for backwards compatibility.
  10. p.make = p.modules.gmake
  11. local make = p.make
  12. local project = p.project
  13. --
  14. -- Write out the default configuration rule for a workspace or project.
  15. --
  16. -- @param target
  17. -- The workspace or project object for which a makefile is being generated.
  18. --
  19. function make.defaultconfig(target)
  20. -- find the right configuration iterator function for this object
  21. local eachconfig = iif(target.project, project.eachconfig, p.workspace.eachconfig)
  22. local defaultconfig = nil
  23. -- find the right default configuration platform, grab first configuration that matches
  24. if target.defaultplatform then
  25. for cfg in eachconfig(target) do
  26. if cfg.platform == target.defaultplatform then
  27. defaultconfig = cfg
  28. break
  29. end
  30. end
  31. end
  32. -- grab the first configuration and write the block
  33. if not defaultconfig then
  34. local iter = eachconfig(target)
  35. defaultconfig = iter()
  36. end
  37. if defaultconfig then
  38. _p('ifndef config')
  39. _x(' config=%s', defaultconfig.shortname)
  40. _p('endif')
  41. _p('')
  42. end
  43. end
  44. ---
  45. -- Escape a string so it can be written to a makefile.
  46. ---
  47. function make.esc(value)
  48. result = value:gsub("\\", "\\\\")
  49. result = result:gsub("\"", "\\\"")
  50. result = result:gsub(" ", "\\ ")
  51. result = result:gsub("%(", "\\(")
  52. result = result:gsub("%)", "\\)")
  53. -- leave $(...) shell replacement sequences alone
  54. result = result:gsub("$\\%((.-)\\%)", "$(%1)")
  55. return result
  56. end
  57. --
  58. -- Get the makefile file name for a workspace or a project. If this object is the
  59. -- only one writing to a location then I can use "Makefile". If more than one object
  60. -- writes to the same location I use name + ".make" to keep it unique.
  61. --
  62. function make.getmakefilename(this, searchprjs)
  63. local count = 0
  64. for wks in p.global.eachWorkspace() do
  65. if wks.location == this.location then
  66. count = count + 1
  67. end
  68. if searchprjs then
  69. for _, prj in ipairs(wks.projects) do
  70. if prj.location == this.location then
  71. count = count + 1
  72. end
  73. end
  74. end
  75. end
  76. if count == 1 then
  77. return "Makefile"
  78. else
  79. return ".make"
  80. end
  81. end
  82. --
  83. -- Output a makefile header.
  84. --
  85. -- @param target
  86. -- The workspace or project object for which the makefile is being generated.
  87. --
  88. function make.header(target)
  89. local kind = iif(target.project, "project", "workspace")
  90. _p('# %s %s makefile autogenerated by Premake', p.action.current().shortname, kind)
  91. _p('')
  92. if kind == "workspace" then
  93. local haspch = false
  94. for _, prj in ipairs(target.projects) do
  95. for cfg in project.eachconfig(prj) do
  96. if cfg.pchheader then
  97. haspch = true
  98. end
  99. end
  100. end
  101. if haspch then
  102. _p('.NOTPARALLEL:')
  103. _p('')
  104. end
  105. end
  106. make.defaultconfig(target)
  107. _p('ifndef verbose')
  108. _p(' SILENT = @')
  109. _p('endif')
  110. _p('')
  111. end
  112. --
  113. -- Rules for file ops based on the shell type. Can't use defines and $@ because
  114. -- it screws up the escaping of spaces and parethesis (anyone know a fix?)
  115. --
  116. function make.mkdir(dirname)
  117. _p('ifeq (posix,$(SHELLTYPE))')
  118. _p('\t$(SILENT) mkdir -p %s', dirname)
  119. _p('else')
  120. _p('\t$(SILENT) mkdir $(subst /,\\\\,%s)', dirname)
  121. _p('endif')
  122. end
  123. function make.mkdirRules(dirname)
  124. _p('%s:', dirname)
  125. _p('\t@echo Creating %s', dirname)
  126. make.mkdir(dirname)
  127. _p('')
  128. end
  129. --
  130. -- Format a list of values to be safely written as part of a variable assignment.
  131. --
  132. function make.list(value, quoted)
  133. quoted = false
  134. if #value > 0 then
  135. if quoted then
  136. local result = ""
  137. for _, v in ipairs (value) do
  138. if #result then
  139. result = result .. " "
  140. end
  141. result = result .. p.quoted(v)
  142. end
  143. return result
  144. else
  145. return " " .. table.concat(value, " ")
  146. end
  147. else
  148. return ""
  149. end
  150. end
  151. --
  152. -- Convert an arbitrary string (project name) to a make variable name.
  153. --
  154. function make.tovar(value)
  155. value = value:gsub("[ -]", "_")
  156. value = value:gsub("[()]", "")
  157. return value
  158. end
  159. ---------------------------------------------------------------------------
  160. --
  161. -- Handlers for the individual makefile elements that can be shared
  162. -- between the different language projects.
  163. --
  164. ---------------------------------------------------------------------------
  165. function make.objdir(cfg)
  166. _x(' OBJDIR = %s', p.esc(project.getrelative(cfg.project, cfg.objdir)))
  167. end
  168. function make.objDirRules(prj)
  169. make.mkdirRules("$(OBJDIR)")
  170. end
  171. function make.phonyRules(prj)
  172. _p('.PHONY: clean prebuild prelink')
  173. _p('')
  174. end
  175. function make.buildCmds(cfg, event)
  176. _p(' define %sCMDS', event:upper())
  177. local steps = cfg[event .. "commands"]
  178. local msg = cfg[event .. "message"]
  179. if #steps > 0 then
  180. steps = os.translateCommandsAndPaths(steps, cfg.project.basedir, cfg.project.location)
  181. msg = msg or string.format("Running %s commands", event)
  182. _p('\t@echo %s', msg)
  183. _p('\t%s', table.implode(steps, "", "", "\n\t"))
  184. end
  185. _p(' endef')
  186. end
  187. function make.preBuildCmds(cfg, toolset)
  188. make.buildCmds(cfg, "prebuild")
  189. end
  190. function make.preBuildRules(prj)
  191. _p('prebuild:')
  192. _p('\t$(PREBUILDCMDS)')
  193. _p('')
  194. end
  195. function make.preLinkCmds(cfg, toolset)
  196. make.buildCmds(cfg, "prelink")
  197. end
  198. function make.preLinkRules(prj)
  199. _p('prelink:')
  200. _p('\t$(PRELINKCMDS)')
  201. _p('')
  202. end
  203. function make.postBuildCmds(cfg, toolset)
  204. make.buildCmds(cfg, "postbuild")
  205. end
  206. function make.settings(cfg, toolset)
  207. if #cfg.makesettings > 0 then
  208. for _, value in ipairs(cfg.makesettings) do
  209. _p(value)
  210. end
  211. end
  212. local value = toolset.getmakesettings(cfg)
  213. if value then
  214. _p(value)
  215. end
  216. end
  217. function make.shellType()
  218. _p('SHELLTYPE := posix')
  219. _p('ifeq (.exe,$(findstring .exe,$(ComSpec)))')
  220. _p('\tSHELLTYPE := msdos')
  221. _p('endif')
  222. _p('')
  223. end
  224. function make.target(cfg)
  225. _x(' TARGETDIR = %s', project.getrelative(cfg.project, cfg.buildtarget.directory))
  226. _x(' TARGET = $(TARGETDIR)/%s', cfg.buildtarget.name)
  227. end
  228. function make.targetDirRules(prj)
  229. make.mkdirRules("$(TARGETDIR)")
  230. end
  231. include("gmake_cpp.lua")
  232. include("gmake_csharp.lua")
  233. include("gmake_makefile.lua")
  234. include("gmake_utility.lua")
  235. include("gmake_workspace.lua")
  236. return p.modules.gmake