質問: ### 前提・実現したいこと Visual Studio2013で、ソースコード管理について、ご相談です。 リリースをビルドする際、事情があり、有効にしたくない(客先事情)ソースコードがあるプロジェクトにて、下記条件で効率的に管理をするにはどういう方法があるのか、ご教授願いたく、投稿しました。 ・ソースコードベースで管理したい(該当ソースコードのようなイメージ) ・Gitなどは使わない [追記] 構成を理解していませんでした。申し訳ありません。 ソリューションの中に、複数プロジェクトがあり、1つのソリューションを一括で管理したいと考えています。そのような方法、ないでしょうか。。。 ### 発生している問題 可能であれば、VB.NETのコンパイルスイッチのような、一発で切替できる管理をしたい(現状、調べた限りでは、そういう機能がない??) ### 該当のソースコード 例えば、今であれば、#if / #end if でソースを管理しています。(管理といっていいのか・・・) また、通常はGitなどを使ってはいるのですが・・・ 今回は、ソースコード上での切替が出来るのがベストだという事を言われています。。。(個人的には、Gitでの差分確認で良いと思うのですが・・・それはNG) ``` #if true // Ver.〇〇より追加/変更 ・ ・ ソースコード ・ ・ #else //変更時はこれ以降に以前のコード(追加時はない) ・ ・ #endif ``` これだと、一つ一つ確認していく必要があるので、漏れが出る可能性が高く(管理しにくく)問題だと考えています。 ### 調査した内容 1) #defineを使用する コンパイラオプションを設定して、有効/無効のソースコードを分ける 参考:https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/compiler-options/define-compiler-option → 自分の理解では、ソースファイル一つずつに宣言をしないといけないので、現実的ではない? ``` #define No_Relese Using System; ・ ・ ・ namespace 〇〇 { ・ ・ ・ } ``` 2)条件付きコンパイル https://dobon.net/vb/dotnet/programing/define.html → まさにこれだっと思ったのですが、構成プロパティ―になぜか「ビルド」が表示されていない。 VisualStudioのオプション → プロジェクトおよびソリューション → 全般 → 「ビルド構成の詳細を表示(I)」のチェックが入っていることを確認。 ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/02c5f90fbaa1c460a4cdd867f94980f5.png) ↓ プロジェクトのプロパティ(複数のプロジェクトが1つのソリューションにある) ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/a985ffbaf9845565145be4c5d9985cd3.png) この使い方は、#defineの使い方と同様の使い方しか出来なそう... ### 補足情報(FW/ツールのバージョンなど) OS:Windows10 開発環境:Visual Studio2013 / .NetFramwork4.6
回答: プロジェクトでビルド時に指定するシンボル(`#define`で指定するもの)は、プロジェクトファイル*.csproj 内で`DefineConstants`要素で指定されています。ビルドの前に、各プロジェクトの *.csprojファイルのこの要素部分を、何らかのスクリプト(バッチファイルでも、PowerShellスクリプトでも何でも)で書き換えた後、ビルドすることで一応は用を成すことができます。 ``` ... TRACE;DEBUG;<追加したいシンボル> ... ``` ただ、プロジェクトの「ビルドイベント」、「ビルド前イベントのコマンドライン」でこれができれば良いですが、ビルド時は*.csprojファイルが使用中である為、難しいでしょう。ビルドする前にあらかじめ実行しておく必要があるかと思います。 で、`#define`で指定するシンボルを、外部で定義できると目的を果たせそうです。 Visual Studioの「開発者コマンドプロンプト」上では、ご存じのように`devenv`コマンドでビルドすることができます。ここで、環境変数を指定してみます。 方法: ビルドで環境変数を使用する - Visual Studio 2015 ※Visual Studio 2015に関する記事ですが、お使いのVisual Studio 2013ならほぼ同じはずです。 例えば上記、*.csprojファイルの``相当の部分に`$(EXTRA_VARS)`と入力します。(`EXTRA_VARS`と言うのは便宜上の名前です。適当に変えてください) !イメージ説明 Visual Studioの「開発者コマンドプロンプト」上で、環境変数`EXTRA_VARS`の値にシンボルとして`DEFVAR1`と`DEFVAR3`を`;`で区切って指定します。確認の為、あえて`DEFVAR2`を除外しておきます。 ``` C:\work>set EXTRA_VARS=DEFVAR1;DEFVAR3 C:\work>echo %EXTRA_VARS% DEFVAR1;DEFVAR3 ``` `DEFVAR1`、`DEFVAR2`、`DEFVAR3`のシンボルを利用する以下のコードを例として ``` using System; namespace ConApp1 { class Program { static void Main(string[] args) { Console.WriteLine("*** start."); #if DEFVAR1 #warning "DEFVAR1 defined." Console.WriteLine("--- DEFVAR1"); #endif #if DEFVAR2 #warning "DEFVAR2 defined." Console.WriteLine("--- DEFVAR2"); #endif #if DEFVAR3 #warning "DEFVAR3 defined." Console.WriteLine("--- DEFVAR3"); #endif Console.WriteLine("*** done."); } } } ``` `devenv`コマンドでソリューションファイル `ConApp1.sln`を指定し、rebuildします。 ``` C:\work>devenv /rebuild debug ConApp1.sln Microsoft (R) Microsoft Visual Studio 2012 Version 11.0.61219.0. Copyright (C) Microsoft Corp. All rights reserved. 1>------ すべてのリビルド開始: プロジェクト: ConApp1, 構成: Debug Any CPU ------ 1>C:\work\Program.cs(11,10,11,28): warning CS1030: #warning: '"DEFVAR1 defined."' 1>C:\work\Program.cs(21,10,21,28): warning CS1030: #warning: '"DEFVAR3 defined."' 1> ConApp1 -> C:\work\bin\Debug\ConApp1.exe ========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ========== ``` コード中に記述した`#warning`プリプロセッサ命令がビルド中に実行されていることが分かります。 ビルドした実行ファイルを実際に実行してみます。`DEFVAR2`部分が無いことが分かります。 ``` C:\work>bin\Debug\ConApp1.exe *** start. --- DEFVAR1 --- DEFVAR3 *** done. C:\work> ``` この方法ならば、各プロジェクトで共通の環境変数の値を利用してコンパイル時の条件を制御できるでしょう。(尚、上記実行例は、Visual Studio 2012で確認したものです) Visual Studio でのビルド時に使われる「MSBuild」に関する情報を踏まえておくと、より高度なことができると思います。