前回の記事で、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を実行し、以下のように出力されれば成功です。