59

Tôi luôn sử dụng Visual Studio được xây dựng trong giao diện hỗ trợ để định cấu hình dự án của mình, thường sử dụng trang thuộc tính để một số dự án sử dụng một bộ chung.Sử dụng thuộc tính dự án Visual Studio hiệu quả cho nhiều dự án và cấu hình

Một trong những ứng dụng chính của tôi là quản lý nhiều dự án, cấu hình và nền tảng. Nếu bạn chỉ làm mọi thứ với GUI chính (nhấn chuột phải vào project -> properties) nó nhanh chóng trở thành một mớ hỗn độn, khó duy trì và dễ bị lỗi (như không định nghĩa chính xác một số macro, hoặc sử dụng thư viện runtime sai, vv). Đối phó với thực tế là những người khác nhau đặt thư viện phụ thuộc vào những nơi khác nhau (ví dụ: tất cả tôi sống trong "C: \ Libs \ [C, C++] \ [lib-name] \") và sau đó thường quản lý các phiên bản khác nhau của các thư viện đó khác nhau (release, debug, x86, x64, etc) cũng là một vấn đề lớn vì nó làm phức tạp thời gian để thiết lập nó trên một hệ thống mới, và sau đó có vấn đề với việc kiểm soát phiên bản và giữ đường dẫn của mọi người riêng biệt ..

Các trang thuộc tính làm cho nó tốt hơn một chút, nhưng tôi không thể có một trang có cài đặt riêng cho các cấu hình và nền tảng khác nhau (hộp thả xuống màu xám), dẫn đến việc tôi có nhiều trang tính nếu được kế thừa theo đúng thứ tự làm những gì tôi muốn ("x86", "x64", "gỡ lỗi", "phát hành", "phổ biến", "thư mục" (giao dịch với vấn đề phụ thuộc đã đề cập trước đây bằng cách xác định macro người dùng như BoostX86LibDir), v.v. d theo thứ tự sai (ví dụ "thông thường" trước "x64" và "gỡ rối") dẫn đến các sự cố như cố gắng liên kết phiên bản thư viện không chính xác hoặc đặt tên không chính xác ...

Điều tôi muốn là một cách xử lý tất cả các phụ thuộc phân tán này và thiết lập một bộ "quy tắc" được tất cả các dự án của tôi sử dụng trong giải pháp, như đặt tên thư viện đầu ra là "mylib- [vc90, vc100] - [x86, x64] [- d] .lib ", mà không phải thực hiện tất cả điều này cho từng dự án, cấu hình và nền tảng kết hợp riêng lẻ, và sau đó giữ chúng hoàn toàn đồng bộ.

Tôi biết chuyển sang các hệ thống hoàn toàn khác như CMake tạo các tệp cần thiết, tuy nhiên điều này làm phức tạp mọi thứ bằng cách làm cho nó trở nên đơn giản như thêm một tệp mới vào dự án. không phải cái gì tôi hoàn toàn hài lòng với một trong hai, trừ khi có một số với hội nhập VS2010 có thể theo dõi các loại thay đổi.

+1

Tôi cảm thấy đau của bạn: Chúng tôi có hơn 600 vcproj trong sản phẩm của chúng tôi tại nơi làm việc. :( –

Trả lời

67

Tôi chỉ phát hiện ra mọi thứ mà tôi không nghĩ là có thể (nó không được hiển thị bởi GUI) giúp làm cho trang thuộc tính hữu ích hơn nhiều. Thuộc tính "Điều kiện" của nhiều thẻ trong các tệp thuộc tính dự án và nó có thể được sử dụng trong các tệp .props!

Tôi chỉ kết hợp những điều sau đây như một bài kiểm tra và nó hoạt động tốt và đã thực hiện nhiệm vụ của 5 trang tính chung (x64, x86, gỡ lỗi, phát hành)!

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup Label="UserMacros"> 
    <!--debug suffix--> 
    <DebugSuffix Condition="'$(Configuration)'=='Debug'">-d</DebugSuffix> 
    <DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix> 
    <!--platform--> 
    <ShortPlatform Condition="'$(Platform)' == 'Win32'">x86</ShortPlatform> 
    <ShortPlatform Condition="'$(Platform)' == 'x64'">x64</ShortPlatform> 
    <!--toolset--> 
    <Toolset Condition="'$(PlatformToolset)' == 'v90'">vc90</Toolset> 
    <Toolset Condition="'$(PlatformToolset)' == 'v100'">vc100</Toolset> 
    </PropertyGroup> 
    <!--target--> 
    <PropertyGroup> 
    <TargetName>$(ProjectName)-$(Toolset)-$(ShortPlatform)$(DebugSuffix)</TargetName> 
    </PropertyGroup> 
</Project> 

Chỉ có thuộc tính GUI không thể xử lý nó, một dự án sử dụng bảng thuộc tính trên chỉ báo cáo giá trị kế thừa mặc định như "$ (ProjectName)" cho mục tiêu.

+0

Kỹ thuật tốt đẹp! – Mordachai

+0

+1 điều này rất giống với những gì tôi sử dụng – AJG85

+0

Vâng, các trang thuộc tính mạnh hơn rất nhiều trong VS2k10. Chỉ là một sự xấu hổ không ai trong số đó được tiếp xúc thông qua IDE. Tôi đã làm một cái gì đó tương tự và nó thực sự đơn giản hóa mọi thứ. – jalf

4

Theo như thư viện ra đi, bạn có thể chọn tất cả các dự án của bạn, sau đó đưa lên các trang bất động sản, chọn All Configurations, tất cả các nền tảng và sau đó đặt tên Target để:

$(ProjectName)-$(PlatformToolset)-$(PlatformShortName)-$(Configuration)

mà sẽ cung cấp đầu ra như mylib-v100-x86-Debug.lib

Chúng tôi cũng làm điều tương tự cho Thư viện Thư viện Bổ sung, sử dụng $(PlatformName)#(Configuration) để chọn đường dẫn thư viện phù hợp, mặc dù điều đó có nghĩa là với thiết lập ban đầu của li braries. ví dụ: chúng tôi đã tăng cài đặt libs của mình lên boost/lib.Win32 hoặc boost/lib.x64.


Đối với thư viện và những người cài đặt chúng ở những nơi khác nhau, có một vài tùy chọn. Nếu bạn có một hệ thống kiểm soát nguồn rất mạnh, bạn có thể đặt mọi thứ trong điều khiển nguồn, sống trong thư mục libs bên cạnh nguồn của bạn. Điều đó có thể sẽ không hoạt động nếu bạn sử dụng nhiều hơn một vài thư viện, hoặc nếu chúng đặc biệt lớn.Một tùy chọn khác mà bạn nghĩ đến là đặt một biến môi trường trên mỗi máy người dùng trỏ đến thư mục gốc của thư viện của họ, ví dụ: LIB_ROOT=c:\libraries và sau đó bạn có thể truy cập vào Visual Studio dưới dạng $(LIB_ROOT). Quay lại đầu trang

+0

Tôi đã thực hiện một số bit như thế này một chút, nhưng sau đó có thư viện sử dụng cái gì đó khác trong tên của họ (ví dụ như thay vì phát hành, -d thay vì -Debug) vv, vẫn yêu cầu nhiều quy tắc đặc biệt (debug.props của tôi và release.props thiết lập macro người dùng để giúp với điều này với common.props thực sự thiết lập các đường dẫn include/lib) .Không được coi là nó với boost, ý tưởng hay (thậm chí còn đẹp hơn nếu có liên kết tự động đi kèm _not_ sử dụng cùng tên cho x86 và x64 xây dựng nhưng những người boost.build dường như không nghĩ rằng một vấn đề của nó) –

+0

Tôi đoán PlatformShortName của bạn đến từ một x86.props và x64.props phải được thừa hưởng chính xác hoặc một cái gì đó hoặc là nó chỉ –

+0

@Fire Lancer: thành thật mà nói tôi không biết PlatformShortName đến từ đâu, tôi nghĩ nó phải là một built-in, bởi vì chúng tôi không có bất cứ điều gì đặc biệt trong các trang thuộc tính của chúng tôi – ngoozeff

7

Tôi đã có cùng một nỗi đau cho sản phẩm của công ty tôi (hơn 200 dự án) trước đây. Cách tôi giải quyết nó là xây dựng một hệ thống phân cấp tốt đẹp của các trang thuộc tính.

Các dự án kế thừa bảng thuộc tính theo kiểu đầu ra của nó, hãy nói x64.Debug.Dynamic.Library.vsprops. Đây vsprops tập tin chỉ đơn giản là được thừa hưởng tờ tài sản khác bằng cách sử dụng InheritedPropertySheets thuộc tính

<VisualStudioPropertySheet 
    ProjectType="Visual C++" 
    Version="8.00" 
    Name="x64.Debug.Dynamic.Binary" 
    InheritedPropertySheets=".\Common.vsprops;.\x64.vsprops;.\Debug.vsprops;.\Runtime.Debug.Dynamic.vsprops;.\Output.x64.Library.vsprops" 
    > 

Bạn cũng có thể sử dụng các biến (ví dụ UserMacro, mà giá trị có thể biến tuyệt đối hoặc thậm chí môi trường) trong tờ sở hữu để tùy chỉnh rất nhiều thứ dựa trên của bạn nhu cầu. Ví dụ, việc xác định một biến BIN trong Debug.vsprops

<UserMacro name="BIN" Value="Debug" /> 

sau đó khi bạn thiết lập tên đầu ra trong hàng loạt các vsprops, nói, Output.x64.Library.vsprops

<VisualStudioPropertySheet 
    ProjectType="Visual C++" 
    Version="8.00" 
    OutputDirectory="$(BIN)" 
> 

Các $ (BIN) sẽ được mở rộng đến những gì được thiết lập (trong trường hợp này là Debug). Sử dụng kỹ thuật này bạn có thể dễ dàng xây dựng một hệ thống phân cấp tốt đẹp của trang thuộc tính để đáp ứng nhu cầu của bạn.

Bây giờ có một điều nữa bạn có thể muốn làm: tạo mẫu dự án của riêng bạn sử dụng tập hợp trang thuộc tính của bạn. Phần khó thực sự là thực thi việc sử dụng thích hợp các mẫu và các trang thuộc tính. Kinh nghiệm cá nhân của tôi là ngay cả khi mọi thứ được thiết lập, ai đó vẫn sẽ quên sử dụng mẫu để tạo dự án mới ...

0

Có vẻ như nó đáng để kiểm tra công cụ xây dựng - tại vị trí của tôi, chúng tôi sử dụng tùy chỉnh làm công cụ để theo dõi các tập tin và dự án để thay đổi và tính toán các phụ thuộc và thứ tự biên dịch. Thêm một tập tin mới là không có vấn đề lớn - biên dịch được thực hiện với msbuild.

Nếu tôi đã phải biên dịch hơn một loạt các dự án Tôi sẽ sử dụng một cái gì đó giống như Nant: http://nant.sourceforge.net/

20

tôi đã thực hiện một số cải tiến, có thể hữu ích cho ai đó

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup Label="UserMacros"> 
    <!--IsDebug: search for 'Debug' in Configuration--> 
    <IsDebug>$([System.Convert]::ToString($([System.Text.RegularExpressions.Regex]::IsMatch($(Configuration), '[Dd]ebug'))))</IsDebug> 

    <!--ShortPlatform--> 
    <ShortPlatform Condition="'$(Platform)' == 'Win32'">x86</ShortPlatform> 
    <ShortPlatform Condition="'$(Platform)' == 'x64'">x64</ShortPlatform> 

    <!--build parameters--> 
    <BUILD_DIR>$(registry:HKEY_CURRENT_USER\Software\MyCompany\@BUILD_DIR)</BUILD_DIR> 
    </PropertyGroup> 

    <Choose> 
    <When Condition="$([System.Convert]::ToBoolean($(IsDebug)))"> 
     <!-- debug macroses --> 
     <PropertyGroup Label="UserMacros"> 
     <MyOutDirBase>Debug</MyOutDirBase> 
     <DebugSuffix>-d</DebugSuffix> 
     </PropertyGroup> 
    </When> 
    <Otherwise> 
     <!-- other/release macroses --> 
     <PropertyGroup Label="UserMacros"> 
     <MyOutDirBase>Release</MyOutDirBase> 
     <DebugSuffix></DebugSuffix> 
     </PropertyGroup> 
    </Otherwise> 
    </Choose> 

    <Choose> 
    <When Condition="Exists($(BUILD_DIR))"> 
     <PropertyGroup Label="UserMacros"> 
     <MyOutDir>$(BUILD_DIR)\Bin\$(MyOutDirBase)_$(ShortPlatform)\</MyOutDir> 
     <MyIntDir>$(BUILD_DIR)\Build\$(Configuration)_$(ShortPlatform)_$(PlatformToolset)\$(ProjectGuid)\</MyIntDir> 
     </PropertyGroup> 
    </When> 
    <Otherwise> 
     <PropertyGroup Label="UserMacros"> 
     <MyOutDir>$(SolutionDir)\Bin\$(MyOutDirBase)_$(ShortPlatform)\</MyOutDir> 
     <MyIntDir>$(SolutionDir)\Build\$(Configuration)_$(ShortPlatform)_$(PlatformToolset)\$(ProjectGuid)\</MyIntDir> 
     </PropertyGroup> 
    </Otherwise> 
    </Choose> 

    <PropertyGroup> 
    <OutDir>$(MyOutDir)</OutDir> 
    <IntDir>$(MyIntDir)</IntDir> 
<!-- some common for projects 
    <CharacterSet>Unicode</CharacterSet> 
    <LinkIncremental>false</LinkIncremental> 
--> 
    </PropertyGroup> 
</Project> 

vui chơi!

+2

Bạn đang ... điên rồ. Nhưng theo cách tốt :) –

+0

Khi nào điều này sẽ được đánh giá? Khi tải dự án? Tôi muốn thêm các quy tắc sao chép sau xây dựng tùy chỉnh vào một trang thuộc tính để chỉ sao chép các tệp DLL thực sự đã được liên kết với dự án. Bạn có nghĩ rằng điều này sẽ có thể? – Bim

+0

Bim, tôi nghĩ rằng nó được đánh giá trước khi xây dựng, vì nó đọc các biến từ registry (xem $ (registry: key)). – lunicon

4

Có thể tạo trang thuộc tính riêng cho từng cấu hình.Để làm điều này:

  1. Tạo một tờ sở hữu cấu hình cụ thể
  2. Mở quản lý tài sản
  3. Nhấp chuột phải vào cấu hình (không dự án) mà bạn muốn sửa đổi
  4. Bấm "Add Trang tính hiện có "và thêm trang tính của bạn

Điều này giúp bạn tránh điều kiện chèn vào một trang tính cho nhiều cấu hình. Nếu bạn có một số thuộc tính phổ biến mà bạn muốn chia sẻ giữa các cấu hình, thì hãy tạo cấu trúc phân cấp. Bạn có thể sử dụng bảng trên cùng trong tất cả các cấu hình và các trang lồng nhau sẽ chỉ chứa thuộc tính cấu hình cụ thể

+0

HOÀN THÀNH! cảm ơn. Vì vậy, bạn cũng có thể tạo các trang mới trong mỗi nút cấu hình. Dễ dàng rơi vào cái bẫy của việc chỉnh sửa trang chia sẻ có tác dụng tất cả các cấu hình mặc dù nó được truy cập dưới mỗi nút cấu hình. – Justin

Các vấn đề liên quan