2013-02-28 12 views
7

Sau đây được lấy từ dự án VS2010 C++ thông thường.Cách đặt PreProcessorDefinitions là một nhiệm vụ thích hợp cho tác vụ msbuild

<ClCompile> 
     <WarningLevel>Level3</WarningLevel> 
     <PrecompiledHeader>Use</PrecompiledHeader> 
     <Optimization>MaxSpeed</Optimization> 
     <FunctionLevelLinking>true</FunctionLevelLinking> 
     <IntrinsicFunctions>true</IntrinsicFunctions> 
     <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> 
    </ClCompile> 

Nếu tôi chỉnh sửa PreprocessorDefinitions tôi có thể đặt định nghĩa được sử dụng bởi bộ tiền xử lý. Tôi có thể thấy điều này trong mã của tôi qua #ifdef, vv

Tuy nhiên nếu tôi sử dụng như sau

<Target Name="NormalBuild" Condition=" '$(_InvalidConfigurationWarning)' != 'true' " DependsOnTargets="_DetermineManagedStateFromCL;CustomBeforeBuild;$(BuildDependsOn)" Returns="@(ManagedTargetPath)"> 
    <ItemGroup> 
     <ManagedTargetPath Include="$(TargetPath)" Condition="'$(ManagedAssembly)' == 'true'" /> 
    </ItemGroup> 
     <Message Text="PreprocessorDefinitions: $(PreprocessorDefinitions)" Importance="High" /> 
    </Target> 

    <Target Name="TestBuild" Returns="@(ManagedTargetPath)"> 
    <MSBuild Projects="demo.vcxproj" Targets="NormalBuild" Properties="PreprocessorDefinitions=THISGETSSETBUTDOESNOTHING"/> 
    </Target> 

tôi cũng có thể thấy qua thông điệp rằng PreprocessorDefinitions chứa giá trị tôi đặt qua Properties="PreprocessorDefinitions=THISGETSSETBUTDOESNOTHING" nhưng tôi không thể kiểm soát của tôi xây dựng sử dụng #ifdef, vv Nếu tôi sử dụng một thiết lập thường xuyên và cố gắng ra PreprocessorDefinitions sử dụng <Message Text="PreprocessorDefinitions: $(PreprocessorDefinitions)" lĩnh vực này thực sự là trống và không chứa dự kiến ​​<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> mặc dù tôi có thể sử dụng bất kỳ một trong những chìa khóa để kiểm soát xây dựng của tôi sử dụng #ifdef, vv

  1. Tại sao lại như vậy?
  2. Tôi có thể làm gì để vượt qua PreprocessorDefinitions für dự án VS2010 C++ thông qua phần tử Properties nhiệm vụ?

Trả lời

6

Bạn không thể làm điều này mà không sửa đổi demo.vcxproj bởi vì bạn cần truy cập vào PreprocessorDefinitions của CLCompile, mà không phải là một PropertyGroup, và do đó không thể được truyền qua dòng lệnh MSBuild.

Bạn có thể sửa đổi các định nghĩa preprocessor trong GUI qua Project Properties -> Cấu hình Propertis -> C/C++ -> Preprocessor hoặc chỉnh sửa XML trực tiếp:

<ClCompile> 
    .... 
    <PreprocessorDefinitions>$(MyMacro);%(PreprocessorDefinitions)</PreprocessorDefinitions> 
    </ClCompile> 

Trong dự án MSBuild của bạn:

<Target Name="TestBuild" Returns="@(ManagedTargetPath)"> 
    <MSBuild Projects="demo.vcxproj" Targets="NormalBuild" Properties="MyMacro=THISGETSSETBUTDOESNOTHING"/> 
    </Target> 

này tương đương với chạy msbuild.exe như:

MSBuild demo.vcxproj /p:MyMacro=THISGETSSETBUTDOESNOTHING 
+0

Không có điều nào trong số này hoạt động trong phiên bản 2017 của tôi và tôi không có phần ClCompile. – Pysis

+0

Vẫn đang làm việc cho tôi. Nó là một dự án C++? –

+0

Tôi không làm việc trong thế giới này MSVC/VS thường .., thêm Eclipse. Tôi đã thêm một thư mục mới và một tệp cpp trống, nhưng giống như một Đường dẫn Xây dựng, tôi không nghĩ rằng nó đã được nhận diện, và/hoặc khía cạnh C++ 'không nằm trong tệp dự án' tổng hợp '. Một khi tôi nhận ra các lỗi trong các tệp vcxproj tiểu dự án xác định các báo cáo tiền xử lý riêng của chúng đã gây ra lũ lụt của các lỗi xkeycheck xuất hiện, tôi thấy mỗi dự án đó là các chỉnh sửa .. Mặc dù! – Pysis

30

Điều này có thể được thực hiện mà không cần sửa đổi dự án gốc: điều đầu tiên được thực hiện trong Microsoft.Cpp.Targets, thường là một trong những điều cuối cùng được nhập trong một dự án C++ bình thường, để kiểm tra xem có thuộc tính được gọi là ForceImportBeforeCppTargets không.

Vì vậy, giả sử bạn muốn thêm ADDITIONAL các định nghĩa preprocessor bạn tạo một file 'override.props' như thế này (cho tự động hóa hoàn toàn sử dụng nhiệm vụ WritelinesToFile để tạo ra các tập tin):

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <ItemDefinitionGroup> 
    <ClCompile> 
     <PreprocessorDefinitions>%(PreprocessorDefinitions);ADDITIONAL</PreprocessorDefinitions> 
    </ClCompile> 
    </ItemDefinitionGroup> 

</Project> 

Và gọi

<MSBuild Projects="demo.vcxproj" 
     Properties="ForceImportBeforeCppTargets=override.props"/> 

hoặc từ dòng lệnh đó sẽ là

msbuild demo.vcxproj /p:ForceImportBeforeCppTargets=override.props 

Lưu ý là điểm richb trong nhận xét, ở trên chỉ hoạt động nếu override.props có thể được tìm thấy bởi các quy tắc tra cứu của msbuild. Để đảm bảo nó luôn được tìm thấy, chỉ cần xác định đường dẫn đầy đủ.

+6

Cảm ơn thông tin này rất hữu ích. Chỉ cần một vài sửa chữa. Đầu tiên, tham số dòng lệnh là/p: not/t :. Thứ hai, bạn cần phải xác định đường dẫn đầy đủ để override.props nếu không msbuild bỏ qua nó mà không có bất kỳ cảnh báo nào. – richb

+0

@richb bắt được, chỉnh sửa. – stijn

+2

Tôi chỉ muốn nhấn mạnh đường dẫn đầy đủ đề cập đến @richb, mà tôi thấy là rất quan trọng trong việc thực hiện công việc này. Bằng cách xuất một phần , nó hoạt động với các định nghĩa trình biên dịch tài nguyên. – mj2008