다음을 통해 공유


Visual Studio C++ 프로젝트 시스템 확장성 및 도구 세트 통합

Visual C++ 프로젝트 시스템은 .vcxproj 파일에 사용됩니다. 이는 Visual Studio CPS(Common Project System)를 기반으로 하며 새로운 도구 세트, 빌드 아키텍처, 대상 플랫폼을 쉽게 통합할 수 있는 추가적인 C++ 전용 확장성 포인트를 제공합니다.

C++ MSBuild 대상 구조체

모든 .vcxproj 파일은 다음 파일을 가져옵니다.

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

이러한 파일은 단독으로 정의하는 경우가 거의 없습니다. 대신 이러한 속성 값을 기반으로 다른 파일을 가져옵니다.

  • $(ApplicationType)

    예: Windows 스토어, Android, Linux

  • $(ApplicationTypeRevision)

    이는 major.minor[.build[.revision] 양식의 유효한 버전 문자열이어야 합니다.

    예제: 1.0, 10.0.0.0

  • $(Platform)

    기록상의 이유로 "플랫폼"이라고 명명한 빌드 아키텍처입니다.

    예: Win32, x86, x64, ARM

  • $(PlatformToolset)

    예: v140, v141, v141_xp, llvm

이러한 속성 값은 $(VCTargetsPath) 루트 폴더 아래에 폴더 이름을 지정합니다.

$(VCTargetsPath)\
    애플리케이션 유형\
        $(ApplicationType)\
            $(ApplicationTypeRevision)\
                플랫폼\
                    $(Platform)\
                        PlatformToolsets\
                            $(PlatformToolset)
    플랫폼\
        $(Platform)\
            PlatformToolsets\
                $(PlatformToolset)

$(VCTargetsPath)\Platforms\ 폴더는 $(ApplicationType)이 비어 있을 때 Windows 데스크톱 프로젝트에 사용됩니다.

새 플랫폼 도구 세트 추가

기존 Win32 플랫폼에 대한 "MyToolset"과 같은 새 도구 세트를 추가하려면 $(VCTargetsPath)\Platforms\Win32\PlatformToolsets\에서 MyToolset 폴더를 만들고 그 안에 Toolset.props 파일 및 Toolset.targets 파일을 만듭니다.

PlatformToolsets 아래의 각 폴더 이름은 다음과 같이 프로젝트 속성 대화 상자에 지정된 플랫폼에 사용할 수 있는 플랫폼 도구 세트로 표시됩니다.

The Platform Toolset property in the project Property Pages dialog

이 도구 세트에서 지원하는 각 기존 플랫폼 폴더에 유사한 MyToolset 폴더와 Toolset.props 파일 및 Toolset.targets 파일을 만듭니다.

새 플랫폼 추가

새 플랫폼(예: "MyPlatform")을 추가하려면 $(VCTargetsPath)\Platforms\ 아래에 MyPlatform 폴더를 만들고 그 안에 Platform.default.props 파일, Platform.props 파일, Platform.targets 파일을 만듭니다. 또한 $(VCTargetsPath)\Platforms\MyPlatform\PlatformToolsets\ 폴더를 만들고 그 안에 하나 이상의 도구 세트를 만듭니다.

$(ApplicationType)$(ApplicationTypeRevision)에 대한 Platforms 폴더 아래의 모든 폴더 이름이 프로젝트에 사용 가능한 플랫폼 선택 항목으로 IDE에 표시됩니다.

The New platform choice in the New Project Platform dialog

새 애플리케이션 유형 추가

새 애플리케이션 유형을 추가하려면 $(VCTargetsPath)\Application Type\ 아래에 MyApplicationType 폴더를 만들고 그 안에 Defaults.props 파일을 만듭니다. 애플리케이션 유형에 대해 하나 이상 수정해야 하므로 $(VCTargetsPath)\Application Type\MyApplicationType\1.0 폴더를 만들고 그 안에 Defaults.props 파일을 만듭니다. 또한 $(VCTargetsPath)\ApplicationType\MyApplicationType\1.0\Platforms 폴더를 만들고 그 안에 하나 이상의 플랫폼을 만들어야 합니다.

$(ApplicationType)$(ApplicationTypeRevision) 속성은 사용자 인터페이스에 표시되지 않습니다. 프로젝트 템플릿에 정의되며 프로젝트를 만든 후에는 변경할 수 없습니다.

.vcxproj 가져오기 트리

Microsoft C++ props 및 대상 파일에 대한 기본 가져오기 트리는 다음과 같습니다.

$(VCTargetsPath)\Microsoft.Cpp.Default.props
    $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props
    $(VCTargetsPath)\ImportBefore\Default\*.props
    $(VCTargetsPath)\Application Type\$(ApplicationType)\Default.props
    $(VCTargetsPath)\Application Type\$(ApplicationType)\$(ApplicationTypeRevision)\Default.props
    $(VCTargetsPath)\Application Type\$(ApplicationType)\$(ApplicationTypeRevision)\Platforms\$(Platform)\Platform.default.props
    $(VCTargetsPath)\ImportAfter\Default\*.props

Windows 데스크톱 프로젝트는 $(ApplicationType)을 정의하지 않으므로 가져오기만 합니다.

$(VCTargetsPath)\Microsoft.Cpp.Default.props
    $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props
    $(VCTargetsPath)\ImportBefore\Default\*.props
    $(VCTargetsPath)\Platforms\$(Platform)\Platform.default.props
    $(VCTargetsPath)\ImportAfter\Default\*.props

$(_PlatformFolder) 속성을 사용하여 $(Platform) 플랫폼 폴더 위치를 유지합니다. 이 속성은

$(VCTargetsPath)\Platforms\$(Platform)

(Windows 데스크톱 앱의 경우)이며

$(VCTargetsPath)\Application Type\$(ApplicationType)\$(ApplicationTypeRevision)\Platforms\$(Platform)

(다른 모든 항목의 경우)입니다.

props 파일은 다음 순서로 가져옵니다.

$(VCTargetsPath)\Microsoft.Cpp.props
    $(_PlatformFolder)\Platform.props
        $(VCTargetsPath)\Microsoft.Cpp.Platform.props
            $(_PlatformFolder)\ImportBefore\*.props
            $(_PlatformFolder)\PlatformToolsets\$(PlatformToolset)\Toolset.props
            $(_PlatformFolder)\ImportAfter\*.props

대상 파일은 다음 순서로 가져옵니다.

$(VCTargetsPath)\Microsoft.Cpp.targets
    $(VCTargetsPath)\Microsoft.Cpp.Current.targets
        $(_PlatformFolder)\Platform.targets
            $(VCTargetsPath)\Microsoft.Cpp.Platform.targets
                $(_PlatformFolder)\ImportBefore\*.targets
                $(_PlatformFolder)\PlatformToolsets\$(PlatformToolset)\Toolset.target
                $(_PlatformFolder)\ImportAfter\*.targets

도구 세트에 대한 몇 가지 기본 속성을 정의해야 하는 경우 적절한 ImportBefore 폴더 및 ImportAfter 폴더에 파일을 추가할 수 있습니다.

Toolset.props 파일 및 Toolset.targets 파일 작성

Toolset.props 파일 및 Toolset.targets 파일은 이 도구 세트를 사용할 때 빌드 중에 발생하는 작업을 완전히 제어할 수 있습니다. 또한 사용 가능한 디버거, 속성 페이지 대화 상자의 콘텐츠와 같은 일부 IDE 사용자 인터페이스 및 프로젝트 동작의 다른 측면을 제어할 수 있습니다.

도구 세트는 전체 빌드 프로세스를 재정의할 수 있지만 일반적으로 도구 세트에서 일부 빌드 단계를 수정하거나 추가하거나 다른 빌드 도구를 기존 빌드 프로세스의 일부로 사용하려고 합니다. 이 목표를 달성하기 위해 여러 가지 일반 소품 및 대상 파일을 도구 세트에서 가져올 수 있습니다. 도구 세트로 어떤 작업을 수행하느냐에 따라 이러한 파일은 가져오기 또는 예제로 사용하는 데 유용할 수 있습니다.

  • $(VCTargetsPath)\Microsoft.CppCommon.targets

    이 파일은 네이티브 빌드 프로세스의 주요 부분을 정의하고 다음을 가져옵니다.

    • $(VCTargetsPath)\Microsoft.CppBuild.targets

    • $(VCTargetsPath)\Microsoft.BuildSteps.targets

    • $(MSBuildToolsPath)\Microsoft.Common.Targets

  • $(VCTargetsPath)\Microsoft.Cpp.Common.props

    Microsoft 컴파일러 및 대상 Windows를 사용하는 도구 세트의 기본값을 설정합니다.

  • $(VCTargetsPath)\Microsoft.Cpp.WindowsSDK.props

    이 파일은 Windows SDK 위치를 결정하고 Windows를 대상으로 하는 앱에 대한 중요한 속성을 정의합니다.

도구 세트별 대상을 기본 C++ 빌드 프로세스와 통합

기본 C++ 빌드 프로세스는 Microsoft.CppCommon.targets에 정의되어 있습니다. 대상은 특정 빌드 도구를 호출하지 않습니다. 기본 빌드 단계, 순서, 종속성을 지정합니다.

C++ 빌드에는 다음 대상으로 표시되는 세 가지 주요 단계가 있습니다.

  • BuildGenerateSources

  • BuildCompile

  • BuildLink

각 빌드 단계는 독립적으로 실행될 수 있으므로 한 단계에서 실행되는 대상은 다른 단계의 일부로 실행되는 대상에 정의된 항목 그룹 및 속성을 사용할 수 없습니다. 이 부분에서는 특정 빌드 성능 최적화를 허용합니다. 기본적으로 사용되지는 않지만 이러한 분리를 인정하는 것이 좋습니다.

각 단계 내에서 실행되는 대상은 다음 속성으로 제어됩니다.

  • $(BuildGenerateSourcesTargets)

  • $(BuildCompileTargets)

  • $(BeforeBuildLinkTargets)

각 단계에는 Before 속성 및 After 속성도 있습니다.

<Target
  Name="_BuildGenerateSourcesAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildGenerateSourcesTargets);$(BuildGenerateSourcesTargets);$(AfterBuildGenerateSourcesTargets)" />

<Target
  Name="\_BuildCompileAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildCompileTargets);$(BuildCompileTargets);$(AfterBuildCompileTargets)" />

<Target
  Name="\_BuildLinkAction"
  DependsOnTargets="$(CommonBuildOnlyTargets);$(BeforeBuildLinkTargets);$(BuildLinkTargets);$(AfterBuildLinkTargets)" />

각 단계에 포함된 대상의 예는 Microsoft.CppBuild.targets 파일을 참조하세요.

<BuildCompileTargets Condition="'$(ConfigurationType)'\!='Utility'">
  $(BuildCompileTargets);
  _ClCompile;
  _ResGen;
  _ResourceCompile;
  $(BuildLibTargets);
</BuildCompileTargets>

대상(예: _ClCompile)을 살펴보면 직접 실시하는 작업은 전혀 없고 다른 대상(예: ClCompile)에 따라 달라집니다.

<Target Name="_ClCompile"
  DependsOnTargets="$(BeforeClCompileTargets);$(ComputeCompileInputsTargets);MakeDirsForCl;ClCompile;$(AfterClCompileTargets)" >
</Target>

ClCompile 및 기타 빌드 도구 관련 대상은 다음과 같이 Microsoft.CppBuild.targets에서 빈 대상으로 정의됩니다.

<Target Name="ClCompile"/>

ClCompile 대상은 비어 있으므로 도구 세트에 의해 재정의되지 않는 한 실제 빌드 작업이 수행되지 않습니다. 도구 세트 대상은 ClCompile 대상을 재정의할 수 있습니다. 즉, ClCompileMicrosoft.CppBuild.targets를 가져온 후 다른 정의를 포함할 수 있습니다.

<Target Name="ClCompile"
  Condition="'@(ClCompile)' != ''"
  DependsOnTargets="SelectClCompile">
  <!-- call some MSBuild tasks -->
</Target>

Visual Studio가 플랫폼 간 지원을 구현하기 전에 만들어진 ClCompile 대상은 이름과는 달리 CL.exe를 호출할 필요가 없습니다. 적절한 MSBuild 작업을 사용하여 Clang, gcc 또는 기타 컴파일러를 호출할 수도 있습니다.

ClCompile 대상에는 종속성이 전혀 없어야 합니다(단일 파일 컴파일 명령이 IDE에서 작동하는 데 필요한 SelectClCompile 대상은 제외).

도구 세트 대상에 사용할 MSBuild 작업

실제 빌드 도구를 호출하려면 대상이 MSBuild 작업을 호출해야 합니다. 실행할 명령줄을 지정할 수 있는 기본 Exec 작업이 있습니다. 그러나 일반적으로 빌드 도구에는 증분 빌드를 추적하기 위한 옵션과 입력, 출력이 많으므로 특수한 작업을 수행하는 것이 더 적합합니다. 예를 들어 CL 태스크는 MSBuild 속성을 CL.exe 스위치로 변환하고, 이를 지시 파일에 쓰고, CL.exe를 호출합니다. 또한 이후 증분 빌드에 대한 모든 입력 파일 및 출력 파일을 추적합니다. 자세한 내용은 증분 빌드 및 최신 검사를 참조하세요.

Microsoft.Cpp.Common.Tasks.dll은 다음 작업을 구현합니다.

  • BSCMake

  • CL

  • ClangCompile (clang-gcc 스위치)

  • LIB

  • LINK

  • MIDL

  • Mt

  • RC

  • XDCMake

  • CustomBuild(예: Exec이지만 입력 및 출력 추적 포함)

  • SetEnv

  • GetOutOfDateItems

기존 도구와 동일한 작업을 수행하는 도구가 있고 명령줄 스위치가 비슷한 경우(clang-cl 및 CL과 마찬가지로) 두 도구 모두에 대해 동일한 작업을 사용할 수 있습니다.

빌드 도구에 대한 새 작업을 만들어야 하는 경우 다음 옵션 중에서 선택할 수 있습니다.

  1. 이 작업을 거의 사용하지 않거나 빌드에 몇 초가 문제되지 않는 경우 MSBuild '인라인' 작업을 사용할 수 있습니다.

    • Xaml 작업(사용자 지정 빌드 규칙)

      Xaml 작업 선언의 한 가지 예는 $(VCTargetsPath)\BuildCustomizations\masm.xml을 참조하고 해당 사용에 대해서는 $(VCTargetsPath)\BuildCustomizations\masm.targets를 참조하세요.

    • 코드 작업

  2. 작업 성능을 개선하려 한다거나 더 복잡한 기능이 필요한 경우 일반 MSBuild 작업 작성 프로세스를 사용합니다.

    도구의 모든 입력 및 출력이 CL 사례, MIDL 사례, RC 사례와 같이 도구 명령줄에 나열되지 않는 경우, 그리고 자동 입력 및 출력 파일 추적 및 .tlog 파일 생성을 원하는 경우 Microsoft.Build.CPPTasks.TrackedVCToolTask 클래스에서 작업을 파생합니다. 현재 기본 ToolTask 클래스에 대한 설명서가 있지만 TrackedVCToolTask 클래스의 세부 정보에 대한 예제나 설명서는 없습니다. 특히 관심이 있는 경우 Developer Community 요청에 자신의 의견을 작성합니다.

증분 빌드 및 최신 검사

기본 MSBuild 증분 빌드 대상은 Inputs 특성 및 Outputs 특성을 사용합니다. 이를 지정하는 경우 MSBuild는 모든 출력보다 더 최신인 타임스탬프가 입력에 있는 경우에만 대상을 호출합니다. 원본 파일은 종종 다른 파일을 포함하거나 가져오며 빌드 도구는 도구 옵션에 따라 다른 출력을 생성하기 때문에 MSBuild 대상에서 가능한 모든 입력 및 출력을 지정하기가 어렵습니다.

이 문제를 관리하기 위해 C++ 빌드는 다른 기술을 사용하여 증분 빌드를 지원합니다. 대부분의 대상은 입력 및 출력을 지정하지 않으므로 빌드 중에 항상 실행됩니다. 대상에서 호출하는 작업은 모든 입력 및 출력에 대한 정보를 확장명이 .tlog인 tlog 파일에 씁니다. .tlog 파일은 이후 빌드에서 변경된 내용과 다시 작성해야 하는 항목 및 최신 항목을 확인하는 데 사용됩니다. 또한 .tlog 파일은 IDE에서 기본 빌드 최신 검사를 위한 원본으로서는 유일합니다.

모든 입력 및 출력을 확인하기 위해 네이티브 도구 작업은 MSBuild에서 제공하는 FileTracker 클래스 및 tracker.exe를 사용합니다.

Microsoft.Build.CPPTasks.Common.dll은 TrackedVCToolTask 공용 추상 기본 클래스를 정의합니다. 대부분의 네이티브 도구 작업은 이 클래스에서 파생됩니다.

Visual Studio 2017 업데이트 15.8부터 Microsoft.Cpp.Common.Tasks.dll 구현된 GetOutOfDateItems 작업을 사용하여 알려진 입력 및 출력이 있는 사용자 지정 대상에 대한 .tlog 파일을 생성할 수 있습니다. 또는 WriteLinesToFile 작업을 사용하여 해당 파일을 만들 수 있습니다. 예를 들어 $(VCTargetsPath)\BuildCustomizations\masm.targets_WriteMasmTlogs 대상을 참조하세요.

.tlog 파일

.tlog 파일에는 세 가지 유형(읽기, 쓰기, 명령줄)이 있습니다. .tlog 파일 읽기 및 쓰기는 증분 빌드 및 IDE의 최신 검사에서 사용됩니다. 명령줄 .tlog 파일은 증분 빌드에서만 사용됩니다.

MSBuild는 .tlog 파일을 읽고 쓸 수 있는 다음과 같은 도우미 클래스를 제공합니다.

FlatTrackingData 클래스를 사용하여 읽기 .tlog 파일 뿐 아니라 쓰기 .tlog에 모두 액세스하고 출력보다 최신인 입력 또는 출력이 누락된 경우를 식별할 수 있습니다. 최신 검사에 사용됩니다.

명령줄 .tlog 파일에는 빌드에 사용되는 명령줄에 대한 정보가 포함되어 있습니다. 최신 검사가 아닌 증분 빌드에만 사용되므로 내부 형식은 이를 생성하는 MSBuild 작업에 의해 결정됩니다.

.tlog 형식 읽기

읽기 .tlog 파일(*.read.*.tlog)에는 원본 파일 및 해당 종속성에 대한 정보가 포함되어 있습니다.

줄의 시작 부분에 있는 caret(^)은 하나 이상의 원본을 나타냅니다. 동일한 종속성을 공유하는 원본은 세로 막대(|)로 구분됩니다.

종속성 파일은 각각 자체 줄에 있는 원본 다음에 나열됩니다. 모든 파일 이름은 전체 경로입니다.

예를 들어 프로젝트 원본이 F:\test\ConsoleApplication1\ConsoleApplication1에 있다고 가정합니다. 원본 파일인 Class1.cpp에 다음 항목이 포함된 경우

#include "stdafx.h" //precompiled header
#include "Class1.h"

CL.read.1.tlog 파일에는 소스 파일 뒤에 두 종속성이 포함됩니다.

^F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\CLASS1.CPP
F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.PCH
F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\CLASS1.H

파일 이름을 대문자로 작성할 필요는 없지만 그렇게 하면 일부 도구를 사용하기 편리합니다.

.tlog 형식 작성

.tlog(*.write.*.tlog) 파일을 작성하여 원본과 출력을 연결합니다.

줄의 시작 부분에 있는 caret(^)은 하나 이상의 원본을 나타냅니다. 여러 원본은 세로 막대(|)로 구분됩니다.

원본에서 빌드된 출력 파일은 각각 자체 줄에서 원본 뒤 나열되어야 합니다. 모든 파일 이름은 전체 경로여야 합니다.

예를 들어 추가 소스 파일인 Class1.cpp가 있는 간단한 ConsoleApplication 프로젝트의 경우 link.write.1.tlog 파일에 다음이 포함될 수 있습니다.

^F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CLASS1.OBJ|F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.OBJ|F:\TEST\CONSOLEAPPLICATION1\CONSOLEAPPLICATION1\DEBUG\STDAFX.OBJ
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.ILK
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.EXE
F:\TEST\CONSOLEAPPLICATION1\DEBUG\CONSOLEAPPLICATION1.PDB

디자인 타임 빌드

IDE에서 .vcxproj 프로젝트는 MSBuild 대상 집합을 사용하여 프로젝트에서 추가 정보를 얻고 출력 파일을 다시 생성합니다. 이러한 대상 중 일부는 디자인 타임 빌드에서만 사용되지만, 그 중 상당수는 일반 빌드와 디자인 타임 빌드 모두에서 사용됩니다.

디자인 타임 빌드에 대한 일반적인 내용은 디자인 타임 빌드에 대한 CPS 설명서를 참조하세요. 이 설명서는 Visual C++ 프로젝트에 부분적으로만 적용됩니다.

디자인 타임 빌드 설명서에 언급된 CompileDesignTime 대상 및 Compile 대상은 .vcxproj 프로젝트에 대해 실행되지 않습니다. Visual C++ .vcxproj 프로젝트는 다양한 디자인 타임 대상을 사용하여 IntelliSense 정보를 가져옵니다.

IntelliSense 정보에 대한 디자인 타임 대상

.vcxproj 프로젝트에 사용되는 디자인 타임 대상은 $(VCTargetsPath)\Microsoft.Cpp.DesignTime.targets에 정의되어 있습니다.

GetClCommandLines 대상은 IntelliSense에 대한 컴파일러 옵션을 수집합니다.

<Target
  Name="GetClCommandLines"
  Returns="@(ClCommandLines)"
  DependsOnTargets="$(DesignTimeBuildInitTargets);$(ComputeCompileInputsTargets)">
  • DesignTimeBuildInitTargets – 디자인 타임 빌드 초기화에 필요한 디자인 타임 전용 대상입니다. 무엇보다도 이러한 대상은 성능을 향상시키기 위해 일반 빌드 기능 중 일부를 사용하지 않도록 설정합니다.

  • ComputeCompileInputsTargets – 컴파일러 옵션 및 항목을 수정하는 대상 집합입니다. 이러한 대상은 디자인 타임 빌드 뿐 아니라 일반 빌드에서 실행됩니다.

대상은 CLCommandLine 작업을 호출하여 IntelliSense에 사용할 명령줄을 만듭니다. 이름과는 달리 CL 옵션뿐만 아니라 Clang 옵션 및 gcc 옵션도 처리할 수 있습니다. 컴파일러 스위치의 형식은 ClangMode 속성에 의해 제어됩니다.

현재 CLCommandLine 작업에서 생성된 명령줄은 IntelliSense 엔진이 구문 분석하기 쉽기 때문에 항상 CL 스위치(Clang 모드에서도)를 사용합니다.

평소 뿐 아니라 디자인 타임에도 컴파일 전에 실행되는 대상을 추가하는 경우 디자인 타임 빌드를 중단하거나 성능에 영향을 주지 않는지 확인합니다. 대상을 테스트하는 가장 간단한 방법은 개발자 명령 프롬프트를 열고 다음 명령을 실행하는 것입니다.

msbuild /p:SolutionDir=*solution-directory-with-trailing-backslash*;Configuration=Debug;Platform=Win32;BuildingInsideVisualStudio=true;DesignTimebuild=true /t:\_PerfIntellisenseInfo /v:d /fl /fileloggerparameters:PerformanceSummary \*.vcxproj

이 명령은 마지막에 대상 및 작업에 대한 성능 요약이 포함된 자세한 빌드 로그인 msbuild.log를 생성합니다.

디자인 타임 빌드가 아닌 일반 빌드에만 적합한 모든 작업에서 Condition ="'$(DesignTimeBuild)' != 'true'"를 사용해야 합니다.

원본을 생성하는 디자인 타임 대상

이 기능은 데스크톱 네이티브 프로젝트에 대해 기본적으로 사용하지 않도록 설정되며 현재 캐시된 프로젝트에서 지원되지 않습니다.

프로젝트 항목에 대해 GeneratorTarget 메타데이터가 정의되면 프로젝트가 로드될 때와 원본 파일이 변경될 때 대상이 자동으로 실행됩니다.

예를 들어 .xaml 파일에서 .cpp 또는 .h 파일을 자동 생성하기 위해 $(VSInstallDir)\MSBuild\Microsoft\WindowsXaml\v16.0\*\Microsoft.Windows.UI.Xaml.CPP.Targets 파일은 다음 엔터티를 정의합니다.

<ItemDefinitionGroup>
  <Page>
    <GeneratorTarget>DesignTimeMarkupCompilation</GeneratorTarget>
  </Page>
  <ApplicationDefinition>
    <GeneratorTarget>DesignTimeMarkupCompilation</GeneratorTarget>
  </ApplicationDefinition>
</ItemDefinitionGroup>
<Target Name="DesignTimeMarkupCompilation">
  <!-- BuildingProject is used in Managed builds (always true in Native) -->
  <!-- DesignTimeBuild is used in Native builds (always false in Managed) -->
  <CallTarget Condition="'$(BuildingProject)' != 'true' Or $(DesignTimeBuild) == 'true'" Targets="DesignTimeMarkupCompilationCT" />
</Target>

원본 파일의 저장되지 않은 콘텐츠를 가져오는 데 Task.HostObject를 사용하려면 대상 및 태스크를 pkgdef의 지정된 프로젝트에 대한 MsbuildHostObjects 로 등록해야 합니다.

\[$RootKey$\\Projects\\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\\MSBuildHostObjects\]
\[$RootKey$\\Projects\\{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\\MSBuildHostObjects\\DesignTimeMarkupCompilationCT;CompileXaml\]
@="{83046B3F-8984-444B-A5D2-8029DEE2DB70}"

Visual Studio IDE의 Visual C++ 프로젝트 확장성

Visual C++ 프로젝트 시스템은 VS Project System을 기반으로 하며 확장 지점을 사용합니다. 그러나 프로젝트 계층 구조 구현은 CPS를 기반으로 하지 않고 Visual C++에만 적용되므로 계층 확장성은 프로젝트 항목으로 제한됩니다.

프로젝트 속성 페이지

일반 디자인 정보는 VC++ 프로젝트에 대한 프레임워크 멀티 타기팅을 참조하세요.

간단히 말하면 C++ 프로젝트의 프로젝트 속성 대화 상자에 표시되는 속성 페이지는 규칙 파일에 의해 정의됩니다. 규칙 파일은 속성 페이지에 표시할 속성 집합과 프로젝트 파일에 저장할 방법 및 위치를 지정합니다. 규칙 파일은 Xaml 형식을 사용하는 .xml 파일입니다. 직렬화하는 데 사용되는 형식은 Microsoft.Build.Framework.XamlTypes에 설명되어 있습니다. 프로젝트에서 규칙 파일을 사용하는 방법에 대한 자세한 내용은 속성 페이지 XML 규칙 파일을 참조하세요.

규칙 파일을 PropertyPageSchema 항목 그룹에 추가해야 합니다.

<ItemGroup>
  <PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\general.xml;"/>
  <PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\general_file.xml">
    <Context>File</Context>
  </PropertyPageSchema>
</ItemGroup>

Context 메타데이터는 규칙 유형에 의해 제어되며 다음 값 중 하나를 가질 수 있는 규칙 표시 유형을 제한합니다.

Project | File | PropertySheet

CPS는 컨텍스트 형식에 대해 다른 값을 지원하지만 Visual C++ 프로젝트에서는 사용되지 않습니다.

규칙이 둘 이상의 컨텍스트에 표시되어야 하는 경우 다음과 같이 세미콜론(;)을 사용하여 컨텍스트 값을 구분합니다.

<PropertyPageSchema Include="$(MyFolder)\MyRule.xml">
  <Context>Project;PropertySheet</Context>
</PropertyPageSchema>

규칙 형식 및 기본 형식

규칙 형식은 간단하므로 이 섹션에서는 사용자 인터페이스에서 규칙의 모양에 영향을 주는 특성만 설명합니다.

<Rule
  Name="ConfigurationGeneral"
  DisplayName="General"
  PageTemplate="generic"
  Description="General"
  xmlns="http://schemas.microsoft.com/build/2009/properties">

PageTemplate 특성은 속성 페이지 대화 상자에 규칙이 표시되는 방식을 정의합니다. 특성은 다음 값 중 하나를 포함할 수 있습니다.

attribute 설명
generic 모든 속성은 한 페이지의 범주 제목 아래의 표시됩니다.
규칙은 ProjectPropertySheet 컨텍스트에 대해 볼 수 있지만 File에 대해서는 볼 수 없습니다.

예: $(VCTargetsPath)\1033\general.xml
tool 범주는 하위 페이지로 표시됩니다.
규칙은 모든 컨텍스트, 즉 ProjectPropertySheetFile에서 볼 수 있습니다.
규칙은 규칙 이름이 ProjectTools 항목 그룹에 포함되지 않는 한 Rule.DataSource에 정의된 ItemType이 포함된 항목이 프로젝트에 있는 경우에만 프로젝트 속성에 표시됩니다.

예: $(VCTargetsPath)\1033\clang.xml
debugger 페이지는 디버깅 페이지의 일부로 표시됩니다.
범주는 현재 무시됩니다.
규칙 이름은 디버그 시작 관리자 MEF 개체의 ExportDebugger 특성과 일치해야 합니다.

예: $(VCTargetsPath)\1033\debugger_local_windows.xml
custom 사용자 지정 템플릿. 템플릿 이름은 PropertyPageUIFactoryProvider MEF 개체의 ExportPropertyPageUIFactoryProvider 특성과 일치해야 합니다. Microsoft.VisualStudio.ProjectSystem.Designers.Properties.IPropertyPageUIFactoryProvider를 참조하세요.

예: $(VCTargetsPath)\1033\userMacros.xml

규칙이 Property Grid 기반 템플릿 중 하나를 사용하는 경우 해당 속성에 대해 다음과 같은 확장 지점을 사용할 수 있습니다.

규칙 확장

기존 규칙을 사용하지만 몇 가지 속성만 추가하거나 제거해야 하는 경우 확장 규칙을 만들 수 있습니다.

규칙 재정의

도구 세트에서 대부분의 프로젝트 기본 규칙을 사용하지만 그 중 하나 또는 몇 개만 바꾸려 할 수 있습니다. 예를 들어 C/C++ 규칙을 변경하여 다른 컴파일러 스위치를 표시하려 합니다. 기존 규칙과 이름 및 표시 이름이 같은 새 규칙을 제공하고 기본 cpp 대상을 가져온 후 이를 PropertyPageSchema 항목 그룹에 포함할 수 있습니다. 이름이 지정된 규칙 하나만 프로젝트에 사용되고 PropertyPageSchema 항목 그룹에 포함된 마지막 규칙이 우선합니다.

프로젝트 항목

ProjectItemsSchema.xml 파일은 프로젝트 항목으로 처리되는 항목의 ContentType 값과 ItemType 값을 정의하고 새 파일이 추가되는 항목 그룹을 결정하는 FileExtension 요소를 정의합니다.

기본 ProjectItemsSchema 파일은 $(VCTargetsPath)\1033\ProjectItemsSchema.xml에 있습니다. 확장하려면 MyProjectItemsSchema.xml 같은 새 이름으로 스키마 파일을 만들어야 합니다.

<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">

  <ItemType Name="MyItemType" DisplayName="C/C++ compiler"/>

  <ContentType
    Name="MyItems"
    DisplayName="My items"
    ItemType=" MyItemType ">
  </ContentType>

  <FileExtension Name=".abc" ContentType=" MyItems"/>

</ProjectSchemaDefinitions>

그런 다음 대상 파일에서 다음을 추가합니다.

<ItemGroup>
  <PropertyPageSchema Include="MyProjectItemsSchema.xml"/>
</ItemGroup>

예: $(VCTargetsPath)\BuildCustomizations\masm.xml

디버거

Visual Studio의 디버그 서비스는 디버그 엔진에 대한 확장성을 지원합니다. 자세한 내용은 다음 샘플을 참조하세요.

디버그 세션에 대한 디버그 엔진 및 기타 속성을 지정하려면 디버그 시작 관리자 MEF 구성 요소를 구현하고 debugger 규칙을 추가해야 합니다. 예제는 $(VCTargetsPath)\1033\debugger_local_windows.xml 파일을 참조하세요.

배포

.vcxproj 프로젝트는 배포 공급자에 Visual Studio 프로젝트 시스템 확장성을 사용합니다.

빌드 최신 검사

기본적으로 빌드 최신 검사를 사용하려면 모든 빌드 입력 및 출력에 대해 빌드하는 동안 $(TlogLocation) 폴더에 .tlog 파일 및 쓰기 .tlog 파일을 만들어야 합니다.

사용자 지정 최신 검사를 사용하려면 다음을 수행합니다.

  1. Toolset.targets 파일에 NoVCDefaultBuildUpToDateCheckProvider 기능을 추가하여 기본 최신 검사를 사용하지 않도록 설정합니다.

    <ItemGroup>
      <ProjectCapability Include="NoVCDefaultBuildUpToDateCheckProvider" />
    </ItemGroup>
    
  2. 고유한 IBuildUpToDateCheckProvider를 구현합니다.

프로젝트 업그레이드

기본 .vcxproj 프로젝트 업그레이드 프로그램

기본 .vcxproj 프로젝트 업그레이드 프로그램은 PlatformToolset, ApplicationTypeRevision, MSBuild 도구 집합 버전 및 .NET Framework를 변경합니다. 마지막 두 가지는 항상 Visual Studio 버전 기본값으로 변경되지만 PlatformToolsetApplicationTypeRevision은 특수 MSBuild 속성으로 컨트롤할 수 있습니다.

업그레이드 프로그램은 다음 조건을 사용하여 프로젝트를 업그레이드할 수 있는지 여부를 결정합니다.

  1. ApplicationTypeApplicationTypeRevision을 정의하는 프로젝트에는 현재 수정 번호보다 높은 수정 번호가 있는 폴더가 있습니다.

  2. _UpgradePlatformToolsetFor_<safe_toolset_name> 속성은 현재 도구 세트에 대해 정의되며 해당 값은 현재 도구 세트과 같지 않습니다.

    이러한 속성 이름에서 < safe_toolset_name>은 밑줄(_)로 대체된 영숫자가 아닌 문자 전체가 있는 도구 세트 이름을 나타냅니다.

업그레이드 가능한 프로젝트는 솔루션 대상 다시 지정에 참여합니다. 자세한 내용은 IVsTrackProjectRetargeting2를 참조하세요.

프로젝트에서 특정 도구 세트를 사용할 때 솔루션 탐색기에서 프로젝트 이름을 표시하려면 _PlatformToolsetShortNameFor_<safe_toolset_name> 속성을 정의합니다.

_UpgradePlatformToolsetFor_<safe_toolset_name> 속성 정의 및 _PlatformToolsetShortNameFor_<safe_toolset_name> 속성 정의 예제는 Microsoft.Cpp.Default.props 파일을 참조하세요. 사용 예제는 $(VCTargetPath)\Microsoft.Cpp.Platform.targets 파일을 참조하세요.

사용자 지정 프로젝트 업그레이드 프로그램

사용자 지정 프로젝트 업그레이드 프로그램 개체를 사용하려면 다음과 같이 MEF 구성 요소를 구현합니다.

/// </summary>
[Export("MyProjectUpgrader", typeof(IProjectRetargetHandler))]
[Export(typeof(IProjectRetargetHandler))]
[ExportMetadata("Name", "MyProjectUpgrader")]
[OrderPrecedence(20)]
[PartMetadata(ProjectCapabilities.Requires, ProjectCapabilities.VisualC)]

internal class MyProjectUpgrader: IProjectRetargetHandler
{
    // ...
}

코드는 기본 .vcxproj 업그레이드 프로그램 개체를 가져오고 호출할 수 있습니다.

// ...
[Import("VCDefaultProjectUpgrader")]
// ...
    IProjectRetargetHandler Lazy<IProjectRetargetHandler>
    VCDefaultProjectUpgrader { get; set; }
// ...

IProjectRetargetHandlerMicrosoft.VisualStudio.ProjectSystem.VS.dll에서 정의되며 IVsRetargetProjectAsync와 비슷합니다.

사용자 지정 업그레이드 프로그램 개체를 사용하려면 프로젝트 시스템에 지시하는 VCProjectUpgraderObjectName 속성을 정의합니다.

<PropertyGroup>
  <VCProjectUpgraderObjectName>MyProjectUpgrader</VCProjectUpgraderObjectName>
</PropertyGroup>

프로젝트 업그레이드 사용 안 함

프로젝트 업그레이드를 사용하지 않도록 설정하려면 NoUpgrade 값을 사용합니다.

<PropertyGroup>
  <VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
</PropertyGroup>

프로젝트 캐시 및 확장성

Visual Studio 2017에서 대형 C++ 솔루션으로 작업할 때 성능을 향상시키고자 프로젝트 캐시가 도입되었습니다. 이는 프로젝트 데이터로 채워진 SQLite 데이터베이스로 구현된 다음 MSBuild 프로젝트 또는 CPS 프로젝트를 메모리에 로드하지 않고 프로젝트를 로드하는 데 사용됩니다.

캐시에서 로드된 .vcxproj 프로젝트에 대한 CPS 개체가 없으므로 UnconfiguredProject 또는 ConfiguredProject를 가져오는 확장의 MEF 구성 요소를 만들 수 없습니다. 확장성을 지원하기 위해 Visual Studio에서 프로젝트가 MEF 확장을 사용하거나 사용할 가능성이 있는지를 감지할 때 프로젝트 캐시가 사용되지 않습니다.

이러한 프로젝트 형식은 항상 완전히 로드되고 메모리에 CPS 개체가 있으므로 다음과 같이 모든 MEF 확장이 이를 위해 만들어집니다.

  • 시작 프로젝트

  • 사용자 지정 프로젝트 업그레이드 프로그램이 있는 프로젝트, 즉 VCProjectUpgraderObjectName 속성을 정의하는 프로젝트

  • 데스크톱 Windows를 대상으로 하지 않는, 즉 ApplicationType 속성을 정의하는 프로젝트

  • 공유 항목 프로젝트(.vcxitems) 및 .vcxitems 프로젝트를 가져와서 참조하는 모든 프로젝트.

이러한 조건이 검색되지 않으면 프로젝트 캐시가 만들어집니다. 캐시에는 VCProjectEngine 인터페이스의 get 쿼리에 응답하는 데 필요한 MSBuild 프로젝트의 데이터 전체가 포함됩니다. 즉, 확장에서 수행된 MSBuild props 및 대상 파일 수준의 수정은 모두 캐시에서 로드된 프로젝트에서만 작동합니다.

확장 전달

VSIX 파일을 만드는 방법에 대한 자세한 내용은 Visual Studio 확장 전달을 참조하세요. 특수 설치 위치에 파일을 추가하는 방법(예: $(VCTargetsPath) 아래에 파일을 추가하는 방법)에 대한 자세한 내용은 확장 폴더 외부에 설치를 참조하세요.

추가 자료

MSBuild(Microsoft Build System)는 프로젝트 파일에 대한 빌드 엔진 및 확장 가능한 XML 기반 형식을 제공합니다. Visual C++ 프로젝트 시스템을 확장하려면 기본 MSBuild 개념Visual C++용 MSBuild의 작동 방식에 대해 잘 알아야 합니다.

MEF(Managed Extensibility Framework)는 CPS 및 Visual C++ 프로젝트 시스템에서 사용하는 확장 API를 제공합니다. CPS에서 MEF를 사용하는 방법에 대한 개요는 MEF의 VSProjectSystem 개요에서 CPS 및 MEF를 확인하세요.

기존 빌드 시스템을 사용자 지정하여 빌드 단계 또는 새 파일 형식을 추가할 수 있습니다. 자세한 내용은 MSBuild(Visual C++) 개요프로젝트 속성 사용을 참조하세요.