MySQL 라이브러리 사용시 config.h 파일 문제

리눅스에서 빌드시 다음과 같은 오류가 있었다.

In file included from /root/DServer2/src/dserver/protocol/../../dserver/database.h:6:0,
from /root/DServer2/src/dserver/protocol/../../dserver/define.h:41,
from /root/DServer2/src/dserver/protocol/base_protocol.h:3,
from /root/DServer2/src/dserver/protocol/base_protocol.cpp:1:
/root/Library/mysql-connector-c++-1.1.9/cppconn/resultset.h:30:20: fatal error: config.h: 그런 파일이나 디렉터리가 없습니다
#include "config.h"
^

config.h 파일이 없다는 에러 메시지인데 cppconn 디렉토리를 살펴보면 config.h.cm 파일이 있다.

mysql 커넥터를 다운 받은 디렉토리로 가서 cmake를 실행한다. 실행이 되지 않는다면 yum 으로 cmake를 설치한다.

[root@localhost Library]# cmake mysql-connector-c++-1.1.9
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Could NOT find Boost
-- Could NOT find Boost
CMake Error at CMakeLists.txt:194 (MESSAGE):
Boost or some of its libraries found. If not in standard place please set
-DBOOST_ROOT:STRING=


-- Configuring incomplete, errors occurred!
See also "/root/Library/CMakeFiles/CMakeOutput.log".
[root@localhost Library]#

https://dev.mysql.com/doc/connector-cpp/en/connector-cpp-installation-source-unix.html 를 참조했다.

https://dev.mysql.com/doc/connector-cpp/en/connector-cpp-source-configuration-options.html 를 읽어봤더니 BOOST 경로를 설정해줘야한다.

/etc/profile 에 BOOST_ROOT 경로를 지정한다.

export BOOST_ROOT=/부스트경로/

다시 cmake를 실행했다.

[root@localhost mysql-connector-c++-1.1.9]# cmake .
-- Boost version: 1.65.1
-- BOOST_INCLUDE_DIRS=/root/Library/boost_1_65_1
-- You will link dynamically to the MySQL client library (set with -DMYSQLCLIENT_STATIC_LINKING=<bool>)
-- Searching for dynamic libraries with the base name(s) "mysqlclient_r mysqlclient"
CMake Error at FindMySQL.cmake:531 (message):
Could not find "mysql.h" from searching "/usr/include/mysql
/usr/local/include/mysql /opt/mysql/mysql/include
/opt/mysql/mysql/include/mysql /usr/local/mysql/include
/usr/local/mysql/include/mysql /MySQL/*/include /MySQL/*/include"
Call Stack (most recent call first):
CMakeLists.txt:252 (INCLUDE)


-- Configuring incomplete, errors occurred!
See also "/root/Library/mysql-connector-c++-1.1.9/CMakeFiles/CMakeOutput.log".
[root@localhost mysql-connector-c++-1.1.9]#

mysql 라이브러리 파일이 있어야한다고 나온다. CentOS 7에서는 MySQL이 빠지고 그대신 MariaDB가 들어가 있기 때문에 mariadb-libs 와 mariadb-devel 을 yum으로 설치해준다.

다시 cmake 하니…

[root@localhost mysql-connector-c++-1.1.9]# cmake .
-- Boost version: 1.65.1
-- BOOST_INCLUDE_DIRS=/root/Library/boost_1_65_1
-- You will link dynamically to the MySQL client library (set with -DMYSQLCLIENT_STATIC_LINKING=<bool>)
-- Searching for dynamic libraries with the base name(s) "mysqlclient_r mysqlclient"
-- mysql_config was found /usr/bin/mysql_config
-- MySQL client environment/cmake variables set that the user can override
--   MYSQL_DIR                   :
--   MYSQL_INCLUDE_DIR           : /usr/include/mysql
--   MYSQL_LIB_DIR               : /usr/lib64/mysql
--   MYSQL_CONFIG_EXECUTABLE     : /usr/bin/mysql_config
--   MYSQL_CXX_LINKAGE           :
--   MYSQL_CFLAGS                : -I/usr/include/mysql
--   MYSQL_CXXFLAGS              : -I/usr/include/mysql

(...중략...)

-- Configuring performance test - statement
-- Configuring bugs test cases - unsorted
-- Configuring unit tests - group template_bug
-- Configuring done
CMake Warning (dev) in driver/CMakeLists.txt:
  Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
  interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
  cmake_policy command to set the policy and suppress this warning.

  Target "mysqlcppconn" has an INTERFACE_LINK_LIBRARIES property which
  differs from its LINK_INTERFACE_LIBRARIES properties.

  INTERFACE_LINK_LIBRARIES:

    mysqlclient;pthread;z;m;ssl;crypto;dl

  LINK_INTERFACE_LIBRARIES:



This warning is for project developers.  Use -Wno-dev to suppress it.

-- Generating done
-- Build files have been written to: /root/Library/mysql-connector-c++-1.1.9
[root@localhost mysql-connector-c++-1.1.9]#

이제서야 완료. config.h 파일이 정상적으로 생성되었다.

boost::property_tree의 위험성

