VC++ MSBuildのmakeファイルの書き方(ライブラリ)

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

前回の記事で、VC++アプリケーション(exeファイル)を作成する、MSBuildのmakeファイルの書き方を解説しました。
今回は、ライブラリ(dllファイル、libファイル)を作成する、MSBuildのmakeファイルの書き方を解説します。

MSBuildのmakeファイル

まずは前回の記事の通り、プロジェクトファイルとプロパティファイルを用意します。
その上で、以下のように修正します。

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" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <_PropertySheetDisplayName>components</_PropertySheetDisplayName>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <OutputFile>$(OutDir)$(ProjectName).dll</OutputFile>  <!-- ★変更箇所 -->
      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup />
</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" />
  <PropertyGroup>
    <_PropertySheetDisplayName>components.debug64</_PropertySheetDisplayName>
    <OutDir>$(HOGE_BUILD_DIR)\components\lib\x64\Debug\</OutDir>  <!-- ★変更箇所 -->
    <IntDir>$(HOGE_VER)\$(PlatformName)\$(Configuration)\</IntDir>
  </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" />
  <PropertyGroup>
    <_PropertySheetDisplayName>components.releas64</_PropertySheetDisplayName>
    <OutDir>$(HOGE_BUILD_DIR)\components\lib\x64\Release\</OutDir>  <!-- ★変更箇所 -->
    <IntDir>$(HOGE_VER)\$(PlatformName)\$(Configuration)\</IntDir>
  </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/component1/component1.vcxproj

component1を使います。
ファイルの内容は以下になります。

src/components/component1/component1.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" />
  </ImportGroup>
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectName>component1</ProjectName>
    <ProjectGuid>{FD09A4AE-F201-4BA3-BB65-271F8694EDF0}</ProjectGuid>
    <RootNamespace>component1</RootNamespace>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>  <!-- ★変更箇所 -->
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>  <!-- ★変更箇所 -->
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="..\make.props" />
    <Import Project="..\make_debug64.props" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="..\make.props" />
    <Import Project="..\make_release64.props" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <ItemDefinitionGroup>
    <ClCompile>
      <PreprocessorDefinitions>HOGE_LIB_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>  <!-- ★変更箇所 -->
    </ClCompile>
  </ItemDefinitionGroup>
  <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/component1/lib.h

src/components/component1に「lib.h」というヘッダファイルを追加し、以下のように実装します。helloworld()という関数を宣言します。

src/components/component1/lib.h

#pragma once

#ifdef HOGE_LIB_EXPORTS  // src/components/component1/component1.vcxproj内の「PreprocessorDefinitions」の値(ここでは「HOGE_LIB_EXPORTS」)と同じにする。
#define HOGE_LIB __declspec(dllexport)
#else
#define HOGE_LIB __declspec(dllimport)
#endif

void HOGE_LIB helloworld();

src/components/component1/main.cpp

ファイルの内容は以下になります。
helloworld()という関数の中身を実装します。

src/components/component1/main.cpp

#include <stdio.h>
#include "lib.h"

void HOGE_LIB helloworld()
{
	::printf("Hello, World \n");
}

ビルド確認

src/components/component1/component1.vcxprojをビルドします。

これで、helloworld()という関数を持ったライブラリ(dllファイル、libファイル)ができます。
ファイルの出力先は「src\build2019\components\lib\x64」以下になります。

ライブラリの呼び出し方法

作成したライブラリを呼び出す方法を解説します。

アプリケーション(exeファイル)のビルド時はlibファイルとリンクし、
アプリケーションの実行時はdllファイルとリンクすることになります。

プロパティファイルを以下のように修正します。

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" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <_PropertySheetDisplayName>components</_PropertySheetDisplayName>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>  <!-- ★変更箇所 -->
      <AdditionalDependencies>component1.lib;%(AdditionalDependencies)</AdditionalDependencies>  <!-- ★変更箇所(libファイルをリンク) -->
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup />
</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" />
  <PropertyGroup>
    <_PropertySheetDisplayName>components.debug64</_PropertySheetDisplayName>
    <OutDir>$(HOGE_BUILD_DIR)\components\bin\x64\Debug\</OutDir>  <!-- ★変更箇所 -->
    <IntDir>$(HOGE_VER)\$(PlatformName)\$(Configuration)\</IntDir>
  </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>$(HOGE_BUILD_DIR)\components\lib\x64\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>  <!-- ★変更箇所(libファイルの場所を指定) -->
    </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" />
  <PropertyGroup>
    <_PropertySheetDisplayName>components.releas64</_PropertySheetDisplayName>
    <OutDir>$(HOGE_BUILD_DIR)\components\bin\x64\Release\</OutDir>  <!-- ★変更箇所 -->
    <IntDir>$(HOGE_VER)\$(PlatformName)\$(Configuration)\</IntDir>
  </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>$(HOGE_BUILD_DIR)\components\lib\x64\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>  <!-- ★変更箇所(libファイルの場所を指定) -->
      <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup />
</Project>

src/components/component2/main.cpp

component2を使います。
ファイルの内容は以下になります。
component1.\lib.hを読み込んでhelloworld関数を認識し、main関数で実際に呼び出しています。

src/components/component1/main.cpp

#include <stdio.h>
#include "..\component1\lib.h"

int main(int argc, const char** argv)
{
	helloworld();

	::getchar();
	return 0;
}

ビルド確認

src/components/component2/component2.vcxprojをビルドします。
ファイルの出力先は「src\build2019\components\bin\x64」以下になります。

以上で、helloworld()という関数を持ったライブラリであるcomponent1.dllと、それを呼び出すcomponent2.exeができました。

動作確認

component1.dllとcomponent2.exeを、同一フォルダに配置します(Debug or Releaseは合わせて下さい)。exeファイルと同一フォルダに、dllファイルが存在している必要があります。

出力ファイル

component2.exeを実行し、以下のように出力されれば成功です。

実行結果
タイトルとURLをコピーしました