vs2005_dotnetbase.lua 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. --
  2. -- vs2005_dotnetbase.lua
  3. -- Generate a Visual Studio 2005+ .NET project.
  4. -- Copyright (c) Jason Perkins and the Premake project
  5. --
  6. local p = premake
  7. p.vstudio.dotnetbase = {}
  8. local vstudio = p.vstudio
  9. local dotnetbase = p.vstudio.dotnetbase
  10. local project = p.project
  11. local config = p.config
  12. local fileconfig = p.fileconfig
  13. local dotnet = p.tools.dotnet
  14. dotnetbase.elements = {}
  15. dotnetbase.langObj = {}
  16. dotnetbase.netcore = {}
  17. --
  18. -- Generate a Visual Studio 200x dotnet project, with support for the new platforms API.
  19. --
  20. function dotnetbase.prepare(langObj)
  21. dotnetbase.elements.project = langObj.elements.project
  22. dotnetbase.elements.projectProperties = langObj.elements.projectProperties
  23. dotnetbase.elements.configuration = langObj.elements.configuration
  24. dotnetbase.langObj = langObj
  25. end
  26. function dotnetbase.generate(prj)
  27. p.utf8()
  28. p.callArray(dotnetbase.elements.project, prj)
  29. _p(1,'<ItemGroup>')
  30. dotnetbase.files(prj)
  31. _p(1,'</ItemGroup>')
  32. dotnetbase.projectReferences(prj)
  33. dotnetbase.packageReferences(prj)
  34. dotnetbase.langObj.targets(prj)
  35. dotnetbase.buildEvents(prj)
  36. p.out('</Project>')
  37. end
  38. --
  39. -- Write the opening <Project> element.
  40. --
  41. function dotnetbase.projectElement(prj)
  42. if dotnetbase.isNewFormatProject(prj) then
  43. if prj.flags.WPF then
  44. _p('<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">')
  45. else
  46. _p('<Project Sdk="Microsoft.NET.Sdk">')
  47. end
  48. else
  49. local ver = ''
  50. local action = p.action.current()
  51. if action.vstudio.toolsVersion then
  52. ver = string.format(' ToolsVersion="%s"', action.vstudio.toolsVersion)
  53. end
  54. _p('<Project%s DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">', ver)
  55. end
  56. end
  57. --
  58. -- Write the opening PropertyGroup, which contains the project-level settings.
  59. --
  60. function dotnetbase.projectProperties(prj)
  61. _p(1,'<PropertyGroup>')
  62. local cfg = project.getfirstconfig(prj)
  63. p.callArray(dotnetbase.elements.projectProperties, cfg)
  64. _p(1,'</PropertyGroup>')
  65. end
  66. --
  67. -- Write out the settings for the project configurations.
  68. --
  69. function dotnetbase.configurations(prj)
  70. for cfg in project.eachconfig(prj) do
  71. dotnetbase.configuration(cfg)
  72. end
  73. end
  74. function dotnetbase.configuration(cfg)
  75. p.callArray(dotnetbase.elements.configuration, cfg)
  76. _p(1,'</PropertyGroup>')
  77. end
  78. function dotnetbase.dofile(node, cfg, condition)
  79. local filecfg = fileconfig.getconfig(node, cfg)
  80. if filecfg then
  81. local fname = path.translate(node.relpath)
  82. -- Files that live outside of the project tree need to be "linked"
  83. -- and provided with a project relative pseudo-path. Check for any
  84. -- leading "../" sequences and, if found, remove them and mark this
  85. -- path as external.
  86. local link, count = node.relpath:gsub("%.%.%/", "")
  87. local external = (count > 0)
  88. -- Try to provide a little bit of flexibility by allowing virtual
  89. -- paths for external files. Would be great to support them for all
  90. -- files but Visual Studio chokes if file is already in project area.
  91. if external and node.vpath ~= node.relpath then
  92. link = node.vpath
  93. end
  94. -- Deduce what, if any, special attributes are required for this file.
  95. -- For example, forms may have related source, designer, and resource
  96. -- files which need to be associated.
  97. local info = dotnet.fileinfo(filecfg)
  98. -- Process any sub-elements required by this file; choose the write
  99. -- element form to use based on the results.
  100. local contents = p.capture(function ()
  101. -- Try to write file-level elements in the same order as Visual Studio
  102. local elements = {
  103. "AutoGen",
  104. "CopyToOutputDirectory",
  105. "DesignTime",
  106. "DependentUpon",
  107. "DesignTimeSharedInput",
  108. "Generator",
  109. "LastGenOutput",
  110. "SubType",
  111. }
  112. for _, el in ipairs(elements) do
  113. local value = info[el]
  114. if value then
  115. _p(3,"<%s>%s</%s>", el, value, el)
  116. end
  117. end
  118. if info.action == "EmbeddedResource" and cfg.customtoolnamespace then
  119. _p(3,"<CustomToolNamespace>%s</CustomToolNamespace>", cfg.customtoolnamespace)
  120. end
  121. end)
  122. if #contents > 0 or external then
  123. _p(2,'<%s%s Include="%s">', info.action, condition, fname)
  124. if external and info.action ~= "EmbeddedResource" then
  125. _p(3,'<Link>%s</Link>', path.translate(link))
  126. end
  127. if #contents > 0 then
  128. _p("%s", contents)
  129. end
  130. _p(2,'</%s>', info.action)
  131. else
  132. _p(2,'<%s%s Include="%s" />', info.action, condition, fname)
  133. end
  134. end
  135. end
  136. --
  137. -- Write out the source files item group.
  138. --
  139. function dotnetbase.files(prj)
  140. local firstcfg = project.getfirstconfig(prj)
  141. local processfcfg = function(node)
  142. -- test if all fileinfo's are going to be the same for each config.
  143. local allsame = true
  144. local first = nil
  145. for cfg in project.eachconfig(prj) do
  146. local filecfg = fileconfig.getconfig(node, cfg)
  147. local info = dotnet.fileinfo(filecfg)
  148. if first == nil then
  149. first = info
  150. elseif not table.equals(first, info) then
  151. allsame = false
  152. end
  153. end
  154. -- output to proj file.
  155. if allsame then
  156. dotnetbase.dofile(node, firstcfg, '')
  157. else
  158. for cfg in project.eachconfig(prj) do
  159. dotnetbase.dofile(node, cfg, ' ' .. dotnetbase.condition(cfg))
  160. end
  161. end
  162. end
  163. if project.isfsharp(prj) then
  164. sorter = function(a,b)
  165. verbosef('Sorting F# proj file (%s, %s), index %s < %s', a.name, b.name, a.order, b.order)
  166. return a.order < b.order
  167. end
  168. table.sort(prj._.files, sorter)
  169. table.foreachi(prj._.files, processfcfg)
  170. else
  171. local tr = project.getsourcetree(prj)
  172. p.tree.traverse(tr, {
  173. onleaf = processfcfg
  174. }, false)
  175. end
  176. end
  177. --
  178. -- Write out pre- and post-build events, if provided.
  179. --
  180. function dotnetbase.buildEvents(prj)
  181. local function output(name, steps)
  182. if #steps > 0 then
  183. steps = os.translateCommandsAndPaths(steps, prj.basedir, prj.location)
  184. steps = table.implode(steps, "", "", "\r\n")
  185. _x(2,'<%sBuildEvent>%s</%sBuildEvent>', name, steps, name)
  186. end
  187. end
  188. local cfg = project.getfirstconfig(prj)
  189. if #cfg.prebuildcommands > 0 or #cfg.postbuildcommands > 0 then
  190. _p(1,'<PropertyGroup>')
  191. output("Pre", cfg.prebuildcommands)
  192. output("Post", cfg.postbuildcommands)
  193. _p(1,'</PropertyGroup>')
  194. end
  195. end
  196. --
  197. -- Write the compiler flags for a particular configuration.
  198. --
  199. function dotnetbase.compilerProps(cfg)
  200. _x(2,'<DefineConstants>%s</DefineConstants>', table.concat(cfg.defines, ";"))
  201. _p(2,'<ErrorReport>prompt</ErrorReport>')
  202. _p(2,'<WarningLevel>4</WarningLevel>')
  203. if not dotnetbase.isNewFormatProject(cfg) then
  204. dotnetbase.allowUnsafeBlocks(cfg)
  205. end
  206. if cfg.flags.FatalCompileWarnings then
  207. _p(2,'<TreatWarningsAsErrors>true</TreatWarningsAsErrors>')
  208. end
  209. dotnetbase.debugCommandParameters(cfg)
  210. end
  211. --
  212. -- Write out the debug start parameters for MonoDevelop/Xamarin Studio.
  213. --
  214. function dotnetbase.debugCommandParameters(cfg)
  215. if #cfg.debugargs > 0 then
  216. _x(2,'<Commandlineparameters>%s</Commandlineparameters>', table.concat(cfg.debugargs, " "))
  217. end
  218. end
  219. --
  220. -- Write out the debugging and optimization flags for a configuration.
  221. --
  222. function dotnetbase.debugProps(cfg)
  223. if _ACTION >= "vs2019" then
  224. if cfg.symbols == "Full" then
  225. _p(2,'<DebugType>full</DebugType>')
  226. _p(2,'<DebugSymbols>true</DebugSymbols>')
  227. elseif cfg.symbols == p.OFF then
  228. _p(2,'<DebugType>none</DebugType>')
  229. _p(2,'<DebugSymbols>false</DebugSymbols>')
  230. elseif cfg.symbols == p.ON or cfg.symbols == "FastLink" then
  231. _p(2,'<DebugType>pdbonly</DebugType>')
  232. _p(2,'<DebugSymbols>true</DebugSymbols>')
  233. else
  234. _p(2,'<DebugType>portable</DebugType>')
  235. _p(2,'<DebugSymbols>true</DebugSymbols>')
  236. end
  237. else
  238. if cfg.symbols == p.ON then
  239. _p(2,'<DebugSymbols>true</DebugSymbols>')
  240. _p(2,'<DebugType>full</DebugType>')
  241. else
  242. _p(2,'<DebugType>pdbonly</DebugType>')
  243. end
  244. end
  245. _p(2,'<Optimize>%s</Optimize>', iif(config.isOptimizedBuild(cfg), "true", "false"))
  246. end
  247. --
  248. -- Write out the target and intermediates settings for a configuration.
  249. --
  250. function dotnetbase.outputProps(cfg)
  251. local outdir = vstudio.path(cfg, cfg.buildtarget.directory)
  252. _x(2,'<OutputPath>%s\\</OutputPath>', outdir)
  253. -- Want to set BaseIntermediateOutputPath because otherwise VS will create obj/
  254. -- anyway. But VS2008 throws up ominous warning if present.
  255. local objdir = vstudio.path(cfg, cfg.objdir)
  256. if _ACTION > "vs2008" and not dotnetbase.isNewFormatProject(cfg) then
  257. _x(2,'<BaseIntermediateOutputPath>%s\\</BaseIntermediateOutputPath>', objdir)
  258. _p(2,'<IntermediateOutputPath>$(BaseIntermediateOutputPath)</IntermediateOutputPath>')
  259. else
  260. _x(2,'<IntermediateOutputPath>%s\\</IntermediateOutputPath>', objdir)
  261. end
  262. end
  263. --
  264. -- Write out the references item group.
  265. --
  266. dotnetbase.elements.references = function(cfg)
  267. return {
  268. dotnetbase.assemblyReferences,
  269. dotnetbase.nuGetReferences,
  270. }
  271. end
  272. function dotnetbase.references(prj)
  273. for cfg in project.eachconfig(prj) do
  274. _p(1,'<ItemGroup %s>', dotnetbase.condition(cfg))
  275. p.callArray(dotnetbase.elements.references, cfg)
  276. _p(1,'</ItemGroup>')
  277. end
  278. end
  279. --
  280. -- Write the list of assembly (system, or non-sibling) references.
  281. --
  282. function dotnetbase.assemblyReferences(cfg)
  283. local prj = cfg.project
  284. config.getlinks(cfg, "system", function(original, decorated)
  285. local name = path.getname(decorated)
  286. if path.getextension(name) == ".dll" then
  287. name = name.sub(name, 1, -5)
  288. end
  289. if decorated:find("/", nil, true) then
  290. _x(2,'<Reference Include="%s">', name)
  291. local decPath, decVars = decorated:match("(.-),")
  292. if not decPath then
  293. decPath = decorated
  294. end
  295. _x(3,'<HintPath>%s</HintPath>', path.appendextension(path.translate(decPath), ".dll"))
  296. if not config.isCopyLocal(prj, original, true) then
  297. _p(3,"<Private>False</Private>")
  298. end
  299. _p(2,'</Reference>')
  300. else
  301. _x(2,'<Reference Include="%s" />', name)
  302. end
  303. end)
  304. end
  305. --
  306. -- This is a bit janky. To compare versions, we extract all numbers from the
  307. -- given string and right-pad the result with zeros. Then we can just do a
  308. -- lexicographical compare on the resulting strings.
  309. --
  310. -- This is so that we can compare version strings such as "4.6" and "net451"
  311. -- with each other.
  312. --
  313. function dotnetbase.makeVersionComparable(version)
  314. local numbers = ""
  315. for number in version:gmatch("%d") do
  316. numbers = numbers .. number
  317. end
  318. return string.format("%-10d", numbers):gsub(" ", "0")
  319. end
  320. --
  321. -- https://github.com/NuGet/NuGet.Client/blob/dev/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkParseTests.cs
  322. --
  323. function dotnetbase.frameworkVersionForFolder(folder)
  324. -- If this exporter ever supports frameworks such as "netstandard1.3",
  325. -- "sl4", "sl5", "uap10", "wp8" or "wp71", this code will need changing
  326. -- to match the right folders, depending on the current framework.
  327. -- Right now this only matches folders for the .NET Framework.
  328. if folder:match("^net%d+$") or folder:match("^[0-9%.]+$") then
  329. return dotnetbase.makeVersionComparable(folder)
  330. elseif folder == "net" then
  331. return dotnetbase.makeVersionComparable("0")
  332. end
  333. end
  334. --
  335. -- Write the list of NuGet references.
  336. --
  337. function dotnetbase.nuGetReferences(cfg)
  338. local prj = cfg.project
  339. if _ACTION >= "vs2010" and not vstudio.nuget2010.supportsPackageReferences(prj) then
  340. for _, package in ipairs(prj.nuget) do
  341. local id = vstudio.nuget2010.packageId(package)
  342. local packageAPIInfo = vstudio.nuget2010.packageAPIInfo(prj, package)
  343. local action = p.action.current()
  344. local targetFramework = cfg.dotnetframework or action.vstudio.targetFramework
  345. local targetVersion = dotnetbase.makeVersionComparable(targetFramework)
  346. -- Figure out what folder contains the files for the nearest
  347. -- supported .NET Framework version.
  348. local files = {}
  349. local bestVersion, bestFolder
  350. for _, file in ipairs(packageAPIInfo.packageEntries) do
  351. local folder = file:match("^lib[\\/](.+)[\\/]")
  352. if folder and path.hasextension(file, ".dll") then
  353. local version = dotnetbase.frameworkVersionForFolder(folder)
  354. if version then
  355. files[folder] = files[folder] or {}
  356. table.insert(files[folder], file)
  357. if version <= targetVersion and (not bestVersion or version > bestVersion) then
  358. bestVersion = version
  359. bestFolder = folder
  360. end
  361. end
  362. end
  363. end
  364. if not bestVersion then
  365. p.error("NuGet package '%s' is not compatible with project '%s' .NET Framework version '%s'", id, prj.name, targetFramework)
  366. end
  367. -- Now, add references for all DLLs in that folder.
  368. for _, file in ipairs(files[bestFolder]) do
  369. -- There's some stuff missing from this include that we
  370. -- can't get from the API and would need to download and
  371. -- extract the package to figure out. It looks like we can
  372. -- just omit it though.
  373. --
  374. -- So, for example, instead of:
  375. --
  376. -- <Reference Include="nunit.framework, Version=3.6.1.0,
  377. -- <Culture=neutral, PublicKeyToken=2638cd05610744eb,
  378. -- <processorArchitecture=MSIL">
  379. --
  380. -- We're just outputting:
  381. --
  382. -- <Reference Include="nunit.framework">
  383. _x(2, '<Reference Include="%s">', path.getbasename(file))
  384. _x(3, '<HintPath>%s</HintPath>', vstudio.path(prj, p.filename(prj.workspace, string.format("packages\\%s.%s\\%s", id, packageAPIInfo.verbatimVersion or packageAPIInfo.version, file))))
  385. if config.isCopyLocal(prj, package, true) then
  386. _p(3, '<Private>True</Private>')
  387. else
  388. _p(3, '<Private>False</Private>')
  389. end
  390. _p(2, '</Reference>')
  391. end
  392. end
  393. end
  394. end
  395. --
  396. -- Write the list of project dependencies.
  397. --
  398. function dotnetbase.projectReferences(prj)
  399. if not dotnetbase.isNewFormatProject(prj) then
  400. _p(1,'<ItemGroup>')
  401. end
  402. local deps = project.getdependencies(prj, 'linkOnly')
  403. if #deps > 0 then
  404. if dotnetbase.isNewFormatProject(prj) then
  405. _p(1,'<ItemGroup>')
  406. end
  407. for _, dep in ipairs(deps) do
  408. local relpath = vstudio.path(prj, vstudio.projectfile(dep))
  409. _x(2,'<ProjectReference Include="%s">', relpath)
  410. _p(3,'<Project>{%s}</Project>', dep.uuid)
  411. _x(3,'<Name>%s</Name>', dep.name)
  412. if not config.isCopyLocal(prj, dep.name, true) then
  413. _p(3,"<Private>False</Private>")
  414. end
  415. _p(2,'</ProjectReference>')
  416. end
  417. if dotnetbase.isNewFormatProject(prj) then
  418. _p(1,'</ItemGroup>')
  419. end
  420. end
  421. if not dotnetbase.isNewFormatProject(prj) then
  422. _p(1,'</ItemGroup>')
  423. end
  424. end
  425. --
  426. -- Write the list of package dependencies.
  427. --
  428. function dotnetbase.packageReferences(prj)
  429. if vstudio.nuget2010.supportsPackageReferences(prj) then
  430. local hasNuget = prj.nuget and #prj.nuget>0
  431. for cfg in project.eachconfig(prj) do
  432. if cfg.nuget and #cfg.nuget>0 then
  433. hasNuget = true
  434. end
  435. end
  436. if hasNuget then
  437. _p(1,'<ItemGroup>')
  438. if prj.nuget and #prj.nuget>0 then
  439. for _, package in ipairs(prj.nuget) do
  440. _p(2,'<PackageReference Include="%s" Version="%s"/>', vstudio.nuget2010.packageId(package), vstudio.nuget2010.packageVersion(package))
  441. end
  442. end
  443. for cfg in project.eachconfig(prj) do
  444. if cfg.nuget and #cfg.nuget>0 then
  445. for _, package in ipairs(cfg.nuget) do
  446. if prj.nuget[package]==nil then
  447. _p(2,'<PackageReference Include="%s" Version="%s" %s/>', vstudio.nuget2010.packageId(package), vstudio.nuget2010.packageVersion(package), dotnetbase.condition(cfg))
  448. end
  449. end
  450. end
  451. end
  452. _p(1,'</ItemGroup>')
  453. end
  454. end
  455. end
  456. --
  457. -- Return the Visual Studio architecture identification string. The logic
  458. -- to select this is getting more complicated in VS2010, but I haven't
  459. -- tackled all the permutations yet.
  460. --
  461. function dotnetbase.arch(cfg)
  462. local arch = vstudio.archFromConfig(cfg)
  463. if arch == "Any CPU" then
  464. arch = "AnyCPU"
  465. end
  466. return arch
  467. end
  468. --
  469. -- Write the PropertyGroup element for a specific configuration block.
  470. --
  471. function dotnetbase.propertyGroup(cfg)
  472. p.push('<PropertyGroup %s>', dotnetbase.condition(cfg))
  473. local arch = dotnetbase.arch(cfg)
  474. if arch ~= "AnyCPU" or _ACTION > "vs2008" then
  475. p.x('<PlatformTarget>%s</PlatformTarget>', arch)
  476. end
  477. end
  478. --
  479. -- Generators for individual project elements.
  480. --
  481. function dotnetbase.applicationIcon(prj)
  482. if prj.icon then
  483. local icon = vstudio.path(prj, prj.icon)
  484. _p(1,'<PropertyGroup>')
  485. _x(2,'<ApplicationIcon>%s</ApplicationIcon>', icon)
  486. _p(1,'</PropertyGroup>')
  487. end
  488. end
  489. ---------------------------------------------------------------------------
  490. --
  491. -- Support functions
  492. --
  493. ---------------------------------------------------------------------------
  494. --
  495. -- Format and return a Visual Studio Condition attribute.
  496. --
  497. function dotnetbase.condition(cfg)
  498. local platform = vstudio.projectPlatform(cfg)
  499. local arch = dotnetbase.arch(cfg)
  500. return string.format('Condition=" \'$(Configuration)|$(Platform)\' == \'%s|%s\' "', platform, arch)
  501. end
  502. --
  503. -- When given a .NET Framework version, returns it formatted for NuGet.
  504. --
  505. function dotnetbase.formatNuGetFrameworkVersion(framework)
  506. return "net" .. framework:gsub("%.", "")
  507. end
  508. ---------------------------------------------------------------------------
  509. --
  510. -- Handlers for individual project elements
  511. --
  512. ---------------------------------------------------------------------------
  513. function dotnetbase.appDesignerFolder(cfg)
  514. _p(2,'<AppDesignerFolder>Properties</AppDesignerFolder>')
  515. end
  516. function dotnetbase.assemblyName(cfg)
  517. if not dotnetbase.isNewFormatProject(cfg) --[[or cfg.assemblyname]] then
  518. _p(2,'<AssemblyName>%s</AssemblyName>', cfg.buildtarget.basename)
  519. end
  520. end
  521. function dotnetbase.commonProperties(prj)
  522. if _ACTION > "vs2010" then
  523. _p(1,'<Import Project="$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props" Condition="Exists(\'$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\')" />')
  524. end
  525. end
  526. function dotnetbase.configurationCondition(cfg)
  527. _x(2,'<Configuration Condition=" \'$(Configuration)\' == \'\' ">%s</Configuration>', cfg.buildcfg)
  528. end
  529. function dotnetbase.fileAlignment(cfg)
  530. if _ACTION >= "vs2010" and not dotnetbase.isNewFormatProject(cfg) then
  531. _p(2,'<FileAlignment>512</FileAlignment>')
  532. end
  533. end
  534. function dotnetbase.bindingRedirects(cfg)
  535. if _ACTION >= "vs2015" and not dotnetbase.isNewFormatProject(cfg) then
  536. _p(2, '<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>')
  537. end
  538. end
  539. function dotnetbase.outputType(cfg)
  540. _p(2,'<OutputType>%s</OutputType>', dotnet.getkind(cfg))
  541. end
  542. function dotnetbase.platformCondition(cfg)
  543. _p(2,'<Platform Condition=" \'$(Platform)\' == \'\' ">%s</Platform>', dotnetbase.arch(cfg.project))
  544. end
  545. function dotnetbase.productVersion(cfg)
  546. local action = p.action.current()
  547. if action.vstudio.productVersion then
  548. _p(2,'<ProductVersion>%s</ProductVersion>', action.vstudio.productVersion)
  549. end
  550. end
  551. function dotnetbase.projectGuid(cfg)
  552. _p(2,'<ProjectGuid>{%s}</ProjectGuid>', cfg.uuid)
  553. end
  554. function dotnetbase.projectTypeGuids(cfg)
  555. if cfg.flags.WPF then
  556. _p(2,'<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>')
  557. end
  558. end
  559. function dotnetbase.rootNamespace(cfg)
  560. if not dotnetbase.isNewFormatProject(cfg) or cfg.namespace then
  561. _p(2,'<RootNamespace>%s</RootNamespace>', cfg.namespace or cfg.buildtarget.basename)
  562. end
  563. end
  564. function dotnetbase.schemaVersion(cfg)
  565. local action = p.action.current()
  566. if action.vstudio.csprojSchemaVersion then
  567. _p(2,'<SchemaVersion>%s</SchemaVersion>', action.vstudio.csprojSchemaVersion)
  568. end
  569. end
  570. function dotnetbase.NoWarn(cfg)
  571. if #cfg.disablewarnings > 0 then
  572. local warnings = table.concat(cfg.disablewarnings, ";")
  573. _p(2,'<NoWarn>%s</NoWarn>', warnings)
  574. end
  575. end
  576. function dotnetbase.targetFrameworkVersion(cfg)
  577. local action = p.action.current()
  578. local framework = cfg.dotnetframework or action.vstudio.targetFramework
  579. if framework and not dotnetbase.isNewFormatProject(cfg) then
  580. _p(2,'<TargetFrameworkVersion>v%s</TargetFrameworkVersion>', framework)
  581. end
  582. end
  583. function dotnetbase.csversion(cfg)
  584. if cfg.csversion then
  585. _p(2,'<LangVersion>%s</LangVersion>', cfg.csversion)
  586. end
  587. end
  588. function dotnetbase.targetFrameworkProfile(cfg)
  589. if _ACTION == "vs2010" then
  590. _p(2,'<TargetFrameworkProfile>')
  591. _p(2,'</TargetFrameworkProfile>')
  592. end
  593. end
  594. function dotnetbase.xmlDeclaration()
  595. if _ACTION > "vs2008" then
  596. p.xmlUtf8()
  597. end
  598. end
  599. function dotnetbase.isNewFormatProject(cfg)
  600. local framework = cfg.dotnetframework
  601. if not framework then
  602. return false
  603. end
  604. if framework:find('^net') ~= nil then
  605. return true
  606. end
  607. return false
  608. end
  609. function dotnetbase.netcore.targetFramework(cfg)
  610. local action = p.action.current()
  611. local framework = cfg.dotnetframework or action.vstudio.targetFramework
  612. if framework and dotnetbase.isNewFormatProject(cfg) then
  613. _p(2,'<TargetFramework>%s</TargetFramework>', framework)
  614. end
  615. end
  616. function dotnetbase.netcore.enableDefaultCompileItems(cfg)
  617. _p(2,'<EnableDefaultCompileItems>%s</EnableDefaultCompileItems>', iif(cfg.enableDefaultCompileItems, "true", "false"))
  618. end
  619. function dotnetbase.netcore.useWpf(cfg)
  620. if cfg.flags.WPF then
  621. _p(2,'<UseWpf>true</UseWpf>')
  622. end
  623. end
  624. function dotnetbase.allowUnsafeBlocks(cfg)
  625. if cfg.clr == "Unsafe" then
  626. _p(2,'<AllowUnsafeBlocks>true</AllowUnsafeBlocks>')
  627. end
  628. end