【问题标题】:Solution-wide #define解决方案范围的#define
【发布时间】:2011-07-06 04:21:38
【问题描述】:

有没有办法全局声明一个#define?

就像我想要一个文件,例如,

#define MONO

并且我希望所有源代码文件都知道该预处理器指令已定义。我将如何实现这一目标?

【问题讨论】:

标签: c# c-preprocessor


【解决方案1】:

更新:您不能对 afaik 进行“解决方案范围”的定义,但是下面的答案在每个项目的基础上都是可行的。

您在编译属性或构建选项中设置它们:

http://msdn.microsoft.com/en-US/library/76zdzba1(v=VS.80).aspx (VS2008) http://msdn.microsoft.com/en-US/library/76zdzba1(v=VS.100).aspx (VS2010)

请参阅“设置自定义常量”标题。

更新

Microsoft Documentation on Build Options

您可以通过右键单击项目并从菜单中选择属性来访问构建选项。

【讨论】:

  • 您可以添加屏幕截图,尽管按照信中的说明进行操作,但我在 VS 2008 Pro 上根本看不到 Compile 选项卡。
  • 我认为这不能回答有关 solution 范围 #define? 的问题
  • 它可能不适合“解决方案范围”方面,但肯定比简单地说“你不能那样做”要好。
  • 这不是问题的答案
  • 这不是问题的答案,而且会误导浪费人们的时间。
【解决方案2】:

我知道 C# 项目的解决方案(我没有为任何其他项目测试过)

例如你有:

Project1\
Project2\
Solution1\Solution1.sln
Solution2\Solution2.sln

在解决方案目录中创建SolutionDefines.targets文件

Project1\
Project2\
Solution1\Solution1.sln
Solution1\SolutionDefines.targets
Solution2\Solution2.sln
Solution2\SolutionDefines.targets
Solution3\Solution2.sln
Solution3\|no target file|

在每个项目文件中添加:

<Import Project="$(SolutionDir)SolutionDefines.targets" Condition="exists('$(SolutionDir)SolutionDefines.targets')" />

Solution1\SolutionDefines.targets 中添加:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <DefineConstants>$(DefineConstants);TRACING_BUILD</DefineConstants>
    </PropertyGroup>
</Project>

Solution2\SolutionDefines.targets 添加:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <DefineConstants>$(DefineConstants);ANOTHER_DEFINE</DefineConstants>
    </PropertyGroup>
</Project>

在这种情况下,您有:

对于解决方案 1 - 所有项目都添加了 TRACING_BUILD 定义

对于解决方案 2 - 所有项目都添加了 ANOTHER_DEFINE 定义

对于解决方案 3 - 所有项目 - 未添加定义

在这种方法中,您必须将具有解决方案范围定义的所有解决方案存储在单独的目录中

【讨论】:

  • 让它与另外两个信息一起工作,非常感谢! 1) 在SolutionDefines.targets 文件中,我必须声明&lt;Project&gt; 没有任何属性,因此它也适用于新的“Microsoft.NET.Sdk”项目。 2) 包含必须放置在 项目的所有其他 &lt;DefineConstants&gt; 之后。
  • 保持干燥的最好(也是唯一的)方法
  • 出于某种原因,我需要重新构建项目/解决方案两次,以使SolutionDefines.targets 中的更改生效,并且即使在重新加载解决方案后,VS intellisense 也不总是检测到更改。
【解决方案3】:

多年后,类似于阿列克谢的回答,但天生支持

可以根据

制作一个类似于NuGet.Config 文件的Directory.Build.props

https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019

我们的样子:

<Project>
    <PropertyGroup>
        <DefineConstants>RC_427</DefineConstants>
    </PropertyGroup>
</Project>

它有效地将其包含在您的 SLN 中的所有 CSPROJ 文件中。出于某种原因,通过谷歌很难找到特定的解决方案。自 MSBuild 15 以来一直存在

【讨论】:

  • 另请注意,如果您更改这个新的全局解决方案文件中的常量,您必须卸载并重新加载每个 vs 项目才能让 VS intellisense 接受更改(ms build 会很好地接受更改)。
  • 此解决方案非常适合使用新 SDK 样式项目格式的项目,但使用旧的非 SDK 样式项目格式的项目在使用 Directory.Build.props 时会出现问题。见.props File Properties Not Reloaded When Changed
  • 不适用于 C# 中的 Azure SF 项目。卸载/重新加载/重建项目没有帮助。
