简体   繁体   English

如何在.csproj文件中使用MSBuild条件测试编译器指令?

[英]How do I test for compiler directives with an MSBuild Condition in a .csproj file?

I am totally new to the functions and conditions in .csproj files so any and all help is appreciated. 我对.csproj文件中的功能和条件完全陌生,因此不胜感激。

What I want to do is check for a specific compiler directive in the current configuration. 我想做的是检查当前配置中的特定编译器指令。 An example would be something like the following: 一个示例如下所示:

<Choose>
    <When Condition= [current configuration has CONST-1 compiler constant defined] >
        ...
    </When>
    <When Condition= [current configuration has CONST-2 compiler constant defined] >
        ...
    </When>
</Choose>

I don't know if this is even possible or not. 我不知道这是否可能。 If there is a better way to do what I am asking let me know that as well. 如果有更好的方法来做我要问的事情,也请告诉我。 Either way, I want to test for a condition independent of the configuration. 无论哪种方式,我都想测试独立于配置的条件。

EDIT 编辑

What I really want is a value that I can edit easily, preferrably within Visual Studio, that I can also check regargless of the configuraiton. 我真正想要的是一个可以轻松编辑的值(最好是在Visual Studio中),我还可以检查配置的无条件设置。 I thought about compiler constants because you can easily change them in the Project Properties in VS. 我考虑过编译器常量,因为您可以在VS的项目属性中轻松更改它们。

Compiler constants are set into a property "DefineConstants" so you should just be able to evaluate that property. 编译器常量设置为属性“ DefineConstants”,因此您应该只可以评估该属性。 Your Choose statement needs to go after the PropertyGroups that define the constants or inside a target. 您的Choose语句需要放在定义常量的PropertyGroup或目标内部。

<Choose>
    <When Condition="$(DefineConstants.Contains(CONST-1))">
        ...
    </When>
    <When Condition="$(DefineConstants.Contains(CONST-2))">
        ...
    </When>
</Choose>

In case you use MSBuild 4 or higher, I suggest using Regular Expression instead of String.Contains(). 如果您使用MSBuild 4或更高版本,我建议使用正则表达式而不是String.Contains()。 The reason for this is that even though String.Contains() usually works well, there are some cases you might get into problems. 原因是,即使String.Contains()通常可以很好地工作,在某些情况下您也可能会遇到问题。

For example: 例如:

Consider case when you use directives CONST-1 and CONST-12 in your code. 当在代码中使用指令CONST-1和CONST-12时,请考虑大小写。 However, you decide to define only CONST-12 directive for current build. 但是,您决定只为当前构建定义CONST-12指令。
Now Condition="$(DefineConstants.Contains('CONST-1'))" evaluates to True even though CONST-1 is not defined. 现在,即使未定义CONST-1, Condition="$(DefineConstants.Contains('CONST-1'))"计算结果也为True

Solution with RegularExpressions.RegEx : 使用RegularExpressions.RegEx解决方案:

<When Condition="$([System.Text.RegularExpressions.Regex]::IsMatch($(DefineConstants), '^(.*;)*CONST-1(;.*)*$'))">
...
</When>

To sum up, you can either be careful to make sure you don't use directive that is Substring of another or you can use the regular expression and not worry at all. 总结起来,您可以小心确保不要使用另一个指令的Substring指令,也可以使用正则表达式而不用担心。

To add to the other answers posted here, another way you can approach this is to wrap the DefineConstants property with semicolons, to guarantee that ";CONST-1;" 要添加到此处发布的其他答案,您可以采用的另一种方法是用分号包装DefineConstants属性,以确保“; CONST-1;” will be contained in DefineConstants if and only if the "CONST-1" constant is defined. 当且仅当定义了“ CONST-1”常量时,它将包含在DefineConstants中。 Without the semicolons, you could have CONST-100, or UNCONST-1, but not CONST-1, as a variable and it would evaluate to true. 如果没有分号,则可以将CONST-100或UNCONST-1作为变量,而不能将CONST-1作为变量,并且其评估结果为true。

<PropertyGroup>
    <DefineConstants2>;$(DefineConstants);</DefineConstants2>
    <Foo Condition="'$(DefineConstants2.Contains(`;CONST-1;`))'">It worked</Foo>
    <Bar>$(Foo)</Bar> <!--It worked-->
</PropertyGroup>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM