শর্তসাপেক্ষিত সংকলন এবং কাঠামোর লক্ষ্যগুলি


124

কয়েকটি ছোটখাটো জায়গা রয়েছে যেখানে টার্গেট ফ্রেমওয়ার্কটি আরও নতুন সংস্করণ হলে আমার প্রকল্পের কোডগুলি মারাত্মকভাবে উন্নত করতে সক্ষম হতে পারে। এগুলি প্রয়োজনীয় হিসাবে স্যুইচ করতে আমি সি # তে আরও ভাল উত্তোলনের শর্তসাপেক্ষ সংকলন করতে সক্ষম হতে চাই।

কিছুটা এইরকম:

#if NET40
using FooXX = Foo40;
#elif NET35
using FooXX = Foo35;
#else NET20
using FooXX = Foo20;
#endif

এই চিহ্নগুলির মধ্যে কোনও কি নিখরচায় আসে? প্রকল্প কনফিগারেশনের অংশ হিসাবে আমার কি এই চিহ্নগুলি ইনজেকশন করা দরকার? এটি করা যথেষ্ট সহজ বলে মনে হচ্ছে যেহেতু আমি জানি যে এমএসবিল্ড থেকে কোন কাঠামোটিকে লক্ষ্য করা হচ্ছে।

/p:DefineConstants="NET40"

লোকেরা কীভাবে এই পরিস্থিতি পরিচালনা করছে? আপনি কি বিভিন্ন কনফিগারেশন তৈরি করছেন? আপনি কমান্ড লাইনের মাধ্যমে স্থির হয়ে যাচ্ছেন?



আপনি যদি ভিএস-তে একটি সাধারণ প্রাক-বেকড সমাধান চান তবে দয়া করে এই ব্যবহারকারীর ভয়েসটি ভিজ্যুয়ালস্টুডিও.ইউসারওয়্যস // ফোরামস / 121579- ভিজ্যুয়াল-স্টুডিও / ...
জনসি

1
পাশাপাশি এই লিঙ্কটি দেখুন। বেশ ব্যাখ্যামূলক। blogs.msmvps.com/punitganshani/2015/06/21/…
মার্কো আলভেস

প্রকল্পের গ্রুপগুলি, নুগেট পুনরুদ্ধার করুন এবং নিউজ রেফের গ্রুপগুলি, দুর্দান্ত সমাধান: shazwazza.com/post/…
ওজব্বি

উত্তর:


119

এটি সম্পাদন করার সর্বোত্তম উপায়গুলির মধ্যে একটি হ'ল আপনার প্রকল্পে বিভিন্ন বিল্ড কনফিগারেশন তৈরি করা:

<PropertyGroup Condition="  '$(Framework)' == 'NET20' ">
  <DefineConstants>NET20</DefineConstants>
  <OutputPath>bin\$(Configuration)\$(Framework)</OutputPath>
</PropertyGroup>


<PropertyGroup Condition="  '$(Framework)' == 'NET35' ">
  <DefineConstants>NET35</DefineConstants>
  <OutputPath>bin\$(Configuration)\$(Framework)</OutputPath>
</PropertyGroup>

এবং আপনার ডিফল্ট কনফিগারেশনের একটিতে:

<Framework Condition=" '$(Framework)' == '' ">NET35</Framework>

এটি অন্য কোথাও সংজ্ঞায়িত না হলে ডিফল্ট সেট করবে। উপরের ক্ষেত্রে আউটপুটপথ প্রতিটি সংস্করণ তৈরির সময় আপনাকে আলাদা আলাদা সমাবেশ দেবে।

তারপরে আপনার বিভিন্ন সংস্করণ সংকলনের জন্য আফটার বিল্ড লক্ষ্য তৈরি করুন:

<Target Name="AfterBuild">
  <MSBuild Condition=" '$(Framework)' != 'NET20'"
    Projects="$(MSBuildProjectFile)"
    Properties="Framework=NET20"
    RunEachTargetSeparately="true"  />
</Target>

এই উদাহরণটি প্রথম বিল্ডের পরে ফ্রেটওয়ার্ক ভেরিয়েবল সেটটি NET20 এ পুরো প্রকল্পটি পুনরায় সংকলন করবে (উভয়টি সংকলন করে এবং ধরে নিবেন যে প্রথম বিল্ডটি উপরে থেকে ডিফল্ট NET35 ছিল)। প্রতিটি সংকলনে শর্তসাপেক্ষে নির্ধারিত মানগুলি সঠিকভাবে সেট করা থাকবে।

আপনি যদি ডাব্লু / ও ফাইলগুলিকে #ifdef করতে চান তবে এই পদ্ধতিতে আপনি প্রজেক্ট ফাইলে নির্দিষ্ট ফাইলগুলিও বাদ দিতে পারেন:

<Compile Include="SomeNet20SpecificClass.cs" Condition=" '$(Framework)' == 'NET20' " />

বা এমনকি তথ্যসূত্র

<Reference Include="Some.Assembly" Condition="" '$(Framework)' == 'NET20' " >
  <HintPath>..\Lib\$(Framework)\Some.Assembly.dll</HintPath>
</Reference>

পারফেক্ট। এটি সম্পন্ন হতে পারে তা জানতে আমার এমসবিল্ড ফর্ম্যাটটি হ্যাক করার যথেষ্ট অভিজ্ঞতা ছিল তবে সমস্ত বিবরণ বের করার জন্য পর্যাপ্ত সময় নেই। আপনাকে অনেক ধন্যবাদ!
ম্যাকামে

আপনি যদি আমার সম্পর্কিত প্রশ্নের ( stackoverflow.com/questions/2923181 ) উপর এই উত্তরের কোনও রেফারেন্স যুক্ত করেন , আমি আপনাকে সমাধান হিসাবে চিহ্নিত করব। এটি আসলে একই সাথে উভয়কেই সমাধান করে ves
ম্যাকামে

7
উত্তরের জন্য ধন্যবাদ, তবে এখন ভিএস2010 এর মধ্যে "টার্গেটফ্রেমকর্ম ভার্সন" নামে একটি নতুন ট্যাগ ইতিমধ্যে অন্তর্ভুক্ত রয়েছে, এখন প্রতিটি সম্পত্তি গোষ্ঠীর শর্তযুক্ত, কেবল টার্গেটফ্রেমওয়ার্ক ভার্সন পরিবর্তন করা হয়েছে, এটিকে কাজ করার জন্য আমাদের এখনও কি এই সমস্ত প্রয়োজন?
আকাশ কাভা

এই উত্তরটি কেবল ফ্রেমওয়ার্কের জন্য সংজ্ঞায়িত ধ্রুবকগুলি সম্পর্কে নয় তবে একাধিক ফ্রেমওয়ার্কের জন্য বিল্ডিং
কেটবাইট

4
এই পোস্টটি আমার পক্ষে কাজ করেছে তবে আমি এমএসবিল্ডে ভাল নই এবং এটি বের করতে কিছুটা সময় নিয়েছে। আমি একটি প্রকল্প তৈরি করেছি যা উদাহরণ হিসাবে কাজ করে। dev6.blob.core.windows.net/blog-images/DualTargetFrameworks.zip
TheDev6

44

আমার পক্ষে এখন পর্যন্ত কাজ করা একটি বিকল্প হ'ল প্রকল্প ফাইলটিতে নিম্নলিখিতগুলি যুক্ত করা:

 <PropertyGroup>
    <DefineConstants Condition=" !$(DefineConstants.Contains(';NET')) ">$(DefineConstants);$(TargetFrameworkVersion.Replace("v", "NET").Replace(".", ""))</DefineConstants>
    <DefineConstants Condition=" $(DefineConstants.Contains(';NET')) ">$(DefineConstants.Remove($(DefineConstants.LastIndexOf(";NET"))));$(TargetFrameworkVersion.Replace("v", "NET").Replace(".", ""))</DefineConstants>
  </PropertyGroup>

এটি "v3.5" এর মতো টার্গেটফ্রেমওয়ার্ক ভার্সন সম্পত্তিটির মান নেয়, "v" এবং "প্রতিস্থাপন করে।" "NET35" পেতে (নতুন সম্পত্তি বৈশিষ্ট্য ব্যবহার করে )। এরপরে এটি বিদ্যমান যে কোনও "এনইটিএক্সএক্সএক্স" মান সরিয়ে দেয় এবং এটি সংজ্ঞায়িত কনস্ট্যান্টস এর শেষে যুক্ত করে। এটি স্ট্রিমলাইন করা সম্ভব হতে পারে, তবে আমি ঝাঁকুনির সময় পাইনি।

ভিএস-তে প্রকল্পের বৈশিষ্ট্যগুলির বিল্ড ট্যাবটির দিকে তাকিয়ে আপনি শর্তসাপেক্ষ সংকলন চিহ্ন বিভাগে ফলাফল মান দেখতে পাবেন। অ্যাপ্লিকেশন ট্যাবে লক্ষ্য কাঠামোর সংস্করণ পরিবর্তন করা হলে প্রতীকটি স্বয়ংক্রিয়ভাবে পরিবর্তিত হয়। তারপরে আপনি #if NETxxপ্রিপ্রোসেসর নির্দেশিকাগুলি স্বাভাবিক উপায়ে ব্যবহার করতে পারেন । ভিএস-তে প্রকল্প পরিবর্তন করা কাস্টম প্রপার্টি গ্রুপটি হারাবে বলে মনে হয় না।

নোট করুন যে এটি আপনাকে ক্লায়েন্ট প্রোফাইল টার্গেট বিকল্পগুলির জন্য আলাদা কিছু দেয় না বলে মনে হয়, তবে এটি আমার পক্ষে কোনও সমস্যা নয়।


জেরেমি, বাহ, ধন্যবাদ এই নিখুঁত যেহেতু আমি ইতিমধ্যে আমার বিল্ড সলিউশনে পৃথকভাবে বিল্ডিং করছি।
গ্রেগ ফিনজার

+1 টি। কে ভেবেছিল "find (DefineConstants.Contains ('..." ??) খুঁজে পাওয়া এত কঠিন হবে বলে ধন্যবাদ
CAD

অবশেষে আমি এই পৃষ্ঠায় আমার পথটি খুঁজে পেলাম, কারণ কীভাবে আমি আমার এই বিল্ডিংয়ের মধ্যে এই ম্যাজিক ধ্রুবকগুলি পেয়েছি সে সম্পর্কে আমার একটি রিফ্রেশার প্রয়োজন। আমি আজ একই প্রকল্পটির পুনর্বিবেচনা করছি, গ্রন্থাগারকে মহকুমা করার জন্য, এবং আমার সাথে কয়েকটি মহকুমায় যাওয়ার জন্য প্রতীকগুলির প্রয়োজন। আমি কেবল এটির উপরে দেখেছি এবং লক্ষ্য করেছি যে আপনার উত্তরটি ইতিমধ্যে মূল .CSPROJ ফাইলে যথাযথভাবে স্বীকৃত।
ডেভিড এ গ্রে

15

আমার এই সমাধানগুলির সাথে সমস্যা ছিল, সম্ভবত আমার প্রাথমিক ধ্রুবকগুলি এই বৈশিষ্ট্যগুলির দ্বারা প্রাক-নির্মিত হয়েছিল because

<DefineConstants />
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<DebugSymbols>true</DebugSymbols>

ভিজ্যুয়াল স্টুডিও ২০১০ সেমি-কোলনের কারণে ত্রুটি ছুঁড়েছে, দাবি করে যে তারা অবৈধ চরিত্র। ত্রুটি বার্তাটি আমাকে একটি ইঙ্গিত দেয় কারণ আমি দেখতে পেলাম পূর্ব-বিল্ট কনস্ট্যান্টগুলি কমা দ্বারা বিচ্ছিন্ন হয়ে পড়েছিলাম এবং অবশেষে আমার "অবৈধ" আধা-কোলন অনুসরণ করবে। কিছু পুনর্নির্মাণ এবং ম্যাসেজ করার পরে আমি এমন একটি সমাধান নিয়ে আসতে সক্ষম হয়েছি যা আমার পক্ষে কাজ করে।