【解决方案4】:

我认为没有办法创建解决方案范围#define。您可以为每个项目/程序集创建一个,如其他答案所述,但如果您需要了解所有源代码文件,则需要为解决方案中的每个项目执行此操作那个#define。

【讨论】:

    【解决方案5】:

    还有一种解决方法,如果我错了,请纠正我:

    例如,ProjectA 引用 ProjectBProjectsCommon 包含基本静态变量。这两个项目都引用了ProjectsCommon

    ProjectsCommon中的代码:

    [assembly: InternalsVisibleTo("ProjectA")]
    
    ------------------------------------------
    
    public class ConditionVariables
    {
        public static bool IsABC { get; internal set; } = false;
    }
    

    ProjectA中的代码:

    #if ABC
        ProjectsCommon.ConditionVariables.IsABC = true;
    #endif
    

    ProjectB中的代码:

    if (ProjectsCommon.ConditionVariables.IsABC )
    {
        // first scenario
    }
    else
    {
        // second one
    }
    

    但是,ProjectA 中的代码应该首先运行。当ProjectA 是一个引导程序项目时,这可能很好。

    【讨论】:

      【解决方案6】:

      扩展@Murtago 和@Mark Cidade 的答案以使其解决方案更广泛:

      打开解决方案的配置管理器并创建一个新配置(从最接近的匹配复制),然后为需要不同的项目更改条件符号。

      【讨论】:

        【解决方案7】:

        在配置管理器中创建新的解决方案配置,并确保选中该框以创建新的项目配置。然后在每个项目的Build属性中的条件编译符号框中输入MONO

        【讨论】:

        • 这如何解决解决方案范围的问题?
        【解决方案8】:

        在 vs 2013 中,您可以使用 /define:x 或 /d:x http://msdn.microsoft.com/en-us/library/0feaad6z.aspx

        【讨论】:

        • 这个选项一直存在,不仅是 VS2013,而且它为单个编译设置选项,而不是为整个解决方案定义宏
        【解决方案9】:

        预处理器指令的正确位置是 VS 构建配置。如果您使用命令行来构建您的解决方案,您也可以使用 /define 选项传递它。

        【讨论】:

        • 这如何解决解决方案范围的问题?
        【解决方案10】:

        我不知道解决方案范围的定义,但我能够通过执行以下操作快速将预处理器定义添加到所有项目:

        1. 按住 ctrl 并选择每个项目
        2. 右键单击任何选定的项目并选择Properties
        3. 转到C/C++ --> Preprocessor
        4. 点击Preprocessor Definitions旁边的小向下箭头
        5. 选择&lt;Edit...&gt;
        6. &lt;different options&gt;之后添加我的定义
        7. OK 不在菜单中

        我正在使用带有 C 代码库的 Visual Studio Community 2019。

        【讨论】:

        • 可以添加类似函数的宏吗?像#define IS_DOUBLE(X, Y) ((Y * 2 == X) ? 1 : 0) 这样的东西。如何在全球范围内添加这样的内容?
        【解决方案11】:

        如果您在解决方案中同时拥有 C# 和 C++ 项目,并且需要在它们之间共享预处理器定义。 在您的*.sln 附近创建一些SolutionDefines.targets 文件,如下所示

        <?xml version="1.0" encoding="utf-8"?>
        <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
            <PropertyGroup>
                <DefineConstants>$(DefineConstants);MY_DEFINITION</DefineConstants>
            </PropertyGroup>
          <ItemDefinitionGroup>
            <ClCompile>
              <PreprocessorDefinitions>MY_DEFINITION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
            </ClCompile>
          </ItemDefinitionGroup>
        </Project>
        

        然后在C/C++/C#*.vcproj/*.vcxproj/*.csproj项目文件中最后某处添加这一行

        <Import Project="$(SolutionDir)SolutionDefines.targets" Condition="exists('$(SolutionDir)SolutionDefines.targets')" />
        

        好的,现在您可以享受 C# 中的 #if MY_DEFINITION 和 C/C++ 中的 #ifdef MY_DEFINITION 了。 Visual Studio C# 编辑器不喜欢这种方式,并告诉没有定义MY_DEFINITION。但是,C# 编译器 csc.exe 可以正确获取符号。

        【讨论】:

          猜你喜欢
          • 2012-11-16
          • 2011-03-10
          • 2012-07-31
          • 2018-06-04
          • 1970-01-01
          • 2011-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多