.ini 파일을 파싱하기 위해 boost::property_tree 클래스를 사용했었다.

서버의 성능을 테스트하던 도중 어디사 CPU를 많이 잡아먹나 계속 테스트했는데 네트워크 전송 부분이 계속 문제였다. 아무리 수정을 해도 고쳐지지 않는 상황. 비주얼스튜디오의 성능프로파일러를 돌려보니 boost::property_tree 가 문제의 원인이었다. 환경설정에서 특정한 값을 가져오기 위해 쓰느 코드가 네트워크 속도를 느리게 만드는데 기여하고 있었다.

이 부분을 수정하고나니 CPU 점유율이 아주 낮아졌다.

boost를 마구 쓰면 안된다는걸 깨닫게되었네.

boost에서 메모리풀 사용

프로그램 구현 중 메모리풀이 필요한 경우가 있어 어떻게 할까 하다가 boost의 메모리풀을 찾아보게 되었다.

boost의 메모리풀은 4가지.

  1. pool
  2. singleton_pool
  3. pool_alloc
  4. object_pool

네가지 메모리풀 중에 어떤 것이 어떤 상황에 가장 적합한지는 많이 써봐야 알 수 있을듯하다. 찾아보니 내가 가지고 있던 몇몇 게임서버 소스는 singleton_pool을 사용하고 있는 케이스가 있었다. 이것부터 먼저 찾아보는 것으로.

singleton_pool은 다른 메모리풀 클래스들과는 다르게 스레드-세이프 특성을 지니고 있어서 가장 유용하게 쓰일 것 같다.

singleton_pool을 아래와 같은 코드로 좀더 편하게 사용 가능. 출처는 ‘아지크의 좌충우돌 IT 이야기’

#include <stdio.h>
#include <iostream>
#include <vector>
#include <boost/pool/singleton_pool.hpp>
#include <boost/pool/pool_alloc.hpp>


template<typename T,  unsigned int NEXT_SIZE = 32U, unsigned int  MAX_POOL_SIZE = 0U>
class CMemoryPoolT
{
public:
     static void* operator new(size_t size)
     {
          return boost::singleton_pool<T,
               sizeof(T),
               boost::default_user_allocator_new_delete,
               boost::details::pool::default_mutex,
               NEXT_SIZE,
               MAX_POOL_SIZE>::malloc();
     }

     static void operator delete(void* p)
     {
          boost::singleton_pool<T,
               sizeof(T),
               boost::default_user_allocator_new_delete,
               boost::details::pool::default_mutex,
               NEXT_SIZE,
               MAX_POOL_SIZE>::free(p);
     }
};


class CMemoryPoolTest  :public CMemoryPoolT<CMemoryPoolTest>
{
public:
     char Dumy[124] ;
};


int _tmain(int argc, _TCHAR* argv[])
{
     using std::vector ;

     CMemoryPoolTest *p = new CMemoryPoolTest() ;

     delete p ;

     printf("Using MemoryPool... \n") ;


     return 0;
}

프로그램 종료시에는 purge_memory()를 꼭 호출해주어야 한다고 한다.

혹은 다음과 같은 방법으로도 사용 가능하다.

struct SEND_BUFFER_TAG {};
typedef boost::singleton_pool<SEND_BUFFER_TAG, SEND_BUFFER_SIZE> SendBufferPool;

사용할 클래스의 헤더파일에서 위와 같이 선언. TAG를 여러개 사용하고 메모리풀마다 다르게 적용하면 서로 다른 메모리풀이 된다.

메모리를 할당 받고 싶다면,

char* send_data = static_cast<char*>(SendBufferPool::malloc()); // 메모리를 할당 받는다.

SendBufferPool::free(send_data); // 다 사용한 메모리를 해제한다.

종료시에는 당연히,

SendBufferPool::purge_memory();

를 호출해야한다.

출처와 참고사이트

 

윈도우에서 C++ Boost 사용하기

윈도우에서 C++ 작업시 유용한 Boost 라이브러리를 사용하기 위해서는 빌드를 해야한다. 파일시스템 등을 다루는 등의 운영체제에 의존하는 기능들을 사용하기 위해 빌드해야한다고 한다.

  1. http://www.boost.org 에 들어가서 Boost를 다운 받는다.
  2. 압축을 풀고 디렉토리에 들어가 bootstrap.bat 를 실행한다.
  3. b2 –help 를 실행해서 한번 도움말을 쭉 읽어본다.
  4. 윈도우 커맨드창을 열고 해당 다음의 명령을 입력하여 빌드를 시작한다. 64비트, 디버그/릴리즈 모두, 멀티쓰레드, MPI 사용 안함으로 빌드한다.
  5. b2 variant=debug,release link=static,shared threading=multi address-model=64 –without-mpi -j8 stage
  6. 빌드 옵션은 여러가지가 더 있다. 찾아봐서 자기가 필요한대로 설정한다.
  7. -j8은 몇개의 작업을 동시에 하는지를 결정한다. 4코어인 경우에는 -j4를 해주면 모든 코어를 다 사용하게 된다. 적당하게 설정하는 것이 좋다.

빌드에는 시간이 꽤 걸린다.

다음의 링크를 참조했다.