<PropertyGroup>
  <!-- Adding a custom constant will auto-magically append a comma and space to the pre-built constants.    -->
  <!-- Move the comma delimiter to the end of each constant and remove the trailing comma when we're done.  -->
  <DefineConstants Condition=" !$(DefineConstants.Contains(', NET')) ">$(DefineConstants)$(TargetFrameworkVersion.Replace("v", "NET").Replace(".", "")), </DefineConstants>
  <DefineConstants Condition=" $(DefineConstants.Contains(', NET')) ">$(DefineConstants.Remove($(DefineConstants.LastIndexOf(", NET"))))$(TargetFrameworkVersion.Replace("v", "NET").Replace(".", "")), </DefineConstants>
  <DefineConstants Condition=" $(TargetFrameworkVersion.Replace('v', '')) >= 2.0 ">$(DefineConstants)NET_20_OR_GREATER, </DefineConstants>
  <DefineConstants Condition=" $(TargetFrameworkVersion.Replace('v', '')) >= 3.5 ">$(DefineConstants)NET_35_OR_GREATER</DefineConstants>
  <DefineConstants Condition=" $(DefineConstants.EndsWith(', ')) ">$(DefineConstants.Remove($(DefineConstants.LastIndexOf(", "))))</DefineConstants>
</PropertyGroup>

আমি উন্নত সংকলক সেটিংস কথোপকথনের একটি স্ক্রিনশট পোস্ট করব (আপনার প্রকল্পের সংকলন ট্যাবে "উন্নত সংকলন বিকল্পগুলি ..." বোতামটি ক্লিক করে খোলা হয়েছে)। তবে একজন নতুন ব্যবহারকারী হিসাবে আমার কাছে এরকম প্রতিনিধিত্ব নেই। আপনি যদি স্ক্রিনশটটি দেখতে পেতেন, আপনি সম্পত্তি গোষ্ঠীর দ্বারা স্বতঃপূর্ণ কাস্টম কনস্ট্যান্টগুলি দেখতে পাবেন এবং তারপরে আপনি বলবেন, "আমাকে তার কিছুটা পেতে হবে।"


সম্পাদনা: চমকপ্রদভাবে দ্রুত এই প্রতিবেদন পেয়েছেন .. ধন্যবাদ বলছি! স্ক্রিনশটটি এখানে:

উন্নত সংকলক সেটিংস


4

ধ্রুবকগুলি সাফ করার সাথে শুরু করুন:

<PropertyGroup>
  <DefineConstants/>
</PropertyGroup>

এরপরে, আপনার ডিবাগ, ট্রেস এবং অন্যান্য ধ্রুবকগুলি যেমন:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <DebugSymbols>true</DebugSymbols>
  <DebugType>full</DebugType>
  <Optimize>false</Optimize>
  <DefineConstants>TRACE;DEBUG;$(DefineConstants)</DefineConstants>
</PropertyGroup>

সর্বশেষে, আপনার কাঠামোর ধ্রুবকগুলি তৈরি করুন:

<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v2.0' ">
  <DefineConstants>NET10;NET20;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v3.0' ">
  <DefineConstants>NET10;NET20;NET30;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v3.5' ">
  <DefineConstants>NET10;NET20;NET30;NET35;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v4.0' ">
  <DefineConstants>NET10;NET20;NET30;NET35;NET40;$(DefineConstants)</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v4.5' ">
  <DefineConstants>NET10;NET20;NET30;NET35;NET40;NET45;$(DefineConstants)</DefineConstants>
</PropertyGroup>

আমি মনে করি এই পদ্ধতিটি খুব পাঠযোগ্য এবং বোধগম্য।


3

একটি বিদ্যমান <DefineConstants>DEBUG;TRACE</DefineConstants>লাইনের পরে একটি .csproj ফাইলে , এটি যুক্ত করুন:

<DefineConstants Condition=" '$(TargetFrameworkVersion.Replace(&quot;v&quot;,&quot;&quot;))' &gt;= '4.0' ">NET_40_OR_GREATER</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkVersion.Replace(&quot;v&quot;,&quot;&quot;))' == '4.0' ">NET_40_EXACTLY</DefineConstants>

ডিবাগ এবং রিলিজ বিল্ড কনফিগারেশন উভয়ের জন্য এটি করুন। তারপরে আপনার কোডটিতে ব্যবহার করুন:

