Bonobo - Simple git server for Windows

- Git 서버를 윈도우즈 환경에서 운영하기 위한 플랫폼 

- IIS 7 이상, .NET Framework 4.5, ASP.NET MVC 4 환경 



# 설치 

- IIS 설치 : Windows 7 이상이면 "프로그램 및 기능" - "Windows 기능 겨키/끄기" 에서 설치 가능 

  * 응용 프로그램 개발 기능에서 .NET 4.5 확장성 및 ASP.NET 4.5 활성화 

- .NET Framework 4.5 설치 (Windows 8.1 이상은 이미 설치 됨) 

   https://www.microsoft.com/ko-KR/download/details.aspx?id=30653

- ASP.NET MVC 4 (http://www.asp.net/mvc/mvc4)


- Bonobo Git Server 다운로드 후, 압축을 풀고 해당 디렉토리를 IIS 응용프로그램으로 가상디렉토리 설정 

- 해당 디렉토리를 IIS 계정 (IIS_IUSER) 쓰기 권한 부여 

- 필요하다면 ASP.NET의 IIS 등록 

  (관리자 권한 : %windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -ir )


Github : https://github.com/philsquared/Catch

Tutorial : https://github.com/philsquared/Catch/blob/master/docs/tutorial.md


# 특징

- CppUnit, Google Test, Boost.Test 등등 다른 프레임웍크에 비해 의존성이 없는 헤더파일(catch.hpp) 하나면 사용 할 수 있음 

  * C++ Test Framework 비교 

- 별도 빌드 모듈로 운영 할 수도 있음

- 크로스 플랫폼 지원


# 사용 

- TEST_CASE 라는 기본 단위 테스트에 SECTION이라는 작은 부분으로 나누어서 테스트 할 수 있음

- 기본적으로 REQUIRE 와 CHECK 의 평가식을 이용하여 로직 검증. 

- REQUIRE 와 CHECK 차이점은, REQUIRE는 평가 실패 시 진행을 중지하고 다음 SECTION 이나 TEST_CASE 로 이동하는 반면, CHECK는 평가 결과와 관계없이 바로 다음 평가를 실행 

- REQUIRE_FALSE, CHECK_FALSE - 실패 평가 (NOT 조건)  

- REQUIRE_THROWS, CHECK_THROWS - 예외가 발생하면 성공 

- REQUIRE_NOTHROW, CHECK_NOTHROW - 예외가 발생하지 않으면 성공 

- INFO, WARN, FAILD - 각 실패 단계에 따른 메세지 출력

- CAPTURE - 주어진 식과 값 출력 (테스트 실패시 노출)

#define CATCH_CONFIG_MAIN - 메인함수 자동으로 생성 및 실행 


# 결론

- 진입장벽 낮으며 사용하기 편리하고 다른 테스트 프레임워크 만큼 많은 기능 제공하는듯

- 살짝 아쉬운점은 출력이 좀더 반듯? 하게 나왔으면 하는 생각. 


# 예제

 
#include <iostream>
#include <string>
#include <memory>
using namespace std;
 
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
 
TEST_CASE("std::string", "test")
{
string s = "abcedf";
 
REQUIRE(s.capacity() > 0);
 
SECTION("TEST 1") {
REQUIRE(s.length() > 0);
REQUIRE(s[0] == 'a');
string ss(move(s));
CAPTURE(ss);
 
CAPTURE(s.capacity());
REQUIRE(s.capacity() == 0); // FAILED
REQUIRE(ss.length() > 0);
}
 
s = "ab";
 
SECTION("TEST 2") {
REQUIRE_THROWS([]{ throw "error"; }());
REQUIRE_THROWS(s.at(5) = 'e');
REQUIRE_NOTHROW(s.at(0) = 's');
 
}
}
 
 
TEST_CASE("std::shared_ptr", "test")
{
auto sp = std::make_shared<string>("init");
CHECK(sp);
 
auto sp2 = sp;
CHECK(sp.use_count() == 2);
 
weak_ptr<string> wp = sp;
CHECK(sp.use_count() == 2);
 
SECTION("WeakPtr 1") {
auto spp = wp.lock();
CAPTURE(sp.use_count());
CAPTURE(spp.use_count());
CHECK(spp.use_count() == 3);
}
 
sp.reset();
sp2.reset();
 
SECTION("WeakPtr 2") {
auto spp = wp.lock();
CAPTURE(sp.use_count());
CAPTURE(spp.use_count());
CHECK(spp); // FAILED
}



# 결과




'Dev > C++' 카테고리의 다른 글

cdecl/asb 개발 중..  (0) 2015.04.01
cdecl/asb - Http benchmarking and load test tool for windows, posix  (0) 2015.03.18
C++ REST SDK (casablanca) 간단 샘플  (0) 2015.02.17
[C++11] Variadic template  (0) 2014.11.02
boost 설치  (0) 2013.11.20

2021년 신규 작성 

C++ REST SDK(cpprestsdk) Sample

 

C++ REST SDK(cpprestsdk) Sample

Introduction https://github.com/Microsoft/cpprestsdk Microsoft에서 만든 클라이언트, 서버용 C++ HTTP 통신 모듈이며, JSON URI, 비동기, 웹소켓, oAuth 등을 지원 C++11의 비동기, 병렬 프로그램 모델 지원 크로스 플랫

cdecl.github.io

--

 

https://casablanca.codeplex.com/

 

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

 

What's in the SDK:

  • Features - HTTP client/server, JSON, URI, asynchronous streams, WebSockets client, oAuth
  • PPL Tasks - A powerful model for composing asynchronous operations based on C++ 11 features
  • Platforms - Windows desktop, Windows Store, Windows Phone, Ubuntu, OS X, iOS, and Android
  • Support for Visual Studio 2012, 2013, and 2015 with debugger visualizers
  • NuGet package with binaries for Windows and Android platforms

 

- Microsoft에서 만든 클라이언트, 서버용 C++ HTTP 통신 모듈이며, JSON URI, 비동기, 웹소켓, oAuth 등을 지원 

- C++11의 비동기, 병렬 프로그램 모델 지원

- 크로스 플랫폼 지원 등..

- XML 파서도 지원 해줬으면 하는 아쉬움이...

 

 

# 설치방법

https://casablanca.codeplex.com/documentation

- openssl 및 boost 라이브러리 필요 

- 리눅스(g++)는 소스를 다운 받아 CMake를 이용하여 make 파일 생성, 빌드 및 설치 

  ** 설치시 Release/include/cpprest/details/http_constants.dat 파일이 누락이 되어 수동으로 복사 해줌 (Ubuntu 14.04)

- 윈도우(VC++)는 프로젝트 파일 포함, VS로 열어서 컴파일 하면 됨. 

  그러나 그냥 Nuget 패키지로 설치하면 바이너리와 include 파일을 쉽게 받음.

- 기본적으로 동적 링크(dll, so) 파일로 생성 

 

 

# 간단 예제 소스 

- U("") 는 _T("") 와 비슷한, UNICODE 및 MBCS 환경의 문자열 타입을 스위칭 해주는 매크로. 

  허나 U는 _T와는 다르게 _WIN32 환경이면 기본으로 _UTF16_STRINGS으로 정의되어 있어 프로젝트의 문자집합의 세팅과 관계 없이 UNICODE와 같은 환경으로 동작 

  리눅스 환경에서는 다른 설정을 해주지 않는 이상 char, std::string으로 정의 

utility::string_t은 std::string과 std::wstring을 스위칭 해주는 타입 

- 대체적인 패턴은, 동기는 .get(), 비동기는 then().wait() 조합으로 사용

 

 

#include <iostream>
using namespace std;
 
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
#pragma comment(lib, "cpprest120_2_4") // windows only
using namespace utility; // Common utilities like string conversions
using namespace web; // Common features like URIs.
using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams
 
 
void GetHttp()
{
http_client client(U("http://en.cppreference.com/w/"));
auto resp = client.request(U("GET")).get();
 
wcout << U("STATUS : ") << resp.status_code() << endl;
wcout << "content-type : " << resp.headers().content_type() << endl;
wcout << resp.extract_string(true).get() << endl;
}
 
void GetHttpAsync()
{
http_client client(U("http://en.cppreference.com/w/"));
 
client.request(U("GET")).then([](http_response resp){
wcout << U("STATUS : ") << resp.status_code() << endl;
wcout << "content-type : " << resp.headers().content_type() << endl;
 
resp.extract_string(true).then([](string_t sBoby){
wcout << sBoby << endl;
}).wait();
 
}).wait();
 
}
 
 
void GetJson()
{
http_client client(U("http://date.jsontest.com/"));
 
http_request req(methods::GET);
 
client.request(req).then([=](http_response r){
wcout << U("STATUS : ") << r.status_code() << endl;
wcout << "content-type : " << r.headers().content_type() << endl;
 
//{
// "time": "11:25:23 AM",
// "milliseconds_since_epoch" : 1423999523092,
// "date" : "02-15-2015"
//}
 
r.extract_json(true).then([](json::value v) {
wcout << v.at(U("date")).as_string() << endl;
wcout << v.at(U("time")).as_string() << endl;
}).wait();
 
}).wait();
 
}
 
int main(int argc, char* argv[])
{
wcout.imbue(locale("kor")); // windows only
 
GetHttp();
GetHttpAsync();
GetJson();
 
return 0

}

 

 

# Variadic template
  - template 에서 타입의 인자를 가변으로 처리 할 수 있는, 새로운 ... 표현식이이 생겼다 

  - http://en.wikipedia.org/wiki/Variadic_template 


  - 그리고 또 다른 설명인 MSDN의 링크 
     
http://msdn.microsoft.com/ko-kr/library/dn439779.aspx

variadic 템플릿 함수를 통합하는 대부분의 구현은 일부 양식의 재귀를 사용하지만 전통적인 재귀와는 약간 다릅니다. 전통적인 재귀는 같은 서명을 사용하여 자신을 호출하는 함수를 포함합니다. (오버로드하거나 템플릿화할 수 있지만 매번 동일한 시그너처가 선택됩니다.) Variadic 재귀에는 다른 수의 인수(거의 항상 줄어듦)를 사용하여 variadic 함수 템플릿을 호출하는 작업이 포함되므로 매번 다른 서명을 사용하지 않게 됩니다. "기본 사례"는 여전히 필요하지만 재귀적 특성은 다릅니다.

그렇다 대부분 재귀로 구현을 하게끔 되어 있고, 메타 프로그램의 기법과 같다.


  - template <typename...Ty> 라는 형식으로 사용 되며 이렇게 사용된 형식은 가변적으로(0~N개) 파라미터를 받아 드릴수 있다

  - 이렇게 받은 파라미터는 재귀함수 형식으로 다시 자기 함수를 호출 (Ty...var) 하게 되며, 파라미터가 앞에서 부터 하나씩 제거 되는 형식으로 다음 함수에 전달 되게 된다

  - 그리고 마지막 end 조건되 되는 별도의 비가변 template 함수를 호출함으로서 종료 되게 끔 동작 함 

 

# 예제 
  - 첫번째로 만들어 본 예제는 vector에 모들 가변 파라미터를 넣어 보는것
  - 재귀 개념으로 실행 되며 마지막에 실행 되는 end 역활로 비가변 템플릿 함수가 실행 되고 끝냄
  - vector의 성능 향상을 위해 C++11 에 포함된 rvalue 레퍼런스를 이용한 move semantics 를 사용하고 마지막 조건 부터 역으로 push 되는 방식을 사용하여 데이터가 template 전달 역순으로 배열 됨.

  - 정상적인 순으로 받아드리게 할려면 별도의 파라미터 vector<T> 로 받아서 넣게 하면 될듯.

  - vector를 사용하여 구조상 한개의 타입으로 한정 지을 수 밖에(다른 타입을 대입하면 vector에서 에러 분출..) 없지만 variant 타입을 사용 한다면 문제가 없고, C++11의 구현으로 실제 std::tuple의 경우 Variadic template으로 구현 되어 있음 


#include <iostream> #include <vector> #include <string> using namespace std; template <typename Ty> vector<Ty> MakeVector(const Ty& p) { vector<Ty> v; v.push_back(p); return std::move(v); } template <typename Ty, typename...VARS> vector<Ty> MakeVector(const Ty& p, VARS...vs) { vector<Ty> v = MakeVector(vs...); v.push_back(p); return std::move(v); } int main() { auto v = MakeVector(1, 3, 5, 7, 9, 11, 13); for (int &n : v) { cout << n << endl; } }


# 결과 (재귀의 역순으로 push 를 해서 역으로 결과가 나옴)

13
11
9
7
5
3
1





# 응용
  - C++에서 COM 을 사용하기 위한 방법 중, 디스패치 인터페이스를 사용하기 위해서는 약간의 수고가 필요한데 그것을 좀 더 편하게 사용하게 사용하기 위한 클래스를 만든 적이 있다. 그 클래스는 동적인 파라미터를 처리하기 위해 40개의 오버로딩으로 처리한 이력이 있음. ( 이것 때문이었을까?, VB 6 의 경우 파라미터 개수가 30개가 MAX 인듯)
  - 물론 printf 류 함수에서 사용하는 것을 사용 할 수 있지만, 이것은 타입을 정확히 알아야 하고 안정성 측면에 보장 살 수가 없음.
  - 기존 구현은 ATL의 _variant_t 를 사용하여 40개의 오버로딩 까지 구현 했으나, C++11 을 새로운 기능인 Variadic template을 이용하여 2개 오버로딩으로 끝냄.

  - _variant_t 특성상 여러 타입을 대입 할 수 있어 vector<_variant_t> 가 템플릿 가변 인수를 처리 할 수 있음


# COMDispatchV.h


// COMDispatch.h: interface for the IDispatch class.
//////////////////////////////////////////////////////////////////////
 
#ifndef _DISPATCH_H_20011012_BY_CDECL_
#define _DISPATCH_H_20011012_BY_CDECL_
 
#include <comdef.h>
#include <vector>
 
 
#define BYREF(x) GLASS::COMDispatch::ToRefParam((x))
 
namespace GLASS {
 
 
class COMDispatch
{
public:
typedef std::vector<_variant_t> vec_param;
typedef _variant_t PT;
 
// Proxy Class
class Proxy
{
public:
void SetParent(COMDispatch *p) { pDisp_ = p; }
void SetPropName(const _bstr_t &bstrName) { bstrName_ = bstrName; }
 
_variant_t operator=(const _variant_t &var) const
{
pDisp_->PutProperty(bstrName_, var);
return var;
}
 
operator _variant_t() const {
return pDisp_->GetProperty(bstrName_);
}
 
_variant_t operator() ()
{
vec_param vecParams;
return pDisp_->Call(bstrName_, vecParams);
}
 
template <typename...VARS>
_variant_t operator() (VARS...param)
{
vec_param vecParams = Param(param...);
return pDisp_->Call(bstrName_, vecParams);
}
private:
 
template <typename Vartype>
vec_param Param(Vartype p)
{
vec_param v;
v.push_back(p);
 
return std::move(v);
}
 
template <typename Vartype, typename...VARS>
vec_param Param(Vartype p, VARS...vs)
{
vec_param v = Param(vs...);
v.push_back(p);
 
return std::move(v);
}
 
private:
COMDispatch *pDisp_;
_bstr_t bstrName_;
};
 
public:
COMDispatch() : spDispatch_(NULL) { proxy_.SetParent(this); }
COMDispatch(const COMDispatch &disp) : spDispatch_(disp.spDispatch_) { proxy_.SetParent(this); }
explicit COMDispatch(const _variant_t &var) : spDispatch_(var) { proxy_.SetParent(this); }
COMDispatch(const char *) = delete;
COMDispatch(const wchar_t *) = delete;
virtual ~COMDispatch() { Release(); }
 
COMDispatch& operator=(const COMDispatch &disp);
COMDispatch& operator=(const _variant_t &var);
 
public:
_variant_t Call(const _bstr_t &bstrMethodName, vec_param &vecParams);
 
void PutProperty(const _bstr_t &strPropName, const _variant_t &var, bool bRef = false);
_variant_t GetProperty(const _bstr_t &strPropName);
 
virtual Proxy& operator[](const _bstr_t &bstrPropName);
 
virtual void CreateObject(const _bstr_t &bstrProgID);
virtual void Release();
 
public:
virtual void GetIDsOfNames(const _bstr_t &bstrMethodName, DISPID &lDispID);
 
protected:
virtual void Invoke(const DISPID lDispID, vec_param &vecParams, _variant_t &varRetVal, 
const WORD wFlags = DISPATCH_METHOD);
 
public:
static _variant_t ToRefParam(_variant_t &var);
 
protected:
Proxy proxy_;
IDispatchPtr spDispatch_;
};
 
 
 
 
 
//////////////////////////////////////////////////////////////////////
// Dispatch implementation
 
COMDispatch& COMDispatch::operator=(const COMDispatch &disp)
{
if (this != &disp) {
spDispatch_ = disp.spDispatch_;
proxy_.SetParent(this);
}
 
return *this;
}
 
 
COMDispatch& COMDispatch::operator=(const _variant_t &var)
{
spDispatch_ = var;
proxy_.SetParent(this);
 
return *this;
}
 
void COMDispatch::Release()
{
if (spDispatch_ != NULL) {
spDispatch_.Release();
}
}
 
void COMDispatch::CreateObject(const _bstr_t &bstrProgID)
{
HRESULT hr = spDispatch_.CreateInstance((LPCSTR)bstrProgID);
 
if (FAILED(hr)) {
_com_raise_error(hr);
}
}
 
_variant_t COMDispatch::Call(const _bstr_t &bstrMethodName, vec_param &vecParams)
{
DISPID lDispID;
GetIDsOfNames(bstrMethodName, lDispID);
 
_variant_t varRetVal;
Invoke(lDispID, vecParams, varRetVal);
 
return varRetVal;
}
 
 
COMDispatch::Proxy& COMDispatch::operator[](const _bstr_t &bstrPropName)
{
proxy_.SetPropName(bstrPropName);
return proxy_;
}
 
 
void COMDispatch::PutProperty(const _bstr_t &strPropName, const _variant_t &var, bool bRef)
{
DISPID lDispID;
GetIDsOfNames(strPropName, lDispID);
 
vec_param vecParams;
vecParams.push_back(var);
 
_variant_t varRetVal;
Invoke(lDispID, vecParams, varRetVal, bRef ? DISPATCH_PROPERTYPUTREF : DISPATCH_PROPERTYPUT);
}
 
_variant_t COMDispatch::GetProperty(const _bstr_t &strPropName)
{
DISPID lDispID;
GetIDsOfNames(strPropName, lDispID);
 
vec_param vecParams;
 
_variant_t varRetVal;
Invoke(lDispID, vecParams, varRetVal, DISPATCH_PROPERTYGET);
 
return varRetVal;
}
 
 
void COMDispatch::GetIDsOfNames(const _bstr_t &bstrMethodName, DISPID &lDispID)
{
BSTR bstrMN = static_cast<BSTR>(bstrMethodName);
 
HRESULT hr = spDispatch_->GetIDsOfNames(IID_NULL, &bstrMN, 1, LOCALE_SYSTEM_DEFAULT, &lDispID);
 
if (FAILED(hr)) {
_com_raise_error(hr);
}
}
 
 
void COMDispatch::Invoke(const DISPID lDispID, vec_param &vecParams, _variant_t &varRetVal, const WORD wFlags)
{
DISPPARAMS dispparams = { 0 };
DISPID dsipid_put = DISPID_PROPERTYPUT;
 
if (DISPATCH_PROPERTYGET != wFlags) {
dispparams.cArgs = vecParams.size();
dispparams.rgvarg = (vecParams.size() == 0) ? NULL : &vecParams.front();
 
if ((DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF) & wFlags) {
dispparams.rgdispidNamedArgs = &dsipid_put;
dispparams.cNamedArgs = 1;
}
}
 
HRESULT hr = spDispatch_->Invoke(
lDispID,
IID_NULL,
LOCALE_USER_DEFAULT,
wFlags,
&dispparams,
DISPATCH_PROPERTYPUT == wFlags ? NULL : &varRetVal,
NULL,
NULL
);
 
if (FAILED(hr)) {
_com_raise_error(hr);
}
}
 
 
_variant_t COMDispatch::ToRefParam(_variant_t &var)
{
_variant_t varRet;
varRet.vt = VT_BYREF | VT_VARIANT;
varRet.pvarVal = &var;
 
return varRet;
}
 
 
} // end namespace
 
  

#endif // _DISPATCH_H_20011012_BY_CDECL_



# Mybatis 를 콘솔 어플리케이션 환경에서 테스트 

  - 한글소개 : http://mybatis.github.io/mybatis-3/ko/

  - 다운로드 : https://github.com/mybatis/mybatis-3/releases

  - SQL Server용 Microsoft JDBC Driver 4.0 : http://www.microsoft.com/ko-kr/download/details.aspx?id=11774



# mybatis.xml

  - mybatis 의 기본 설정 파일

  - 다중 DB 연결 관리(environment) 및 다중 매퍼파일 등록을 관리 

  - 다중 DB 연결 테스트를 위해 같은 DBMS의 DB 만 다른 설정 


<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="Glass"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="url" value="jdbc:sqlserver://localhost:1433;DatabaseName=Glass"/> <property name="username" value="user"/> <property name="password" value="pass"/> </dataSource> </environment> <environment id="SecureDB"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="url" value="jdbc:sqlserver://localhost:1433;DatabaseName=SecureDB"/> <property name="username" value="user"/> <property name="password" value="pass"/> </dataSource> </environment> </environments> <mappers> <mapper resource="net/cdecl/mapper.xml"/> <mapper resource="net/cdecl/mapper_securedb.xml"/> </mappers> </configuration>



# mapper.xml

  - 매퍼파일

  - 결과매핑 클래스에 대한 정의 및 각 쿼리 및 파라미터, 결과 타입에 대한 정의 

  - 다중 파라미터 및 매핑된 구조(이거 꽤 귀찮을 일 일듯;;) 형태로 결과를 받지 않는다면 HashMap 구조로 처리 가능

  - 각각의 쿼리는 select (혹은 update, delete) 엘러먼트의 id 로 선택을 하며, 디폴트의 경우 이름만 적어줘도 문제 없는듯 하나 mapper namespace 와 더불러 full 경로를 적어 주는 것이 문제가 없어 보임   


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
<mapper namespace="net.cdecl.CodeDAO">
  
    <resultMap id="result" type="net.cdecl.Code">
        <result property="code" column="code"/>
        <result property="codename" column="codename"/>   
    </resultMap>
 
    <select id="selectAll" resultMap="result">
        SELECT * FROM tCode;
    </select>
    
    <select id="select"  parameterType="String" resultMap="result">
        SELECT * FROM tCode Where code = #{code}
    </select>
    
    
    <select id="select2" parameterType="hashmap" resultMap="result">
        SELECT * 
        FROM tCode 
        Where code In ( #{s1} ) 
    </select>
    
    <select id="selectMap" resultType="hashmap">
        SELECT * FROM tCode;
    </select>
    
    
</mapper>



# mapper_securedb.xml

  - 다른 매퍼파일


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
<mapper namespace="net.cdecl">
  
    <select id="selectSHA256" parameterType="String" resultType="hashmap">
        select [dbo].[xfn_IntCrypt_SHA1_Encoding](#{in}) as sha1, [dbo].[xfn_IntCrypt_SHA256_Encoding](#{in}) as sha256
    </select>
    
</mapper>




# Code.java

  - tCode 테이블의 데이터 클래스


package net.cdecl;

public class Code {
    private String code;
    private String codename;

    /*
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getCodeName() {
        return codename;
    }

    public void setCodeName(String codename) {
        this.codename = codename;
    }
    */

    public String toString() {
        return "code: " + code + ", codename: " + codename;
    }
}


# CodeDAO.java

  - 매퍼 클래스와 매퍼 XML 구조를 매핑하는 Data Access Object 


package net.cdecl;

import java.util.ArrayList;
import java.util.Map;

import net.cdecl.*;

public interface CodeDAO {
 
    public ArrayList<Code> selectAll(); // 모든 행 가져오기
    public ArrayList<Code> select(String s);
    public ArrayList<Code> select2(Map<String, Object> m);

}




# MyBaApp.java 

  - 테스트 어플리케이션 


import java.io.IOException; import java.io.InputStream; import java.util.*; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.*; import net.cdecl.*; public class MyBaApp { public static void main(String[] args) { try (SqlSession session = GetSqlSession("Glass")) { session.getConfiguration().getMappedStatementNames(); Mybatis(); Mybatis_HashMap(); } catch (Exception e) { e.printStackTrace(); } } public static SqlSession GetSqlSession(String env) throws IOException { String resource = "net/cdecl/mybatis.xml"; SqlSessionFactory sp = null; try (InputStream inputStream = Resources.getResourceAsStream(resource)) { sp = new SqlSessionFactoryBuilder().build(inputStream, env); } return sp.openSession(); } public static void Mybatis_HashMap() { try (SqlSession session = GetSqlSession("SecureDB") ){ System.out.println("======== SHA256 DB조회"); List list = session.selectList("net.cdecl.selectSHA256", "abcedfg"); System.out.println(list); for (int i = 0; i < list.size(); ++i) { HashMap<String, Object> m = (HashMap<String, Object>)list.get(i); String s = String.format("abcedfg - SHA1 : %s, SHA256 : %s", m.get("sha1"), m.get("sha256")); System.out.println(s); } } catch (Exception ex) { ex.printStackTrace(); } } public static void Mybatis() { try (SqlSession session = GetSqlSession("Glass")) { CodeDAO code = session.getMapper(CodeDAO.class); System.out.println("======== 데이터 매핑 리턴 "); ArrayList<Code> Codes = code.selectAll(); for (Code c : Codes) { System.out.println(c.toString()); } System.out.println("======== 데이터 매핑 리턴, 다중 파라미터(HashMap) "); Map<String, Object> m = new HashMap<String, Object>(); m.put("s1", "0"); Codes = code.select2(m); for (Code c : Codes) { System.out.println(c.toString()); } System.out.println("======== List 리턴 List<HashMap<String, Object>> "); List list = session.selectList("net.cdecl.CodeDAO.selectMap"); System.out.println(list); for (int i = 0; i < list.size(); ++i) { m = (HashMap<String, Object>)list.get(i); String s = String.format("%s %s", m.get("Code"), m.get("CodeName")); System.out.println(s); } } catch (Exception ex) { ex.printStackTrace(); } } }



# 결과 
[select2, selectAll, selectSHA256, select, net.cdecl.CodeDAO.select, net.cdecl.CodeDAO.selectAll, net.cdecl.CodeDAO.select2, selectMap, net.cdecl.CodeDAO.selectMap, net.cdecl.selectSHA256]
======== 데이터 매핑 리턴 
code: 0, codename: zero
code: 1, codename: one
code: 2, codename: two
code: 3, codename: three
code: 4, codename: 4444
======== 데이터 매핑 리턴, 다중 파라미터(HashMap) 
code: 0, codename: zero
======== List 리턴 List<HashMap<String, Object>> 
[{CodeName=zero, Code=0}, {CodeName=one, Code=1}, {CodeName=two, Code=2}, {CodeName=three, Code=3}, {CodeName=4444, Code=4}]
0 zero
1 one
2 two
3 three
4 4444
======== SHA256 DB조회
[{sha1=470e2dac6d8e0b17412cceb91442659a9d561e02, sha256=34541528206d252e76bb2597687112b53aff7f70dd1da1d763dab4c59095bf89}]
abcedfg - SHA1 : 470e2dac6d8e0b17412cceb91442659a9d561e02, SHA256 : 34541528206d252e76bb2597687112b53aff7f70dd1da1d763dab4c59095bf89






'Dev > Java' 카테고리의 다른 글

JVM GC 모니터링(Tomcat), VisualVM 사용  (1) 2016.04.13

SHA1 해쉬 함수의 경우 crypto++ 라이브러리로 사용 가능 하지만, 간단히(?) boost 라이브러리도 가능.

http://www.cryptopp.com/



#include <iostream>
#include <string>
using namespace std;

#include <boost/uuid/sha1.hpp>
#include <boost/format.hpp>
 
 
string ToSHA1(const string s)
{
    boost::uuids::detail::sha1 sh;
    sh.process_bytes(s.c_str(), s.length());

    unsigned int digest[5];
    sh.get_digest(digest);

    string r;
    for(int i = 0; i < 5; ++i) {
        r += str(boost::format("%08x") % digest[i]);
    }

    return r;
}

int main()
{
    
    try {
        cout << ToSHA1("abcedfg") << endl;

    }
    catch (exception &e) {
        cout << e.what() << endl;
    }
    catch (...) {
        cout << "unknown error" << endl;
    }

    return 0;
}


'Dev > Encryption' 카테고리의 다른 글

디피-헬만 키 교환, C++ 예제  (0) 2014.10.17
디피-헬만 키 교환  (0) 2014.10.16
SSL 키 교환 방식  (0) 2014.10.15
해쉬 함수 SHA1CryptoServiceProvider, SHA1Managed 차이  (0) 2014.09.26
Crypto++ 사용하기, 예제  (2) 2009.10.14


# 큰수를 나타내기 위해 boost::multiprecision 의 cpp_int 클래스 이용
http://www.boost.org/doc/libs/1_56_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html


# 큰수를 나타내는 boost 지원 3개의 클래스 비교
http://www.boost.org/doc/libs/1_56_0/libs/multiprecision/doc/html/boost_multiprecision/tut/ints.html


# 소수 판별을 위한 boost::multiprecision 의 miller_rabin_test 함수 사용 


# 밀러 라빈 소수 판별법 
http://ko.wikipedia.org/wiki/%EB%B0%80%EB%9F%AC-%EB%9D%BC%EB%B9%88_%EC%86%8C%EC%88%98%ED%8C%90%EB%B3%84%EB%B2%95


# Random 클래스는 C++11의 표준을 사용함 



#include <iostream>
#include <algorithm>
#include <limits>
#include <random>
#include <sstream>
using namespace std;

#include <boost/format.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/miller_rabin.hpp>
namespace bmp = boost::multiprecision;
typedef bmp::cpp_int INT;


INT RND_INT(int bytes)
{
    random_device rd;   
    std::mt19937 rnd(rd());
    INT r;

    if (bytes < 8) {
        std::uniform_int_distribution<uint32_t> dist(1, numeric_limits<uint32_t>().max());
        r = dist(rnd);
    }
    else {
        std::uniform_int_distribution<uint64_t> dist(1, numeric_limits<uint64_t>().max());
        int loop = bytes / 8;

        for (int i = 0; i < loop; ++i) {
            r |= (INT(dist(rnd)) << (64 * i));
        }
    }

    return r;
}

INT RND_Prime(int bytes)
{
    INT r(0);

    for (int i = 0; i < 1024; ++i) {
        INT n = RND_INT(bytes);

        bool b = bmp::miller_rabin_test(n, 25);
        if (b) {
            r = n;
            cout << "find : " << i << ", prime nmber is " <<  endl;
            cout << str(boost::format("%X") % n) << endl << endl;
            break;
        }   
    }

    return r;
}



void DHC_TEST()
{
    INT P = RND_Prime(16);
    if (P == 0) {
        throw logic_error("DHC_TEST : prime number failed ");
    }
    const INT G = RND_INT(8);

    const INT privateA = RND_INT(8);
    const INT privateB = RND_INT(8);

    cout << "ali private : " << endl <<  str(boost::format("%X") % privateA) << endl;
    cout << "bob private : " << endl <<  str(boost::format("%X") % privateB) << endl;
    cout << endl;

    auto publicA = bmp::powm(G, privateA, P);       
    auto publicB = bmp::powm(G, privateB, P);

    cout << "ali public : " << endl <<  str(boost::format("%X") % publicA) << endl;
    cout << "bob public : " << endl <<  str(boost::format("%X") % publicB) << endl;
    cout << endl;

    cout << "ali block key : " << endl <<  str(boost::format("%032X") % bmp::powm(publicB, privateA, P)) << endl;
    cout << "bob block key : " << endl <<  str(boost::format("%032X") % bmp::powm(publicA, privateB, P)) << endl;

}


int main()
{
    
    try {
        DHC_TEST(); 
    }
    catch (exception &e) {
        cout << e.what() << endl;
    }
    catch (...) {
        cout << "unknown error" << endl;
    }

    return 0;
}


출처 : 위키백과 http://ko.wikipedia.org/wiki/%EB%94%94%ED%94%BC-%ED%97%AC%EB%A7%8C_%ED%82%A4_%EA%B5%90%ED%99%98


디피-헬만 키 교환

위키백과, 우리 모두의 백과사전.

디피-헬만 키 교환(Diffie–Hellman key exchange)은 암호 키를 교환하는 하나의 방법으로, 두 사람이 암호화되지 않은 통신망을 통해 공통의 비밀 키를 공유할 수 있도록 한다. 휫필드 디피와 마틴 헬만이 1976년에 발표하였다.

디피-헬만 키 교환은 기초적인 암호학적 통신 방법을 수립하였으며, 이후 1977년 공개 키 암호 방식인 RSA 암호가 제안되었다.

방식[편집]

앨리스와 밥이 공개된 통신망에서 디피-헬만 키 교환을 하기 위해서는 다음과 같은 절차를 거친다.

  1. 앨리스가 소수 p, 그리고 1부터 p-1까지의 정수 g를 선택하여 사전에 밥과 공유한다.
  2. 앨리스가 정수 a를 선택한다. 이 정수는 외부에 공개되지 않으며, 밥 또한 알 수 없다.
  3. 앨리스가 A = g^a \text{ mod }p, 즉 g^a를 p로 나눈 나머지를 계산한다.
  4. 밥이 마찬가지로 정수 b를 선택하여 B = g^b \text{ mod }p를 계산한다.
  5. 앨리스와 밥이 서로에게 A와 B를 전송한다.
  6. 앨리스가 B^a \text{ mod }p를, 밥이 A^b \text{ mod }p를 계산한다.

마지막 단계에서 B^a = (g^b)^a = g^{ab}A^b = (g^a)^b = g^{ab}이며 따라서 앨리스와 밥은 g^{ab} \text{ mod }p라는 공통의 비밀 키를 공유하게 된다.

앨리스와 밥 이외의 인물은 a와 b를 알 수 없으며, g, p, g^a \text{ mod }p, g^b \text{ mod }p를 알 수 있다.

예제[편집]

이 과정을 실제 숫자를 통해 예를 들면 다음과 같다. 여기서는 설명을 위해 작은 크기의 소수를 사용하지만, 실제 응용에서는 안전을 위해 10진수 수백~수천자리 크기의 큰 소수를 사용한다. 공개된 정보는 파란색으로, 비밀 정보는 붉은색 굵은 글씨로 표시하였다.

  1. 앨리스와 밥은 p=23g=5를 사용하기로 합의한다.
  2. 앨리스가 비밀 정보를 전송하기 위해 임의의 정수 a=6을 고른 후, 밥에게 A = ga mod p 을 전송한다.
    • A = 56 mod 23
    • A = 15,625 mod 23
    • A = 8
  3. 밥은 임의의 정수 b=15 를 고르고, 앨리스에게 B = gb mod p 를 전송한다.
    • B = 515 mod 23
    • B = 30,517,578,125 mod 23
    • B = 19
  4. 앨리스는 밥에게서 받은 B 를 바탕으로 s = B a mod p 를 계산한다.
    • s = 196 mod 23
    • s = 47,045,881 mod 23
    • s = 2
  5. 밥은 앨리스에게서 받은 A 를 바탕으로 s = A b mod p 를 계산한다.
    • s = 815 mod 23
    • s = 35,184,372,088,832 mod 23
    • s = 2
  6. 앨리스와 밥은 이제 비밀 키 s = 2 를 공유하게 되었다.

여기서 p가 충분히 클 경우, 외부에서 비밀 키를 알아내기 위해 도청을 하는 도청자 이브는 g^a나 g^b를 통해 s를 알아낼 수 없는 것으로 알려져 있다. 앨리스와 밥은 두 사람 만이 아는 비밀 키 s를 갖게 되었으므로, 대칭 키 암호를 이용해 이후의 통신을 암호화할 수 있다.

그러나 p나 ab가 너무 작을 경우, 도청자는 가능한 모든 조합을 다 계산해보는 방식으로 s를 계산해낼 수 있다. 따라서 실제 비밀 통신에는 충분히 큰 소수를 사용해야 한다. 만약 p가 최소 300자리의 소수이고, a와 b가 각각 100자리 이상의 정수일 경우, 현재 인류가 보유한 모든 컴퓨터를 동원해도 공개된 정보로부터 비밀 키를 알아낼 수 없는 것으로 알려져 있다.

안전성[편집]

디피-헬만 키 교환은 소수 p와 g를 적절하게 고르면 도청에 대해 안전한 것으로 알려져 있다. 도청자 이브가 비밀키를 얻어내기 위해서는 앨리스와  사이의 통신에서 도청할 수 있는 정보인 g^a와 g^b로부터 g^{ab}를 구해야 한다. 이 문제를 디피-헬만 문제(Diffie-Hellman problem)로 부르며, 이 문제를 푸는 효율적인 알고리즘은 2013년 현재 알려지지 않았다. 이산 로그 문제를 효율적으로 풀 수 있을 경우 디피-헬만 문제 또한 효율적으로 풀 수 있지만, 그 역이 참인지는 알려지지 않았다.

안전한 키 교환을 위해서는 p와 g를 신중하게 선택해야 한다. g는 순환군 G의 차수가 소수이거나, 인수분해하기 어려운 큰 소수를 약수로 갖도록 해야 한다. 이 때문에 p와 \frac{p-1}{2}이 모두 소수인 안전 소수를 고르기도 한다. p가 안전 소수일 경우 G의 차수는 2 또는 \frac{p-1}{2}만을 약수로 갖게 된다.

또한 앨리스와 밥이 충분히 안전하지 못한 난수 생성 알고리즘을 사용할 경우, 공격자는 이를 이용해 다음 a와 b의 특성을 어느정도 예측할 수 있다.

디피-헬만 키 교환은 통신을 하는 대상과 비밀 정보를 공유할 수 있지만, 상대방에 대한 인증은 보장되지 않으며 중간자 공격이 가능하다. 앨리스와 밥이 상대방에 대한 인증을 하지 못할 경우, 공격자는 중간에서 통신을 가로채 앨리스와 공격자, 그리고 공격자와 밥 사이에 각각 두 개의 디피 헬만 키 교환을 생성하고, 앨리스와 밥이 각각 서로와 통신을 하는 것처럼 위장할 수 있다. 이와 같은 종류의 중간자 공격을 막기 위한 여러가지 다른 알고리즘이 개발되어 있다.



출처 : http://eastdg.wordpress.com/2014/04/09/ssltls-%EA%B8%B0%EB%B3%B8/


Key Exchange (키 교환)

SSL/TLS이 사용할 수 있는 몇몇 키 알고리즘들이 있는데, 대부분의 키 알고리즘들은 서버의 공개키를 이용하여 동작한다. 다음은 많이 쓰이는 키 알고리즘 들이다.

  • RSA: 서버의 키…….유형이 RSA 형식인 경우 사용가능하다. 클라이언트는 46바이트의 랜덤 값과 2바이트 버전을 포함한 총 48바이트의 “pre-master secret” 값을 만들어 서버의 공개키로 암호화 하여 전송한다. 이러한 경우 ServerKeyExchange 과정은 없다.
  • DHE_RSA: 서버의 키 유형이 RSA 형식인 경우지만, 해당 키는 서명을 하는 경우에만 사용된다. 실제 키 교환은 Diffie-Hellman 알고리즘을 이용하여 교환하는데, 이 경우 서버는 DH 인자값들(modulus, generator)과 DH용 공개키를 포함한 ServerKeyExchange 메시지를 보낸다. (아직까진 이걸로 추천)
  • DHE_DSS: DHE_RSA 키 알고리즘과 유사하게 동작하지만 서버가 DSS 키를 가지고 있는 경우 사용된다. DSS는 DSA로도 알려져 있으며 서명에만 쓰인다.

다음은 보안상이나 기타 다른 이유로 잘 쓰이지 않는 키 알고리즘들이다.

  • DH: 서버의 키 유형이 Diffie-Hellman 유형인 경우 사용된다.
  • DH_anon: DHE와 비슷하지만 서버의 서명이 없다. 서버의 인증서 없이 동작되기 때문에 MITM 공격에 취약하다.
  • PSK: 키를 이미 기타 다른 방법으로 공유한 경우 사용되는 키 알고리즘이다.
  • SRP: application of the SRP protocol which is a Password Authenticated Key Exchange protocol. Client and certificate authenticate each other with regards to a shared secret, which can be a low-entropy password (whereas PSK requires a high-entropy shared secret). Very nifty. Not widely supported yet.
  • An ephermeral RSA key: DHE와 비슷하지만 RSA 키쌍을 생성한다. 그렇기 때문에 성능 부분에 대해 꽤 비싼 비용을 지불하며, 또 그렇게 매력적인 옵션은 아니다.
  • ECDH_ECDSA, ECDH_RSA, ECDHE_ECDSA, ECDHE_RSA, ECDH_anon: elliptic curves를 이용한 다양한 DH* 알고리즘들로서 가장 강력하며 추후 표준이 될 수도 있다. (ECDH_anon은 제외)

현 시점에서는 elliptic curves를 이용한 DH* 알고리즘을 지원하는 클라이언트가 그리 많지 않다. 그리고 대부분의 클라이언트가 RSA 또는 DHE_RSA를 지원하기 때문에 이 2개를 먼저 고려하게 될 것이다. 이 2개중 어느것이 더 괜찮냐고 물어본다면 DHE_RSA가 더 괜찮다. 이유인즉 RSA경우 만약에 공격자가 서버의 비밀키를 획득하게 된다면 이전의 모든 SSL/TLS 전문들을 다시 복호화 할 수 있기 때문이다. DHE_RSA인 경우에는 별도로 교환된 키로 암복호화 하기 때문에 이전의 SSL/TLS 전문들을 다시 복호화 하기는 힘들다.



SHA1CryptoServiceProvider는 윈도우의 CryptoAPI(CAPI)를 래핑한 unmanaged 구현체 이고,
SHA1Managed는 .NET으로 구현한 Managed 코드


SHA1Managed가 상대적으로 느리다고 하는데, 그 차이는 ms 단위의 속도를 중요시 하지 않는 업무라면 문제 없을 듯 하고,
자체 구현이라 이식성도 좋아 보임


물론 사용 가능 하다면 SHA1CryptoServiceProvider 쓰는것이 최선..



http://codeissue.com/issues/i34dda6deaad90a/difference-between-sha1-sha1cryptoserviceprovider-sha1managed-and-sha1cng


SHA1CryptoServiceProvider: this is wrapper for unmanaged CryptoAPI(CAPI). This is Federal Information Processing Standard (FIPS) certified.

SHA1Managed: this is complete implementation of SHA1 using managed code. This is fully managed but not FIPS certified and may be slower.




'Dev > Encryption' 카테고리의 다른 글

SHA1 해쉬함수, boost 라이브러리로 구현  (0) 2014.10.22
디피-헬만 키 교환, C++ 예제  (0) 2014.10.17
디피-헬만 키 교환  (0) 2014.10.16
SSL 키 교환 방식  (0) 2014.10.15
Crypto++ 사용하기, 예제  (2) 2009.10.14


출처 : http://blogs.msdn.com/b/distributedservices/archive/2012/01/16/how-to-configure-the-msdtc-service-to-listen-on-a-specific-rpc-server-port.aspx



My name is Steven Graves and I am a Senior Support Escalation Engineer on the Windows Core Team.  In this blog, I will discuss how to configure MSDTC to use a specific port on Windows Server 2012/2012R2 as this has slightly changed from the way it is configured in Windows Server 2008 R2 in order to prevent overlapping ports.  As a reference, here is the blog for Windows 2008 R2.

How to configure the MSDTC service to listen on a specific RPC server port
http://blogs.msdn.com/b/distributedservices/archive/2012/01/16/how-to-configure-the-msdtc-service-to-listen-on-a-specific-rpc-server-port.aspx

Scenario

There is a web server in a perimeter network and a standalone SQL Server (or Clustered SQL Server instance) on a backend production network and a firewall that separates the networks. MSDTC needs to be configured between the web server and backend SQL Server using a specific port in order to limit the ports opened on the firewall between the networks.

So as an example, we will configure MSDTC to use port 5000.

There are two things that need to be configured on the frontend web server to restrict the ports that MSDTC will use.

  • Configure the ports DCOM can use
  • Configure the specific port or ports for MSDTC to use

Steps

1. On the web server launch Dcomcnfg.exefrom the Run menu.

2. Expand Component Services, right click My Computer and select Properties

clip_image002

3. Select the Default Protocols tab

clip_image004

4. Click Properties button

clip_image006

5. Click Add

6. Type in the port range that is above the port MSDTC will use. In this case, I will use ports 5001-6000.

7. Click OK back to My Computer properties window and click OK.  Here is the key that is modified in the Registry for theephemeral ports.

clip_image008

8. Start Regedt32.exe

9. Locate HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC

10. Right click the MSDTC key, select New and DWord (32-bit) Value

11. Type ServerTcpPort for the key name

12. Right click ServerTcpPort key and select Modify

13. Change radio button to Decimal and type 5000 in the value data, click OK.  This is how the registry key should look

clip_image010

14. Restart the MSDTC Service (if stand-alone) or take the MSDTC Resource offline/online in Failover Cluster Manager if clustered.

To confirm MSDTC is using the correct port:

  1. Open an Administrative command prompt and run Netstat –ano to get the port and the Process Identifier (PID)
  2. Start Task Manager and select Details tab
  3. Find MSDTC.exe and get the PID
  4. Review the output for the PID to show it is MSDTC

clip_image012

Now DTC will be using the port specified in the registry and no other processes will try to use the same port thus preventing an overlap of ports.

Steven Graves
Senior Support Escalation Engineer
Microsoft Core Support

'Dev > SQL' 카테고리의 다른 글

SQL Server CLR - 레지스트리 읽기  (0) 2008.10.10
CTE (Common Table Expression)  (0) 2008.07.08
테이블 변수  (0) 2008.07.04


<예제, boost::asio 필요 라이브러리 >

# msvc-14.0 : vc++ 2015

# msvc-12.0 : vc++ 2013

# 64bit : address-model=64

bjam.exe toolset=msvc-11.0 link=static runtime-link=static --with-system --with-date_time --with-regex --with-thread -j 4 stage






출처 : http://www.viper.pe.kr/cgi-bin/moin.cgi/Boost


3.1. bjam 사용법 [Bottom] [Top]

Boost 라이브러리는 대부분 Template 으로 구성되어 있다. 하지만 regex, thread 와 같이 빌드가 필요한 라이브러리를 포함하고 있다. bjam 은 이런 라이브러리들을 빌드와 설치를 자동화 해주기 위한 프로그램으로 직접 빌드해서 사용해도 되고 아래의 링크에서 다운받아서 사용해도 된다.

  • 다운로드 - http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941&release_id=643622

  • 사용법
    bjam [options] [properties] [install|stage]
    
  • Targets 과 관련 옵션 ([install|stage], [options])
    install
    헤더 파일과 빌드된 라이브러리 파일을 설치한다.
    --prefix=<PREFIX>

    플랫폼에 종속적이지 않은 파일(헤더 파일)을 설치할 경로를 지정한다. (기본값: [Win32] C:\Boost, [Unix계열] /usr/local)

    --exec-prefix=<EPREFIX>

    플랫폼에 종속적인 파일(바이너리 파일)을 설치할 경로를 지정한다. (기본값: <PREFIX>)

    --libdir=<DIR>

    라이브러리 파일을 설치할 경로를 지정한다. (기본값: <EPREFIX>/lib)

    --includedir=<HDRDIR>

    헤더 파일을 설치할 경로를 지정한다. (기본값: <PREFIX>/include)

    stage
    빌드된 라이브러리 파일만 설치한다.
    --stagedir=<STAGEDIR>

    라이브러리 파일을 설치할 경로를 지정한다. (기본값: ./stage)

  • 기타 옵션 ([options])
    --build-type=<type>
    미리 정의된 빌드 타입 중에서 빌드될 타입을 지정한다. 단, 각 라이브러리에서 지원하는 빌드 타입에 한해서 빌드 가능하다.
    minimal (기본값)

    - 릴리즈 모드(빌드 속성: "release <threading>multi <link>shared <link>static <runtime-link>shared")만 빌드한다.

    complete
    - 가능한 모든 타입(릴리즈/디버그, 정적/동적, 싱글/멀티 쓰레드 등)의 라이브러리를 빌드한다.
    --build-dir=DIR
    빌드 시 사용될 임시 디렉토리를 지정한다.
    --show-libraries
    빌드가 필요한 라이브러리를 보여준다.
    --layout=<layout>
    Boost 의 다양한 버전에 대한 라이브러리 파일 이름과 헤더 파일의 위치를 결정하거나 동일 시스템에서 여러 컴파일러를 사용할 경우 사용한다.
    versioned (기본값)

    - 라이브러리(바이너리) 파일의 이름에 버전, 라이브러리 이름, 컴파일러 버전을 포함한다. Boost 헤더 파일은 Boost 버전이 포함된 이름으로 생성된 <HDRDIR> 의 하위 디렉토리에 설치된다.

    system

    - 라이브러리(바이너리) 파일의 이름에 버전, 라이브러리 이름, 컴파일러 버전을 포함하지 않는다. Boost 헤더 파일은 <HDRDIR> 디렉토리에 설치된다. 이 옵션은 배포 패키지를 빌드하기 위하여 준비된 옵션이다.

    --buildid=ID
    빌드된 라이브러리 파일 이름에 지정된 ID 를 추가한다. 기본적으로는 어떤 것도 추가되지 않는다.
    --help
    도움말을 보여준다.
    --with-<library>
    지정된 라이브러리만 빌드 후 설치한다.
    --without-<library>
    지정된 라이브러리를 빌드하지 않는다. (기본값: 모든 라이브러리를 빌드한다.)
  • 빌드 속성 ([properties])
    toolset=toolset
    컴파일러를 지정한다. (VC++일 경우: msvc 사용)
    variant=debug|release
    릴리즈 또는 디버그 모드로 빌드할지 선택한다.
    link=static|shared
    정적 또는 동적(공유) 라이브러리로 빌드할지 선택한다.
    threading=single|multi
    멀티 쓰레드 지원 여부를 선택한다.
    runtime-link=static|shared
    C/C++ Runtime 라이브러리를 정적 또는 동적(공유) 라이브러리로 링크할지 선택한다.
  • 중요 옵션 ([options])
    --clean
    Targets 을 정리(제거)한다.
    -a
    라이브러리를 재빌드(Rebuild)한다.
    -n
    빌드 명령을 실행하지 않고, 출력만 한다.
    -d+2
    실행되는 빌드 명령을 출력한다.
    -d0
    빌드 메시지를 출력하지 않는다.
    -q
    에러 발생 시 작업 과정을 중지한다.
    --debug-generator
    빌드 과정과 명령을 상세히 출력한다.
    --debug-configuration
    환경 설정 사항(요구사항 검사)을 포함하여 빌드 과정과 명령을 상세히 출력한다.
    --debug-building
    Targets 의 빌드 속성을 포함하여 빌드 과정과 명령을 상세히 출력한다.
  • 빌드가 필요한 라이브러리 (--show-libraries 옵션으로 확인 가능)

    • date_time (./)

    • filesystem (./)

    • graph
    • graph_parallel
    • iostreams (./)

    • math
    • mpi
    • program_options (./)

    • python
    • random
    • regex
    • serialization
    • signals (./)

    • system (./)

    • test
    • thread (./)

    • wave

3.2. 라이브러리 네이밍(Library Naming) [Bottom] [Top]

For example, libboost_regex-vc71-mt-d-1_34.lib can be broken down into the following elements:

lib

Prefix: except on Microsoft Windows, every Boost library name begins with this string. On Windows, only ordinary static libraries use the lib prefix; import libraries and DLLs do not.

boost_regex

Library name: all boost library filenames begin with boost_.

-vc71

Toolset tag: identifies the toolset and version used to build the binary.

-mt

Threading tag: indicates that the library was built with multithreading support enabled. Libraries built without multithreading support can be identified by the absence of -mt.

-d

ABI tag: encodes details that affect the library's interoperability with other compiled code. For each such feature, a single letter is added to the tag:

  • Key

    Use this library when:

    s

    linking statically to the C++ standard library and compiler runtime support libraries.

    g

    using debug versions of the standard and runtime support libraries.

    y

    using a special debug build of Python.

    d

    building a debug version of your code.

    p

    using the STLPort standard library rather than the default one supplied with your compiler.

    n

    using STLPort's deprecated “native iostreams” feature.

    For example, if you build a debug version of your code for use with debug versions of the static runtime library and the STLPort standard library in “native iostreams” mode, the tag would be: -sgdpn. If none of the above apply, the ABI tag is ommitted.
-1_34

Version tag: the full Boost release number, with periods replaced by underscores. For example, version 1.31.1 would be tagged as "-1_31_1".

.lib

Extension: determined according to the operating system's usual convention. On most unix-style platforms the extensions are .a and .so for static libraries (archives) and shared libraries, respectively. On Windows, .dll indicates a shared library and .lib indicates a static or import library. Where supported by toolsets on unix variants, a full version extension is added (e.g. ".so.1.34") and a symbolic link to the library file, named without the trailing version number, will also be created.




'Dev > C++' 카테고리의 다른 글

C++ REST SDK (casablanca) 간단 샘플  (0) 2015.02.17
[C++11] Variadic template  (0) 2014.11.02
boost::asio 클라이언트 소켓 (timeout 기능)  (0) 2010.10.14
이미지 변환 모듈 (모바일용, GDI+)  (0) 2010.06.22
C++0x, RValue Reference  (0) 2009.05.27

+ Recent posts