gmake_csharp.lua 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. --
  2. -- make_csharp.lua
  3. -- Generate a C# project makefile.
  4. -- Copyright (c) 2002-2013 Jason Perkins and the Premake project
  5. --
  6. local p = premake
  7. p.make.cs = {}
  8. local make = p.make
  9. local cs = p.make.cs
  10. local project = p.project
  11. local config = p.config
  12. local fileconfig = p.fileconfig
  13. --
  14. -- Add namespace for element definition lists for p.callarray()
  15. --
  16. cs.elements = {}
  17. --
  18. -- Generate a GNU make C++ project makefile, with support for the new platforms API.
  19. --
  20. cs.elements.makefile = function(prj)
  21. return {
  22. make.header,
  23. make.phonyRules,
  24. make.csConfigs,
  25. make.csProjectConfig,
  26. make.csSources,
  27. make.csEmbedFiles,
  28. make.csCopyFiles,
  29. make.csResponseFile,
  30. make.shellType,
  31. make.csAllRules,
  32. make.csTargetRules,
  33. make.targetDirRules,
  34. make.csResponseRules,
  35. make.objDirRules,
  36. make.csCleanRules,
  37. make.preBuildRules,
  38. make.preLinkRules,
  39. make.csFileRules,
  40. }
  41. end
  42. --
  43. -- Generate a GNU make C# project makefile, with support for the new platforms API.
  44. --
  45. function make.cs.generate(prj)
  46. p.eol("\n")
  47. local toolset = p.tools.dotnet
  48. p.callArray(cs.elements.makefile, prj, toolset)
  49. end
  50. --
  51. -- Write out the settings for a particular configuration.
  52. --
  53. cs.elements.configuration = function(cfg)
  54. return {
  55. make.csTools,
  56. make.target,
  57. make.objdir,
  58. make.csFlags,
  59. make.csLinkCmd,
  60. make.preBuildCmds,
  61. make.preLinkCmds,
  62. make.postBuildCmds,
  63. make.settings,
  64. }
  65. end
  66. function make.csConfigs(prj, toolset)
  67. for cfg in project.eachconfig(prj) do
  68. _x('ifeq ($(config),%s)', cfg.shortname)
  69. p.callArray(cs.elements.configuration, cfg, toolset)
  70. _p('endif')
  71. _p('')
  72. end
  73. end
  74. --
  75. -- Given a .resx resource file, builds the path to corresponding .resource
  76. -- file, matching the behavior and naming of Visual Studio.
  77. --
  78. function cs.getresourcefilename(cfg, fname)
  79. if path.getextension(fname) == ".resx" then
  80. local name = cfg.buildtarget.basename .. "."
  81. local dir = path.getdirectory(fname)
  82. if dir ~= "." then
  83. name = name .. path.translate(dir, ".") .. "."
  84. end
  85. return "$(OBJDIR)/" .. p.esc(name .. path.getbasename(fname)) .. ".resources"
  86. else
  87. return fname
  88. end
  89. end
  90. --
  91. -- Iterate and output some selection of the source code files.
  92. --
  93. function cs.listsources(prj, selector)
  94. local tr = project.getsourcetree(prj)
  95. p.tree.traverse(tr, {
  96. onleaf = function(node, depth)
  97. local value = selector(node)
  98. if value then
  99. _x('\t%s \\', value)
  100. end
  101. end
  102. })
  103. end
  104. ---------------------------------------------------------------------------
  105. --
  106. -- Handlers for individual makefile elements
  107. --
  108. ---------------------------------------------------------------------------
  109. function make.csAllRules(prj, toolset)
  110. _p('all: $(TARGETDIR) $(OBJDIR) prebuild $(EMBEDFILES) $(COPYFILES) prelink $(TARGET)')
  111. _p('')
  112. end
  113. function make.csCleanRules(prj, toolset)
  114. --[[
  115. -- porting from 4.x
  116. _p('clean:')
  117. _p('\t@echo Cleaning %s', prj.name)
  118. _p('ifeq (posix,$(SHELLTYPE))')
  119. _p('\t$(SILENT) rm -f $(TARGETDIR)/%s.* $(COPYFILES)', target.basename)
  120. _p('\t$(SILENT) rm -rf $(OBJDIR)')
  121. _p('else')
  122. _p('\t$(SILENT) if exist $(subst /,\\\\,$(TARGETDIR)/%s) del $(subst /,\\\\,$(TARGETDIR)/%s.*)', target.name, target.basename)
  123. for target, source in pairs(cfgpairs[anycfg]) do
  124. _p('\t$(SILENT) if exist $(subst /,\\\\,%s) del $(subst /,\\\\,%s)', target, target)
  125. end
  126. for target, source in pairs(copypairs) do
  127. _p('\t$(SILENT) if exist $(subst /,\\\\,%s) del $(subst /,\\\\,%s)', target, target)
  128. end
  129. _p('\t$(SILENT) if exist $(subst /,\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\,$(OBJDIR))')
  130. _p('endif')
  131. _p('')
  132. --]]
  133. end
  134. function make.csCopyFiles(prj, toolset)
  135. --[[
  136. -- copied from 4.x; needs more porting
  137. _p('COPYFILES += \\')
  138. for target, source in pairs(cfgpairs[anycfg]) do
  139. _p('\t%s \\', target)
  140. end
  141. for target, source in pairs(copypairs) do
  142. _p('\t%s \\', target)
  143. end
  144. _p('')
  145. --]]
  146. end
  147. function make.cs.getresponsefilename(prj)
  148. return '$(OBJDIR)/' .. prj.filename .. '.rsp'
  149. end
  150. function make.csResponseFile(prj, toolset)
  151. _x('RESPONSE += ' .. make.cs.getresponsefilename(prj))
  152. end
  153. function make.csResponseRules(prj)
  154. local toolset = p.tools.dotnet
  155. local ext = make.getmakefilename(prj, true)
  156. local makefile = path.getname(p.filename(prj, ext))
  157. local response = make.cs.getresponsefilename(prj)
  158. _p('$(RESPONSE): %s', makefile)
  159. _p('\t@echo Generating response file', prj.name)
  160. _p('ifeq (posix,$(SHELLTYPE))')
  161. _x('\t$(SILENT) rm -f $(RESPONSE)')
  162. _p('else')
  163. _x('\t$(SILENT) if exist $(RESPONSE) del %s', path.translate(response, '\\'))
  164. _p('endif')
  165. local sep = os.istarget("windows") and "\\" or "/"
  166. local tr = project.getsourcetree(prj)
  167. p.tree.traverse(tr, {
  168. onleaf = function(node, depth)
  169. if toolset.fileinfo(node).action == "Compile" then
  170. _x('\t@echo %s >> $(RESPONSE)', path.translate(node.relpath, sep))
  171. end
  172. end
  173. })
  174. _p('')
  175. end
  176. function make.csEmbedFiles(prj, toolset)
  177. local cfg = project.getfirstconfig(prj)
  178. _p('EMBEDFILES += \\')
  179. cs.listsources(prj, function(node)
  180. local fcfg = fileconfig.getconfig(node, cfg)
  181. local info = toolset.fileinfo(fcfg)
  182. if info.action == "EmbeddedResource" then
  183. return cs.getresourcefilename(cfg, node.relpath)
  184. end
  185. end)
  186. _p('')
  187. end
  188. function make.csFileRules(prj, toolset)
  189. --[[
  190. -- porting from 4.x
  191. _p('# Per-configuration copied file rules')
  192. for cfg in p.eachconfig(prj) do
  193. _x('ifneq (,$(findstring %s,$(config)))', cfg.name:lower())
  194. for target, source in pairs(cfgpairs[cfg]) do
  195. p.make_copyrule(source, target)
  196. end
  197. _p('endif')
  198. _p('')
  199. end
  200. _p('# Copied file rules')
  201. for target, source in pairs(copypairs) do
  202. p.make_copyrule(source, target)
  203. end
  204. _p('# Embedded file rules')
  205. for _, fname in ipairs(embedded) do
  206. if path.getextension(fname) == ".resx" then
  207. _x('%s: %s', getresourcefilename(prj, fname), fname)
  208. _p('\t$(SILENT) $(RESGEN) $^ $@')
  209. end
  210. _p('')
  211. end
  212. --]]
  213. end
  214. function make.csFlags(cfg, toolset)
  215. _p(' FLAGS =%s', make.list(toolset.getflags(cfg)))
  216. end
  217. function make.csLinkCmd(cfg, toolset)
  218. local deps = p.esc(config.getlinks(cfg, "dependencies", "fullpath"))
  219. _p(' DEPENDS =%s', make.list(deps))
  220. _p(' REFERENCES = %s', table.implode(deps, "/r:", "", " "))
  221. end
  222. function make.csProjectConfig(prj, toolset)
  223. -- To maintain compatibility with Visual Studio, these values must
  224. -- be set on the project level, and not per-configuration.
  225. local cfg = project.getfirstconfig(prj)
  226. local kindflag = "/t:" .. toolset.getkind(cfg):lower()
  227. local libdirs = table.implode(p.esc(cfg.libdirs), "/lib:", "", " ")
  228. _p('FLAGS += %s', table.concat(table.join(kindflag, libdirs), " "))
  229. local refs = p.esc(config.getlinks(cfg, "system", "fullpath"))
  230. _p('REFERENCES += %s', table.implode(refs, "/r:", "", " "))
  231. _p('')
  232. end
  233. function make.csSources(prj, toolset)
  234. local cfg = project.getfirstconfig(prj)
  235. _p('SOURCES += \\')
  236. cs.listsources(prj, function(node)
  237. local fcfg = fileconfig.getconfig(node, cfg)
  238. local info = toolset.fileinfo(fcfg)
  239. if info.action == "Compile" then
  240. return node.relpath
  241. end
  242. end)
  243. _p('')
  244. end
  245. function make.csTargetRules(prj, toolset)
  246. _p('$(TARGET): $(SOURCES) $(EMBEDFILES) $(DEPENDS) $(RESPONSE)')
  247. _p('\t$(SILENT) $(CSC) /nologo /out:$@ $(FLAGS) $(REFERENCES) @$(RESPONSE) $(patsubst %%,/resource:%%,$(EMBEDFILES))')
  248. _p('\t$(POSTBUILDCMDS)')
  249. _p('')
  250. end
  251. function make.csTools(cfg, toolset)
  252. _p(' CSC = %s', toolset.gettoolname(cfg, "csc"))
  253. _p(' RESGEN = %s', toolset.gettoolname(cfg, "resgen"))
  254. end