MSBuildはWindowsにおけるソースコードのコンパイル・ビルドコマンドであり、主にVisual Studioを使って開発する場合に使用されます。
ここでは、MSBuildのmakeファイルの書き方を解説します。
MSBuildのmakeファイル
概要
MSBuildのmakeファイルは「プロジェクトファイル(*.vcxproj)」と「プロパティファイル(*.props)」から構成されます。プロジェクトファイルは、Visual Studioを使って開発する場合に必ずつくられるファイルです。1つのプロジェクトファイルで、1つのdllもしくはexeを作成することができます。
プロジェクトファイルのみを使って開発することもできますが、システムの規模が大きくなるとプロジェクトファイルの数が増え、各プロジェクトファイルに共通の記載が増えてきます。すると、プロジェクトファイルのある項目を変更をしたいとき、他のプロジェクトファイルもすべて変更しなくてはいけないケースが出てきます。このようなときに使うのがプロパティファイルであり、各プロジェクトファイルの共通項目を集約することができます。
フォルダ・ファイル構成
基本的なフォルダ・ファイル構成を解説します。
以下のように、フォルダ・ファイルを配置します。
フォルダ・ファイル | 概要 |
---|---|
src/make.props | プロパティファイル ファイル名は任意でよい。 |
src/make.config.props | プロパティファイル ファイル名は任意でよい。 プロパティファイルは複数に分けることも可能。 このプロパティファイルには、バージョン情報などを記載する。 |
src/components | コンポーネントを配置するフォルダ |
src/components/make.props | プロパティファイル ファイル名は任意でよい。 src/make.propsを継承する。 その上で、componentsフォルダ内で固有のプロパティを指定できる。 |
src/components/make.config.props | プロパティファイル ファイル名は任意でよい。 src/make.config.propsを継承する。 その上で、componentsフォルダ内で固有のプロパティを指定できる。 |
src/components/make_debug64.props | プロパティファイル ファイル名は任意でよい。 Debug|x64ビルドで固有のプロパティを指定できる。 |
src/components/make_release64.props | プロパティファイル ファイル名は任意でよい。 Release|x64ビルドで固有のプロパティを指定できる。 |
src/components/component* | 各コンポーネントを配置するフォルダ |
src/components/component*/components*.vcxproj | プロジェクトファイル ファイル名は任意でよい。 各propsファイルを継承する。 その上で、プロジェクト固有のプロパティを指定できる。 |
src/components/component*/main.cpp | ソースファイル |
ファイル内容
プロジェクトファイル、プロパティファイルはXMLで構成されます。
ここでは、各ファイルの全体像と、特質すべきXML要素(★箇所)のみ言及します。
その他の基本的なXML要素の役割は、Microsoftのドキュメントをご覧下さい。
src/make.props
ファイルの内容は以下になります。
src/make.props
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
</ImportGroup>
<PropertyGroup Label="UserMacros"> <!-- ★ユーザーによるマクロ変数を定義できる -->
<HOGE_SRC_DIR>..\..</HOGE_SRC_DIR> <!-- ★プロジェクトファイルからの相対パス -->
<HOGE_BUILD_DIR>$(HOGE_SRC_DIR)\build$(HOGE_VER)</HOGE_BUILD_DIR> <!-- ★ビルド結果の出力先("HOGE_VER"はsrc/make.config.propsに定義している) -->
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
<_PropertySheetDisplayName>HOGE Base Property Sheet</_PropertySheetDisplayName> <!-- ★このファイルの任意の名前 -->
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<AdditionalIncludeDirectories>$(WindowsSdkDir)\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<StringPooling>true</StringPooling>
<AssemblerOutput>All</AssemblerOutput>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile>
<MapExports>true</MapExports>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
src/make.config.props
ファイルの内容は以下になります。
src/make.config.props
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
</ImportGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='16.0'" Label="Globals"> <!-- ★Visual Studio 2019の場合の定義 -->
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <!-- ★Windows SDKのバージョン、「10.0」とすると、自分の環境にある最新のSDKを指す -->
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='15.0'" Label="Globals"> <!-- ★Visual Studio 2017の場合の定義 -->
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='14.0'" Label="Globals"> <!-- ★Visual Studio 2015の場合の定義 -->
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='16.0'" Label="Configuration"> <!-- ★Visual Studio 2019の場合の定義(コンフィグ) -->
<PlatformToolset>v142</PlatformToolset> <!-- ★ツールセット(ドライバーなど)のバージョン -->
<CharacterSet>MultiByte</CharacterSet> <!-- ★文字コードの指定。"MultiByte" or "UNICODE"であり、プログラムがUTF-8等を扱う場合は前者、UTF-16の場合は後者を指定 -->
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='15.0'" Label="Configuration"> <!-- ★Visual Studio 2017の場合の定義(コンフィグ) -->
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='14.0'" Label="Configuration"> <!-- ★Visual Studio 2015の場合の定義(コンフィグ) -->
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='16.0'" Label="UserMacros"> <!-- ★Visual Studio 2019の場合の定義(ユーザーが任意に定義するマクロ変数) -->
<HOGE_VER>2019</HOGE_VER>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='15.0'" Label="UserMacros"> <!-- ★Visual Studio 2017の場合の定義(ユーザーが任意に定義するマクロ変数) -->
<HOGE_VER>2017</HOGE_VER>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)'=='14.0'" Label="UserMacros"> <!-- ★Visual Studio 2015の場合の定義(ユーザーが任意に定義するマクロ変数) -->
<HOGE_VER>2015</HOGE_VER>
</PropertyGroup>
</Project>
src/components/make.props
ファイルの内容は以下になります。
src/components/make.props
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
<Import Project="..\make.props" /> <!-- ★src/make.propsを継承 -->
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <!-- ★componentsフォルダ内で固有のマクロ変数を指定できる -->
<PropertyGroup>
<_PropertySheetDisplayName>components</_PropertySheetDisplayName> <!-- ★このファイルの任意の名前 -->
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
src/components/make.config.props
ファイルの内容は以下になります。
src/components/make.config.props
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
<Import Project="..\make.config.props" /> <!-- ★src/make.config.propsを継承 -->
</ImportGroup>
</Project>
src/components/make_debug64.props
ファイルの内容は以下になります。
src/components/make_debug64.props
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <!-- ★componentsフォルダ内かつDebug|x64ビルドで固有のマクロ変数を指定できる -->
<PropertyGroup>
<_PropertySheetDisplayName>components.debug64</_PropertySheetDisplayName> <!-- ★このファイルの任意の名前 -->
<OutDir>$(HOGE_BUILD_DIR)\components\bin\x64\Debug\</OutDir> <!-- ★componentsフォルダ内かつDebug|x64ビルドでのビルド結果の出力先 -->
<IntDir>$(HOGE_VER)\$(PlatformName)\$(Configuration)\</IntDir> <!-- ★componentsフォルダ内かつDebug|x64ビルドでのビルド結果の出力先(関連ファイル) -->
</PropertyGroup>
<ItemDefinitionGroup>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX64</TargetMachine>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
src/components/make_release64.props
ファイルの内容は以下になります。
src/components/make_release64.props
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <!-- ★componentsフォルダ内かつRelease|x64ビルドで固有のマクロ変数を指定できる -->
<PropertyGroup>
<_PropertySheetDisplayName>components.releas64</_PropertySheetDisplayName> <!-- ★このファイルの任意の名前 -->
<OutDir>$(HOGE_BUILD_DIR)\components\bin\x64\Release\</OutDir> <!-- ★componentsフォルダ内かつRelease|x64ビルドでのビルド結果の出力先 -->
<IntDir>$(HOGE_VER)\$(PlatformName)\$(Configuration)\</IntDir> <!-- ★componentsフォルダ内かつRelease|x64ビルドでのビルド結果の出力先(関連ファイル) -->
</PropertyGroup>
<ItemDefinitionGroup>
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<TargetMachine>MachineX64</TargetMachine>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
src/components/component*/component*.vcxproj
ファイルの内容は以下になります。
src/components/component*/component*.vcxproj
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
<Import Project="..\make.config.props" /> <!-- ★src/components/make.config.propsを継承 -->
</ImportGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64"> <!-- ★当プロジェクトかつDebug|x64ビルドでのコンフィグ -->
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64"> <!-- ★当プロジェクトかつRelease|x64ビルドでのコンフィグ -->
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>component1</ProjectName> <!-- ★当プロジェクトの名前(ビルド結果のファイル名) -->
<ProjectGuid>{FD09A4AE-F201-4BA3-BB65-271F8694EDF0}</ProjectGuid> <!-- ★当プロジェクトの固有ID -->
<RootNamespace>component1</RootNamespace> <!-- ★当プロジェクトの名前空間 -->
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <!-- ★当プロジェクトかつDebug|x64ビルドでのコンフィグ -->
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <!-- ★当プロジェクトかつRelease|x64ビルドでのコンフィグ -->
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> <!-- ★当プロジェクトかつDebug|x64ビルドでのコンフィグ -->
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\make.props" /> <!-- ★src/components/make.propsを継承 -->
<Import Project="..\make_debug64.props" /> <!-- ★src/components/make_debug64.propsを継承 -->
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> <!-- ★当プロジェクトかつRelease|x64ビルドでのコンフィグ -->
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\make.props" /> <!-- ★src/components/make.propsを継承 -->
<Import Project="..\make_release64.props" /> <!-- ★src/components/make_release64.propsを継承 -->
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
プロパティファイルを継承している順番に注目して下さい。
上記の場合、①src/components/make.config.props ②src/components/make.props ③src/components/make_debug(release)64.props の順番に読み込んでいます。
例えば、①で定義したユーザーのマクロ変数を②では認識できますが、その逆は認識できないことになります。
ビルド確認
src/components/component*/main.cppは例えば以下のように実装し、ビルドを確認します。
src/components/component*/main.cpp
int main(int argc, const char** argv)
{
return 0;
}
用意したプロジェクトファイル、プロパティファイルでビルドすることができました。
ビルド結果が「src\build2019」以下に出力されていることも確認して下さい。