複数バージョンのVisual Studioで開けるC++のプロジェクトを作る
解決策1: CMakeをつかう
まあ一番確実だし、他のコンパイラでも使えるしコンパイラのバージョンなんでいうわかりにくい指標ではなく対応している言語機能で制約することもできる(らしい)が、まあそれは他のサイトに解説を譲る。
解決策2:あえてCMakeを使わないという選択肢
今回の本題。
Condition
attribute
C++プロジェクトの実体は.vcxproj
という拡張子のxmlファイルである。xmlのattributeをハックして条件分岐できるようになっている、いわゆるCondition
attributeだ、汚いです。
こいつを活用する。
複数バージョンで利用するときの障害となるのはなにか
そもそもなんで普通に作ったプロジェクトが他のVisual Studioのバージョンで開けないのかを確認する。
まあ理由は簡単でPlatform Toolset
が指定されているものと開いたVSの持っているVC++のバージョンが合わないと「アップグレードしますか?」というダイアログが出るわけだ。
.vcxproj
の中で該当する部分を見てみよう。下のxmlは普通にC++のプロジェクトを作ったときのものである
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- 中略 -->
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<!-- 中略 -->
</Project>
自動生成の設定ファイルでもCondition
attributeが使われているあたりなんか怖いが、問題となっているのはPlatformToolset
tagだ。
PlatformToolset
もCondition
で分ければいいじゃない
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration" Condition="'$(VisualStudioVersion)' == '12.0'">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(VisualStudioVersion)' == '14.0'">
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(VisualStudioVersion)' == '15.0'">
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
</Project>
つまりこういうファイルを作ってこれを読み込めばいい。なんでVisualStudioVersion
が15.0
のときPlatformToolset
がv150
じゃないんや!という疑問については
Visual C++ 2017のバージョン番号がややこしすぎる件
を参照してほしい。主にはbinary capabilityの問題だ。
上記ではVS2013/VS2015/VS2017に対応させたが、もちろん必要に応じて適宜いじれば良い。
具体的には、これをvcxcompat.props
という名前で(説明の都合上).vcxproj
がある場所に(説明の都合上、ただの相対パス指定)UTF-8で(BOMはどっちでも)保存し、.vcxproj
は
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- 中略 -->
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="vcxcompat.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<!-- 中略 -->
</Project>
というふうに書き換えればよい。何が変わったかはまあdiffればいいと思うが、Import
tagが増えて、PlatformToolset
タグが消滅した。
実例
追記
なんかあの有名なサクラエディタの開発者ドキュメントにこの記事のURLを見つけてめっちゃわろてます。 @m-tmatma さんが出したPRがきっかけのようで。わざわざリンクして頂いてありがとうございます。
をみるとわかるように、Windows SDKの切り替えにも活用できます。
まあでも良い子のみんなは新しくプロジェクト始めるときは素直にCMake使おうな?
License
Author And Source
この問題について(複数バージョンのVisual Studioで開けるC++のプロジェクトを作る), 我々は、より多くの情報をここで見つけました https://qiita.com/yumetodo/items/a8324efaf83c9c08d168著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .