MSBuild,定义条件编译符号

85

我可能眼瞎了,但是在MSBUILD中有没有命令行可以指定条件编译符号?

目前我的构建脚本中有这一行:

SET MSBUILD=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe
SET CONFIG=Debug
%MSBUILD% /p:Configuration=%CONFIG% /p:OutputPath=..\..\output source\MyProject\MyProject.csproj

我想添加一个条件。在Visual Studio中,我可以进入“项目属性”=>“生成”=>“条件编译符号”,但我没有看到msbuild中的该选项?

如果您知道我是否可以完全覆盖已在.csproj文件中指定的所有符号,以确保只有来自我的Buildscript的条件编译进入,则可以获得额外的Karma。


顺便说一句,这不是http://stackoverflow.com/questions/296147/msbuild-conditional-compilation的重复,因为另一个问题有相同的标题,但答案只包括Visual Studio /项目文件修改。 - Michael Stum
4个回答

153

你看过这个吗?(大部分信息在倒数第二篇文章中)

/p:DefineConstants="MYSYMBOL1;MYSYMBOL2"

5
已添加代码,就是这样,谢谢!它覆盖了在.csproj文件中定义的所有常量,这也很好。 - Michael Stum
6
为了让这对我起作用,我被迫将/t:Rebuild添加到命令行中。 - Dan W
在 macOS 终端使用 xbuild 命令,我得到了以下错误信息:MSBUILD: error MSBUILD0005: Invalid syntax. Property name and value expected as <prop name>=[<prop value>] - Sanandrea
1
有没有办法追加到现有的定义中? - James Esh
6
请注意,这将替换现有的定义,因此如果您依赖NETCOREAPP或NETFRAMEWORK之类的定义,您将失去它们。如果要附加到现有定义,则最好在.csproj文件中添加一个属性,如:<DefineConstants>$(DefineConstants);FOO;BAR</DefineConstants>。 - rmunn
显示剩余2条评论

22

我不得不使用空格代替分号,就像Björn Lasar在这篇文章中所述:http://www.linqinpark.net/2009/01/13/MSBuildWithMultipleDefineConstants.aspx

更新:该博客已经消失;通过Internet Archive检索:

最近,我不得不直接使用MSBuild来自动化一些构建。 我还必须根据配置来配置一些预处理器定义。 这通常是通过以下方式完成的

"/p:DefineConstants=MY_PREPROC_FLAG"

这里没有什么特别的,因为网络上已经有足够的评论了。今天我需要一个额外的标志并且我使用了类似于IDE中我所知道的命令行语法:

"/p:DefineConstants=MY_PREPROC_FLAG;YET_ANOTHER_FLAG"

但是这个方法并没有起作用。

所以问题在于,如果你想通过命令行支持将多个定义应用到项目中,你需要使用简单的空格来分隔它们...

"/p:DefineConstants=MY_PREPROC_FLAG YET_ANOTHER_FLAG" 

它将会被添加到(以分号分隔的)IDE Defines 中。我想这很重要...


你如何测试这些符号是否存在?我尝试了 if '$(SIGN_ASSEMBLY)' == '' goto :exit 但如果该符号不存在,你会得到相同的空字符串。 - Quark Soup
@MikeDoonsebury,通常我们使用值的存在以及其特定的值,例如 == "True" - 我不确定您在msbuild中的goto exit是什么意思 - 相当于在 <Task 上或任务调用上放置一个 Condition,例如 <Exec Condtion="$(SignAssembly)=='True' ... - Ruben Bartelink

6

/p:DefineConstants是一个全部或无的交易。

如果你只想关闭跟踪符号,你不能只使用以下命令: msbuild /p:DefineTrace=false

你必须定义一些内容来覆盖已经定义的所有符号:msbuild /p:DefineConstants="RANDOM-SYMBOL"

感谢Michael Stum指出了这个隐藏规则 我也写了一篇关于它的博客 --- 链接已失效


1
这里“所有的符号”非常重要。如果您使用 /p: DefineConstants 定义一个常量,那么您将失去项目中定义的所有其他常量。DefineConstants 应包含项目中需要的所有常量,您不能混合和匹配项目中定义的常量和使用 DefineConstants 定义的常量。 - Jitendra

1
答案中提到的内容适用于C#代码,也适用于ASP.NET“codebehind” C#代码。对于ASP.NET Web项目,如果您还想在ASPX页面中进行条件编译,则与在页面上有条件地呈现HTML略有不同(请注意,我已删除了通常在<%@ ... %>声明中具有的MasterPageFile="..." AutoEventWireup="true" CodeBehind="..." Inherits="..."):
<%@ Page Title="MyPage" Language="C#" CompilerOptions="/d:DebugSym1;DebugSym2" %>

<% #if DebugSym1 %>         
    <h4>Section1</h4>
<% #else %>
    <h4>(Section 1 skipped)</h4>
<% #endif %>

<% #if DebugSym2 %>         
    <h4>Section2</h4>
<% #else %>
    <h4>(Section 2 skipped)</h4>
<% #endif %>

如果您从CompilerOptions中删除DebugSym1DebugSym2,则相关的#if语句的#else部分将被呈现。
我认为这值得提一下,以便完整地介绍此主题并节省您的时间。如果您有兴趣,可以在文章中找到更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接