VC++ MSBuildのmakeファイルの書き方

vc-msbuild-makefileのアイキャッチ画像 Windows

MSBuildはWindowsにおけるソースコードのコンパイル・ビルドコマンドであり、主にVisual Studioを使って開発する場合に使用されます。

VisualStudioでのビルド

ここでは、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;
}
VisualStudioでのビルド

用意したプロジェクトファイル、プロパティファイルでビルドすることができました。
ビルド結果が「src\build2019」以下に出力されていることも確認して下さい。

タイトルとURLをコピーしました