Windows 10及Visual Studio 2015下安裝libconfig
前言
筆者一開始打算在Windows 10下安裝官方的libconfig,並搭配Visual Studio 2015使用。但是因為官方的教程在這方面並沒有太多著墨,筆者自己踩了坑後(詳見Unable to compile on Windows 10),決定轉而使用vcpkg來安裝。
安裝vcpkg
vcpkg
是由微軟開發,用於在Windows, Mac及Linux下管理C/C++套件的工具。
vcpkg
的安裝十分簡單,其步驟都寫在官方的Readme裡了。
官方建議的安裝路徑為C:\src\vcpkg
或C:\dev\vcpkg
,在此筆者選擇的是C:\src\vcpkg
。
首先到C:\src
(要自己創建這個目錄):
cd C:\src
然後下載vcpkg
:
git clone https://github.com/microsoft/vcpkg
接著進入該專案,執行bootstrap-vcpkg.bat
:
cd vcpkg
bootstrap-vcpkg.bat
安裝完成後試著下vcpkg
這個指令,如果成功的話會打印出一連串的help message。
安裝libconfig
要用vcpkg
安裝套件也很簡單,只要在vcpkg install
後面加上套件名稱即可:
vcpkg install libconfig
如上,但是有一點要注意的是,它默認安裝的版本是在x86
系統上使用的libconfig:x86-windows
,如果想要在x64
系統上使用,則應使用以下指令:
vcpkg install libconfig:x64-windows
在Visual Studio 2015中使用
設定Properties
在Solution Explorer
中,先點選要配置的專案,然後選取Properties
。
左側選取VC++ Directories
,然後配置相關路徑。
在Executable Directories
中加上C:\src\vcpkg\installed\x64-windows\bin
;
在Include Directories
中加上C:\src\vcpkg\installed\x64-windows\include
;
在Library Directories
中加上C:\src\vcpkg\installed\x64-windows\lib
。
接著選取左側Linker
->General
,在Additional Library Directories
處加上C:\src\vcpkg\installed\x64-windows\lib
。
然後點選Linker
->Input
,在Additional Dependencies
處加上libconfig++.lib
。
使用property sheet
上一節是在Visual Studio的GUI裡添加相關路徑,這裡採用另外一種方式,即使用property sheet設置。
新增一份名為libconfig.props
的檔案,填入以下內容。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<!-- User Macros -->
<PropertyGroup Label="UserMacros">
<LIBCONFIG_ROOT Condition="'$(Platform)'=='Win32'">C:\src\vcpkg\installed\x86-windows</LIBCONFIG_ROOT>
<LIBCONFIG_ROOT Condition="'$(Platform)'=='x64'">C:\src\vcpkg\installed\x64-windows</LIBCONFIG_ROOT>
</PropertyGroup>
<!-- Release|x64 -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>$(LIBCONFIG_ROOT)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<SDLCheck>false</SDLCheck>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(LIBCONFIG_ROOT)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies Condition="'$(PlatformToolset)'=='v142'">libconfig++.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>
然後在Visual Studio右上角的小視窗中,切換到Property Manager
頁面:
在Release | x64
上右鍵,選擇Add Existing Property Sheet...
,將剛剛建立的libconfig.props
加入即可。
dll檔
在link時會需要用到libconfig.dll
或libconfig++.dll
這兩個檔案,要把它們從C:\src\vcpkg\installed\x64-windows\bin
複製到<Visual_Studio_Project_Directory>\x64\Release
下面。
(後來發現不必做這一步libconfig.dll
及libconfig++.dll
也會自動被複製到該目錄底下?)
至此libconfig
已經配置完成,可以來跑跑看簡單的範例程式了。
範例程式
以下是一個簡單的C++範例程式,用於從config.txt
中讀取鍵值對。
其中要注意的是,對於C++,應該include libconfig.h++
;如果是用C語言,則應include libconfig.h
。
#include <iostream>
#include <iomanip>
#include <libconfig.h++>
int main(int argc, char** argv) {
libconfig::Config cfg;
cfg.readFile("config.txt");
std::cout << "==============================" << std::endl;
std::cout << "configs: " << std::endl;
const libconfig::Setting& root = cfg.getRoot();
for (libconfig::SettingConstIterator it = root.begin(); it != root.end(); ++it) {
switch (it->getType()) {
case libconfig::Setting::TypeInt: {
int val = root.lookup(it->getName());
std::cout << std::setw(25) << it->getName() << std::setw(20) << " (TypeInt) : " << val << std::endl;
break;
}
case libconfig::Setting::TypeInt64: {
long long val = root.lookup(it->getName());
std::cout << std::setw(25) << it->getName() << std::setw(20) << " (TypeInt64) : " << val << std::endl;
break;
}
case libconfig::Setting::TypeFloat: {
float val = root.lookup(it->getName());
std::cout << std::setw(25) << it->getName() << std::setw(20) << " (TypeFloat) : " << val << std::endl;
break;
}
case libconfig::Setting::TypeString: {
std::string val = root.lookup(it->getName());
std::cout << std::setw(25) << it->getName() << std::setw(20) << " (TypeString) : " << val << std::endl;
break;
}
case libconfig::Setting::TypeBoolean: {
bool val = root.lookup(it->getName());
std::cout << std::setw(25) << it->getName() << std::setw(20) << " (TypeBoolean) : " << (val ? "true" : "false") << std::endl;
break;
}
case libconfig::Setting::TypeGroup:
case libconfig::Setting::TypeArray:
case libconfig::Setting::TypeList:
std::cout << std::setw(25) << it->getName() << " (TypeGroup, TypeArray or TypeList)" << std::endl;
break;
default:
std::cout << std::setw(25) << it->getName() << " (None)" << std::endl;
}
}
}
以下是config.txt
:
mybool = true;
myint = 123;
myfloat = 3.14;
mystring = "abc";
其執行結果為:
==============================
configs:
mybool (TypeBoolean) : true
myint (TypeInt) : 123
myfloat (TypeFloat) : 3.14
mystring (TypeString) : abc
==============================
參考連結
LNK2019: Unresolved external symbol __declspec(dllimport)