• c++中如何利用VA_LIST 和单体模式,构建自己的log小系统


    目录

    一、日志小系统设计知识点

    二、日志小系统设计

    三、编译及展示

    四、完整代码目录:


            在前文“利用c语言中宏定义及宏替换特性构建自己的log输出_py_free的博客-CSDN博客”,利用宏定义及宏替换,可以实现日志信息屏幕输出,但通常我们在实际项目中:

            【1】需要将日志信息记录在文件中

            【2】日志记录顺序需要得到保证

            【3】日志信息是不确定的,需要支持到不确定参数集输入

            鉴于以上三点,来设计一个日志小系统

    一、日志小系统设计知识点

            在c/c++中VA_LIST是解决变参问题的一组宏,所在头文件:#include ,通常用法是:

            (1)首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针;
            (2)然后用VA_START宏初始化刚定义的VA_LIST变量;
            (3)然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型(如果函数有多个可变参数的,依次调用VA_ARG获取各个参数);
            (4)最后用VA_END宏结束可变参数的获取。

    1. void myprint(const char* lpszFormat, ...)
    2. {
    3. va_list args;
    4. char szBuffer[2048] = {0};
    5. va_start(args, lpszFormat);
    6. #ifdef WIN32
    7. vsnprintf_s(szBuffer,sizeof(szBuffer), lpszFormat, args);
    8. #else
    9. vsnprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    10. #endif
    11. va_end(args);
    12. //printf(szBuffer);
    13. }

             在c/c++中,单体实例实现主要就是将类的构造、拷贝构造函数等隐藏起来,使其仅在第一次实例化时可以创建实例,后续其每次实例化或使用时,仅提供或指向其第一次实例化创建的唯一实例指针。

    1. class SingleClass
    2. {
    3. public:
    4. static SingleClass* createInstance( void )
    5. {
    6. if (m_Instance== NULL)
    7. {
    8. m_Instance= new SingleClass();
    9. return m_Instance;
    10. }
    11. else
    12. return m_Instance;
    13. }
    14. private:
    15. SingleClass(){};
    16. ~SingleClass(){};
    17. private:
    18. static SingleClass* m_Instance;
    19. };

    二、日志小系统设计

            鉴于以上的要求,计划设计一个单体类CLogger,该类具备独立线程能力,采用一个队列来接收来自各个线程、各个功能模块的日志推送,CLogger实例负责将加入到队列的日志,添加一些附加信息后,逐条记录在文件中。

            为了区分日志事件,通过枚举创建日志类型;针对日志运行是一个长期的过程,不可能全部存储在一个日志文件中,因此指定一个文件目录,并按天来存放.

    1. log_test
    2. bin #编译目标输出目录
    3. build_win #win编译文件及中间文件目录
    4. build_linux #Linux编译文件及中间文件目录
    5. src #源码
    6. log.h #单体实例,继承自定义基类MyThread线程类
    7. log.cpp
    8. Mutex.h
    9. Mutex.cpp
    10. myThread.h #linux下线程类实现
    11. myThread.cpp
    12. win32Thread.h #win下线程类实现
    13. win32Thread.cpp
    14. CMakeLists.txt #cmake工程配置文件

    log.h:

    1. #ifndef CHANNELLOG_H
    2. #define CHANNELLOG_H
    3. #include
    4. #include
    5. #include
    6. #ifdef WIN32
    7. #include "win32Thread.h"
    8. #endif
    9. #ifdef linux
    10. #include "myThread.h"
    11. #include
    12. #endif
    13. #include
    14. #include "Mutex.h"
    15. enum eLogType
    16. {
    17. eHardError = 1,
    18. eSoftError = 2,
    19. eConfigError = 3,
    20. eParameterError = 4,
    21. eReadError = 5,
    22. eWriteError = 6,
    23. eControlMessage = 7,
    24. eResponseMessage = 8,
    25. eTipMessage = 9
    26. };
    27. struct MyLogStruct
    28. {
    29. MyLogStruct():type(0)
    30. {
    31. memset(szBuffer, 0, 1024);
    32. };
    33. int type;
    34. char szBuffer[1024];
    35. };
    36. class CLogger : public MyThread
    37. {
    38. public:
    39. void Log(const eLogType type, const char* lpszFormat, ...);
    40. static CLogger* createInstance( void );
    41. private:
    42. CLogger();
    43. ~CLogger();
    44. int Run();
    45. bool getFirstLog(MyLogStruct &it);
    46. void addLog(MyLogStruct it);
    47. private:
    48. static CLogger* m_pLogInstance;
    49. bool running;
    50. //for cache
    51. std::queue mylogs;
    52. PYMutex m_Mutex_Log;
    53. int i_log_over;
    54. };
    55. #endif

    log.cpp

    1. #include "Log.h"
    2. #include
    3. #include
    4. #ifdef __linux__
    5. #ifndef sprintf_s
    6. #define sprintf_s sprintf
    7. #endif
    8. #include
    9. #include
    10. #include
    11. #else
    12. #include
    13. #endif
    14. namespace GlobalVar
    15. {
    16. std::string logdir = "log"; //后期记录日志目录重配置文件读取
    17. std::string logname = "pyfree"; //可设置为服务名
    18. };
    19. CLogger* CLogger::m_pLogInstance = NULL;
    20. void WriteLogToFile( std::string strPath,std::string strTime,const char * strMsg)
    21. {
    22. FILE * fpLog = NULL;
    23. //open
    24. #ifdef WIN32
    25. fopen_s(&fpLog, strPath.c_str(), "a+");
    26. #else
    27. fpLog = fopen(strPath.c_str(), "a+");
    28. #endif
    29. if (NULL != fpLog)
    30. {
    31. fseek(fpLog, 0, SEEK_END);
    32. fwrite(strTime.c_str(), strTime.length(), 1, fpLog);
    33. fwrite(strMsg, strlen(strMsg), 1, fpLog);
    34. fwrite("\n", 1, 1, fpLog);
    35. fclose(fpLog);
    36. }
    37. }
    38. std::string createFileName(std::string strTime_)
    39. {
    40. //file name
    41. std::string strPath = GlobalVar::logdir;
    42. #ifdef WIN32
    43. strPath += "\\";
    44. #else
    45. strPath += "/";
    46. #endif
    47. strPath += strTime_;
    48. strPath += "_";
    49. strPath += GlobalVar::logname;
    50. strPath += ".log";
    51. return strPath;
    52. }
    53. std::string strTime()
    54. {
    55. time_t tt;
    56. struct timeb tm0;
    57. struct tm tm1;
    58. char buf[512];
    59. //time(&tt);
    60. ftime(&tm0);
    61. tt = tm0.time;
    62. #ifdef WIN32
    63. localtime_s(&tm1, &tt);
    64. #else
    65. localtime_r(&tt, &tm1);
    66. #endif
    67. sprintf_s(buf, "%04d-%02d-%02d %02d:%02d:%02d.%03d "
    68. , tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday
    69. , tm1.tm_hour, tm1.tm_min, tm1.tm_sec, tm0.millitm);
    70. std::string strTime_ = buf;
    71. buf[10] = '\0';
    72. return strTime_;
    73. }
    74. std::string createLogTimeAndTypeDesc(const int iMsgType, std::string strTime_)
    75. {
    76. std::string strTimeAndTypeDesc = strTime_;
    77. //
    78. switch (iMsgType)
    79. {
    80. case eHardError:
    81. strTimeAndTypeDesc += "[HardErrorIMsg] ";
    82. break;
    83. case eSoftError:
    84. strTimeAndTypeDesc += "[SoftErrorIMsg] ";
    85. break;
    86. case eConfigError:
    87. strTimeAndTypeDesc += "[ConfErrorIMsg] ";
    88. break;
    89. case eParameterError:
    90. strTimeAndTypeDesc += "[ParamErrorMsg] ";
    91. break;
    92. case eReadError:
    93. strTimeAndTypeDesc += "[ReadErrorIMsg] ";
    94. break;
    95. case eWriteError:
    96. strTimeAndTypeDesc += "[WriteErrorMsg] ";
    97. break;
    98. case eControlMessage:
    99. strTimeAndTypeDesc += "[ControlExeMsg] ";
    100. break;
    101. case eResponseMessage:
    102. strTimeAndTypeDesc += "[ResponseUpMsg] ";
    103. break;
    104. case eTipMessage:
    105. strTimeAndTypeDesc += "[NoticeTipIMsg] ";
    106. break;
    107. default:
    108. strTimeAndTypeDesc += "[PromptUnNoMsg] ";
    109. break;
    110. }
    111. return strTimeAndTypeDesc;
    112. }
    113. void WriteLog( const int iMsgType, const char * strMsg)
    114. {
    115. try {
    116. //system time to string
    117. std::string strTime_ = strTime();
    118. //file name
    119. std::string strPath = createFileName(strTime_.substr(0,10));
    120. // log time and type desc
    121. std::string strTimeAndTypeDesc = createLogTimeAndTypeDesc(iMsgType, strTime_);
    122. WriteLogToFile(strPath,strTimeAndTypeDesc,strMsg);
    123. }
    124. catch (...) {
    125. printf("write log[%d]{%s}error\n", iMsgType, strMsg);
    126. }
    127. }
    128. CLogger::CLogger()
    129. : running(true)
    130. , i_log_over(0)
    131. {
    132. char buf[256] = {0};
    133. sprintf_s(buf,"mkdir %s",GlobalVar::logdir.c_str());
    134. system(buf);
    135. this->start();
    136. };
    137. CLogger::~CLogger()
    138. {
    139. running = false;
    140. };
    141. CLogger* CLogger::createInstance( void )
    142. {
    143. if (m_pLogInstance == NULL)
    144. {
    145. m_pLogInstance = new CLogger();
    146. return m_pLogInstance;
    147. }
    148. else
    149. return m_pLogInstance;
    150. };
    151. int CLogger::Run()
    152. {
    153. MyLogStruct log_;
    154. while (running) {
    155. if (getFirstLog(log_))
    156. {
    157. WriteLog(log_.type, log_.szBuffer);
    158. #ifndef WIN32
    159. printf("Log::[%d]-->%s\n", getpid(), log_.szBuffer);
    160. #else
    161. printf("Log::-->%s\n", log_.szBuffer);
    162. #endif
    163. }
    164. #ifdef WIN32
    165. Sleep(10);
    166. #else
    167. usleep(10000);
    168. #endif
    169. }
    170. return 0;
    171. };
    172. void CLogger::Log(const eLogType type, const char* lpszFormat, ...)
    173. {
    174. va_list args;
    175. //char szBuffer[2048] = {0};
    176. MyLogStruct log_;
    177. log_.type = static_cast<int>(type);
    178. va_start(args, lpszFormat);
    179. #ifdef WIN32
    180. vsnprintf_s(log_.szBuffer,sizeof(log_.szBuffer), lpszFormat, args);
    181. #else
    182. vsnprintf(log_.szBuffer, sizeof(log_.szBuffer), lpszFormat, args);
    183. #endif
    184. va_end(args);
    185. addLog(log_);
    186. }
    187. bool CLogger::getFirstLog(MyLogStruct &it) {
    188. bool ret = false;
    189. m_Mutex_Log.Lock();
    190. if (!mylogs.empty()) {
    191. it = mylogs.front();
    192. mylogs.pop();
    193. ret = true;
    194. }
    195. m_Mutex_Log.Unlock();
    196. return ret;
    197. }
    198. void CLogger::addLog(MyLogStruct it) {
    199. m_Mutex_Log.Lock();
    200. if (mylogs.size() > 100) {
    201. i_log_over++;
    202. mylogs.pop();
    203. }
    204. mylogs.push(it);
    205. m_Mutex_Log.Unlock();
    206. if (i_log_over >= 100) {//每溢出100次,报告一次
    207. MyLogStruct log_;
    208. log_.type = static_cast<int>(eTipMessage);
    209. sprintf(log_.szBuffer,"the size of mylogs queue is up to limmit size[100],[%s %s %d]."
    210. , __FILE__, __FUNCTION__, __LINE__);
    211. m_Mutex_Log.Lock();
    212. mylogs.push(log_);
    213. m_Mutex_Log.Unlock();
    214. i_log_over = 0;
    215. }
    216. }

    Mutex.h

    1. #if _MSC_VER > 1000
    2. #pragma once
    3. #endif // _MSC_VER > 1000
    4. #ifndef PYMUTEX_H
    5. #define PYMUTEX_H
    6. #ifdef WIN32
    7. //#include
    8. #else
    9. #include
    10. #endif
    11. typedef void *HANDLE;
    12. class IMutex
    13. {
    14. public:
    15. virtual ~IMutex() {}
    16. virtual void Lock() const = 0;
    17. virtual bool TryLock() const = 0;
    18. virtual void Unlock() const = 0;
    19. };
    20. class PYMutex : public IMutex
    21. {
    22. public:
    23. PYMutex();
    24. ~PYMutex();
    25. virtual void Lock() const;
    26. virtual bool TryLock() const;
    27. virtual void Unlock() const;
    28. private:
    29. #ifdef _WIN32
    30. HANDLE m_mutex;
    31. #else
    32. mutable pthread_mutex_t m_mutex;
    33. #endif
    34. };
    35. #endif //PYMUTEX_H

    Mutex.cpp

    1. #include "Mutex.h"
    2. #ifdef WIN32
    3. #include
    4. #endif
    5. #include
    6. PYMutex::PYMutex()
    7. {
    8. #ifdef _WIN32
    9. m_mutex = ::CreateMutex(NULL, FALSE, NULL);
    10. #else
    11. pthread_mutex_init(&m_mutex, NULL);
    12. #endif
    13. }
    14. PYMutex::~PYMutex()
    15. {
    16. #ifdef _WIN32
    17. ::CloseHandle(m_mutex);
    18. #else
    19. pthread_mutex_destroy(&m_mutex);
    20. #endif
    21. }
    22. void PYMutex::Lock() const
    23. {
    24. #ifdef _WIN32
    25. WaitForSingleObject(m_mutex, INFINITE);
    26. #else
    27. pthread_mutex_lock(&m_mutex);
    28. #endif
    29. }
    30. bool PYMutex::TryLock() const
    31. {
    32. #ifdef _WIN32
    33. DWORD dwWaitResult = WaitForSingleObject(m_mutex, 0);
    34. if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT) {
    35. printf("thread WARNING: bad result from try-locking mutex\n");
    36. }
    37. return (dwWaitResult == WAIT_OBJECT_0) ? true : false;
    38. #else
    39. return (0==pthread_mutex_trylock(&m_mutex))?true:false;
    40. #endif
    41. };
    42. void PYMutex::Unlock() const
    43. {
    44. #ifdef _WIN32
    45. ::ReleaseMutex(m_mutex);
    46. #else
    47. pthread_mutex_unlock(&m_mutex);
    48. #endif
    49. }

    linux下myThread.h

    1. /*
    2. * add arg in linux system and compile: -lpthread
    3. *
    4. */
    5. #ifndef _MYTHREAD_H
    6. #define _MYTHREAD_H
    7. #include
    8. #include
    9. class MyThread
    10. {
    11. private:
    12. //current thread ID
    13. pthread_t tid;
    14. //thread status
    15. int threadStatus;
    16. //get manner pointer of execution
    17. static void* run0(void* pVoid);
    18. //manner of execution inside
    19. void* run1();
    20. public:
    21. //threadStatus-new create
    22. static const int THREAD_STATUS_NEW = 0;
    23. //threadStatus-running
    24. static const int THREAD_STATUS_RUNNING = 1;
    25. //threadStatus-end
    26. static const int THREAD_STATUS_EXIT = -1;
    27. // constructed function
    28. MyThread();
    29. ~MyThread();
    30. //the entity for thread running
    31. virtual int Run()=0;
    32. //start thread
    33. bool start();
    34. //gte thread ID
    35. pthread_t getThreadID();
    36. //get thread status
    37. int getState();
    38. //wait for thread end
    39. void join();
    40. //wait for thread end in limit time
    41. void join(unsigned long millisTime);
    42. };
    43. #endif /* _MYTHREAD_H */

    linux下myThread.cpp

    1. #include "myThread.h"
    2. #include
    3. void* MyThread::run0(void* pVoid)
    4. {
    5. MyThread* p = (MyThread*) pVoid;
    6. p->run1();
    7. return p;
    8. }
    9. void* MyThread::run1()
    10. {
    11. threadStatus = THREAD_STATUS_RUNNING;
    12. tid = pthread_self();
    13. Run();
    14. threadStatus = THREAD_STATUS_EXIT;
    15. tid = 0;
    16. pthread_exit(NULL);
    17. }
    18. MyThread::MyThread()
    19. {
    20. tid = 0;
    21. threadStatus = THREAD_STATUS_NEW;
    22. }
    23. MyThread::~MyThread()
    24. {
    25. join(10);
    26. }
    27. int MyThread::Run()
    28. {
    29. while(true){
    30. printf("thread is running!\n");
    31. sleep(100);
    32. }
    33. return 0;
    34. }
    35. bool MyThread::start()
    36. {
    37. return pthread_create(&tid, NULL, run0, this) == 0;
    38. }
    39. pthread_t MyThread::getThreadID()
    40. {
    41. return tid;
    42. }
    43. int MyThread::getState()
    44. {
    45. return threadStatus;
    46. }
    47. void MyThread::join()
    48. {
    49. if (tid > 0)
    50. {
    51. pthread_join(tid, NULL);
    52. }
    53. }
    54. void MyThread::join(unsigned long millisTime)
    55. {
    56. if (tid == 0)
    57. {
    58. return;
    59. }
    60. if (millisTime == 0)
    61. {
    62. join();
    63. }else
    64. {
    65. unsigned long k = 0;
    66. while (threadStatus != THREAD_STATUS_EXIT && k <= millisTime)
    67. {
    68. usleep(100);
    69. k++;
    70. }
    71. }
    72. }

    win下win32Thread.h

    1. #if _MSC_VER > 1000
    2. #pragma once
    3. #endif // _MSC_VER > 1000
    4. #ifndef WIN32THREAD_H
    5. #define WIN32THREAD_H
    6. #include
    7. #include
    8. typedef void *HANDLE;
    9. class MyThread
    10. {
    11. public:
    12. MyThread();
    13. ~MyThread();
    14. void start();
    15. virtual int Run();
    16. HANDLE getThread();
    17. private:
    18. HANDLE hThread;
    19. static void agent(void *p);
    20. };
    21. #endif

    win下win32Thread.cpp

    1. #include "win32Thread.h"
    2. #include
    3. MyThread::MyThread()
    4. {
    5. }
    6. MyThread::~MyThread()
    7. {
    8. WaitForSingleObject(hThread, INFINITE);
    9. }
    10. void MyThread::start()
    11. {
    12. hThread =(HANDLE)_beginthread(agent, 0, (void *)this);
    13. }
    14. int MyThread::Run()
    15. {
    16. printf("Base Thread\n");
    17. return 0;
    18. }
    19. void MyThread::agent(void *p)
    20. {
    21. MyThread *agt = (MyThread *)p;
    22. agt->Run();
    23. }
    24. HANDLE MyThread::getThread()
    25. {
    26. return hThread;
    27. }

     main.cpp,展示如何使用log类

    1. #include
    2. #include
    3. #ifdef WIN32
    4. #include
    5. #endif
    6. #include "Log.h"
    7. char LOG_FILE_NAME[128] = "pyfree_log";
    8. std::string logdir = "./log";
    9. namespace GlobalVar {
    10. extern std::string logname;
    11. };
    12. int main(int argc, char *argv[])
    13. {
    14. #ifdef WIN32
    15. std::string appname = std::string(argv[0]);
    16. GlobalVar::logname = appname.substr(0,appname.length()-4);
    17. #else
    18. GlobalVar::logname = std::string(argv[0]);
    19. #endif
    20. int i = 0;
    21. while(i<1)
    22. {
    23. CLogger::createInstance()->Log(eLogType(rand()%10),"log test for %d\n",i++);
    24. #ifdef WIN32
    25. Sleep(10);
    26. #else
    27. usleep(10000);
    28. #endif
    29. }
    30. return 0;
    31. }

    三、编译及展示

            CMakeLists.txt:

    1. # CMake 最低版本号要求
    2. cmake_minimum_required (VERSION 2.8)
    3. # 项目信息
    4. project (log_test)
    5. #
    6. if(WIN32)
    7. message(STATUS "windows compiling...")
    8. add_definitions(-D_PLATFORM_IS_WINDOWS_)
    9. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
    10. set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
    11. set(WIN_OS true)
    12. else(WIN32)
    13. message(STATUS "linux compiling...")
    14. add_definitions( -D_PLATFORM_IS_LINUX_)
    15. add_definitions("-Wno-invalid-source-encoding")
    16. # add_definitions("-O2")
    17. set(UNIX_OS true)
    18. set(_DEBUG true)
    19. endif(WIN32)
    20. #
    21. set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    22. # 指定源文件的目录,并将名称保存到变量
    23. SET(source_h
    24. #
    25. ${PROJECT_SOURCE_DIR}/src/Mutex.h
    26. ${PROJECT_SOURCE_DIR}/src/log.h
    27. )
    28. SET(source_cpp
    29. #
    30. ${PROJECT_SOURCE_DIR}/src/Mutex.cpp
    31. ${PROJECT_SOURCE_DIR}/src/log.cpp
    32. ${PROJECT_SOURCE_DIR}/src/main.cpp
    33. )
    34. #头文件目录
    35. include_directories(${PROJECT_SOURCE_DIR}/include)
    36. if (${UNIX_OS})
    37. SET(source_h_linux
    38. #
    39. ${PROJECT_SOURCE_DIR}/src/myThread.h
    40. )
    41. SET(source_cpp_linux
    42. ${PROJECT_SOURCE_DIR}/src/myThread.cpp
    43. )
    44. add_definitions(
    45. "-W"
    46. "-fPIC"
    47. "-Wall"
    48. # "-Wall -g"
    49. "-Werror"
    50. "-Wshadow"
    51. "-Wformat"
    52. "-Wpointer-arith"
    53. "-D_REENTRANT"
    54. "-D_USE_FAST_MACRO"
    55. "-Wno-long-long"
    56. "-Wuninitialized"
    57. "-D_POSIX_PTHREAD_SEMANTICS"
    58. "-DACL_PREPARE_COMPILE"
    59. "-Wno-unused-parameter"
    60. "-fexceptions"
    61. )
    62. set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
    63. link_directories()
    64. # 指定生成目标
    65. add_executable(log_test ${source_h} ${source_cpp} ${source_h_linux} ${source_cpp_linux})
    66. #link
    67. target_link_libraries(log_test
    68. -lpthread -pthread -lz -lrt -ldl
    69. )
    70. endif(${UNIX_OS})
    71. if (${WIN_OS})
    72. SET(source_h_win
    73. ${PROJECT_SOURCE_DIR}/src/win32Thread.h
    74. )
    75. SET(source_cpp_win
    76. ${PROJECT_SOURCE_DIR}/src/win32Thread.cpp
    77. )
    78. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4819")
    79. add_definitions(
    80. "-D_CRT_SECURE_NO_WARNINGS"
    81. "-D_WINSOCK_DEPRECATED_NO_WARNINGS"
    82. "-DNO_WARN_MBCS_MFC_DEPRECATION"
    83. "-DWIN32_LEAN_AND_MEAN"
    84. )
    85. link_directories()
    86. if (CMAKE_BUILD_TYPE STREQUAL "Debug")
    87. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)
    88. # 指定生成目标
    89. add_executable(log_testd ${source_h} ${source_cpp} ${source_h_win} ${source_cpp_win})
    90. else(CMAKE_BUILD_TYPE)
    91. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)
    92. # 指定生成目标
    93. add_executable(log_test ${source_h} ${source_cpp} ${source_h_win} ${source_cpp_win})
    94. endif (CMAKE_BUILD_TYPE)
    95. endif(${WIN_OS})

            Linux下

    1. cd log_test
    2. mkdir build_linux
    3. cd build_linux
    4. cmake ..
    5. make

    编译及执行过程

    1. [py@pyfree build_linux]$ cmake ..
    2. -- The C compiler identification is GNU 4.8.5
    3. -- The CXX compiler identification is GNU 4.8.5
    4. -- Check for working C compiler: /usr/bin/cc
    5. -- Check for working C compiler: /usr/bin/cc -- works
    6. -- Detecting C compiler ABI info
    7. -- Detecting C compiler ABI info - done
    8. -- Detecting C compile features
    9. -- Detecting C compile features - done
    10. -- Check for working CXX compiler: /usr/bin/c++
    11. -- Check for working CXX compiler: /usr/bin/c++ -- works
    12. -- Detecting CXX compiler ABI info
    13. -- Detecting CXX compiler ABI info - done
    14. -- Detecting CXX compile features
    15. -- Detecting CXX compile features - done
    16. -- linux compiling...
    17. -- Configuring done
    18. -- Generating done
    19. -- Build files have been written to: /mnt/hgfs/workForMy/workspace/log_test/build_linux
    20. [py@pyfree build_linux]$ make
    21. Scanning dependencies of target log_test
    22. [ 20%] Building CXX object CMakeFiles/log_test.dir/src/Mutex.cpp.o
    23. [ 40%] Building CXX object CMakeFiles/log_test.dir/src/log.cpp.o
    24. [ 60%] Building CXX object CMakeFiles/log_test.dir/src/main.cpp.o
    25. [ 80%] Building CXX object CMakeFiles/log_test.dir/src/myThread.cpp.o
    26. [100%] Linking CXX executable ../bin/log_test
    27. [100%] Built target log_test
    28. [py@pyfree build_linux]$
    29. [py@pyfree bin]$ ./log_test
    30. mkdir: 无法创建目录"log": 文件已存在
    31. Log::[5153]-->log test for 0
    32. [py@pyfree bin]$

    win编译时采用cmake+vs编译,具体编译版本可以依据自身电脑安装版本决定

    1. cd log_test && mkdir build_win && cd build_win
    2. cmake -G "Visual Studio 10 2010 Win64" -DCMAKE_BUILD_TYPE=Release ..
    3. msbuild log_test.sln /p:Configuration="Release" /p:Platform="x64"

     省略编译过程,结果展示如下:

    四、完整代码目录:

    文案中已经提供完整代码信息,如果还是不知道如何组织项目代码,请这里下载:

    https://download.csdn.net/download/py8105/86548527

  • 相关阅读:
    AI助力快速定位数据库难题
    [蓝桥杯 2022 省 A] 求和
    组件-utest
    每日三题 8.24
    单例模式Singleton
    aduino 联动ULN2003驱动板营造夏日炫酷小风扇
    【Flutter】Android Studio的Flutter环境配置
    ConcurrentHashMap底层原理(1.7&1.8)
    PHPmail 发送邮件错误 550 的原因是什么?
    【软考学习7】数据校验——海明校验码、循环校验码、奇偶校验码
  • 原文地址:https://blog.csdn.net/py8105/article/details/126930886