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