#if NET_40_OR_GREATER
   // can use dynamic, default and named parameters
#endif

3
ডিফল্ট এবং নামযুক্ত প্যারামিটারগুলি .NET ফ্রেমওয়ার্ক 4 এর বৈশিষ্ট্য নয়,। নেট 4 সংকলকের বৈশিষ্ট্য। এগুলি নেট ভিজুয়াল স্টুডিও ২০১০-তে সংকলিত রয়েছে। নেট 2 বা। নেট 3 প্রকল্পগুলিতে লক্ষ্য হিসাবে প্রজেক্টেও এটি ব্যবহার করা যেতে পারে It এটি কেবল সিনট্যাকটিক চিনি। অন্যদিকে, ডায়নামিক .NET ফ্রেমওয়ার্ক 4 এর বৈশিষ্ট্য, এবং আপনি এর আগে ফ্রেমওয়ার্ক লক্ষ্য করে প্রকল্পগুলিতে এটি ব্যবহার করতে পারবেন না।
থানাসিস আইওনানিডিস

2

@ আজারিয়ান, আপনার উত্তরটি জেরেমির সাথে একত্রিত করা যায় এটি ডিবাগ | রিলিজ ইত্যাদির চেয়ে এক জায়গায় রাখতে to

আমার জন্য, উভয় প্রকারের সংমিশ্রণটি সবচেয়ে ভাল কাজ করে যেমন # আইইটিএনটিএক্সএক্স ব্যবহার করে কোডের শর্তাদি এবং একসাথে বিভিন্ন ফ্রেমওয়ার্কের সংস্করণ তৈরি করা।

আমার .csproj ফাইলটিতে এটি রয়েছে:

  <PropertyGroup>
    <DefineConstants Condition=" '$(TargetFrameworkVersion.Replace(&quot;v&quot;,&quot;&quot;))' &gt;= '4.0' ">NET_40_OR_GREATER</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(TargetFrameworkVersion.Replace(&quot;v&quot;,&quot;&quot;))' == '3.5' ">
    <DefineConstants>NET35</DefineConstants>
    <OutputPath>bin\$(Configuration)\$(TargetFrameworkVersion)</OutputPath>
  </PropertyGroup>

এবং লক্ষ্যগুলিতে:

  <Target Name="AfterBuild">
    <MSBuild Condition=" '$(TargetFrameworkVersion.Replace(&quot;v&quot;,&quot;&quot;))' &gt;= '4.0' "
      Projects="$(MSBuildProjectFile)"
      Properties="TargetFrameworkVersion=v3.5"
      RunEachTargetSeparately="true"  />
  </Target>

0

আপনি যদি .NET কোর বিল্ড সিস্টেম ব্যবহার করে থাকেন তবে আপনি এর পূর্বনির্ধারিত চিহ্নগুলি ব্যবহার করতে পারেন (যা বাস্তবে ইতিমধ্যে আপনার উদাহরণের সাথে মেলে এবং আপনার কোনও পরিবর্তনের প্রয়োজন নেই .csproj!):

#if NET40
using FooXX = Foo40;
#elif NET35
using FooXX = Foo35;
#else NET20
using FooXX = Foo20;
#endif

পূর্বনির্ধারিত প্রতীকগুলির তালিকা ক্রস প্ল্যাটফর্ম সরঞ্জাম এবং #if (সি # রেফারেন্স) সহ গ্রন্থাগারগুলি বিকাশ করে নথিভুক্ত করা হয়েছে :

.NET ফ্রেমওয়ার্ক: NETFRAMEWORK , NET20, NET35, NET40, NET45, NET451, NET452, NET46, NET461, NET462, NET47, NET471, NET472,NET48

.NET মান: NETSTANDARD , NETSTANDARD1_0, NETSTANDARD1_1, NETSTANDARD1_2, NETSTANDARD1_3, NETSTANDARD1_4, NETSTANDARD1_5, NETSTANDARD1_6, NETSTANDARD2_0,NETSTANDARD2_1

.NET কোর: NETCOREAPP , NETCOREAPP1_0, NETCOREAPP1_1, NETCOREAPP2_0, NETCOREAPP2_1, NETCOREAPP2_2,NETCOREAPP3_0

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.