目录
一、本地日志文件管理设计
在前文“c++中如何利用VA_LIST 和单体模式,构建自己的log小系统_py_free的博客-CSDN博客”中,简要创建了自己的log功能模块后,那么在系统长期运行过程中,会不断地创建日志文件并记录。对于微机、小型工控机等设备而言,存储空间是很宝贵的资源。为了节省空间,需要对日志文件进行管理,解决方法有不少,例如,日志文件远程推送后台、云端,或者不定时删除旧文件等等。
在本文中,将设计一个磁盘管理功能模块,根据指定磁盘目录,如win指定{C,D},linux指定{/}等,获取磁盘总空间、剩余空间的数值,就可以依据存储空间来判定是否删除日志文件,为系统运行保持必要的空间。提供一个删除日志的API,根据指定目录和文件扩展名,去删除旧的日志文件。
/**
* 根据指定磁盘获取磁盘的总空间和剩余空间
* @param _DiskStr {char} 磁盘目录,一般win指定{C,D},linux指定{/}
* @param _totalSize {int} 返回磁盘总空间
* @param _freeSize {int} 返回磁盘剩余空间
* @return {int} 预留的返回值,暂指定是常量1
*/
int getDiskFreeSpace(char _DiskStr, int &_totalSize, int &_freeSize);
/**
* 根据指定目录 扩展名 天数限制等删除目录下的文件,项目用于删除旧日志操作
* @param _dir {string}} 目录
* @param extname {string} 扩展名,如txt/ini/log等
* @param dayForLimit_ {int} 指定天数,默认为0时会删除非当天的其他文件
* @return {void} 无返回
*/
void moveOldFile(std::string _dir, const std::string &extname, int dayForLimit_=0);
/**
* 获取当天凌晨时刻的偏移时间,单位秒,与1970-01-01 00:00:00起
* @param deviation {int} 偏移秒数
* @return {int} 当天凌晨时刻的偏移时间.单位秒
*/
int getCurDayZeroClockTime(int deviation=0);
二、案例实现
在win中,提供类GetDiskFreeSpaceEx等API函数,获取与一个磁盘的组织有关的信息,以及了解剩余空间的容量。
BOOL GetDiskFreeSpaceEx(
LPCWSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailableToCaller,
PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes
);
而在删除文件方面,可以先调用winAPI函数_findfirst来不断搜索与指定的文件名称匹配的第一个实例,若成功则返回第一个实例的句柄,并能获得_finddata_t结构化文件信息,然后依据扩展名、创建时间等确定是否删除该文件。
#函数原型如下,需要包含<io.h>
long _findfirst( char *filespec, struct _finddata_t *fileinfo )
在Linux中,提供了statfs或fstatfs的API函数来获取文件系统相关信息,
#include <sys/vfs.h> /* 或者 <sys/statfs.h> */
int statfs(const char *path, struct statfs *buf);
int fstatfs(int fd, struct statfs *buf);
#相关参数及statfs结构体说明
path: 需要查询信息的文件系统的文件路径名。
fd: 需要查询信息的文件系统的文件描述词。
buf:以下结构体的指针变量,用于储存文件系统相关的信息
struct statfs {
long f_type; /* 文件系统类型 */
long f_bsize; /* 经过优化的传输块大小,单位B*/
long f_blocks; /* 文件系统数据块总数 */
long f_bfree; /* 可用块数 */
long f_bavail; /* 非超级用户可获取的块数 */
long f_files; /* 文件结点总数 */
long f_ffree; /* 可用文件结点数 */
fsid_t f_fsid; /* 文件系统标识 */
long f_namelen; /* 文件名的最大长度 */
};
而在删除日志文件的处理上,采用opendir、readdir来获得指定目录下各个文件信息“struct dirent”,然后依据扩展名、时间要求等判定是否删除。
#include <sys/types.h> #include <dirent.h>
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dir);
struct dirent
{
ino_t d_ino; //d_ino 此目录进入点的inode
ff_t d_off; //d_off 目录文件开头至此目录进入点的位移
signed short int d_reclen; //d_reclen _name 的长度, 不包含NULL 字符
unsigned char d_type; //d_type d_name 所指的文件类型 d_name 文件名
har d_name[256];
};
三、案例代码设计
代码目录结构:
log_test
bin #编译目标输出目录
build_win #win编译文件及中间文件目录
build_linux #Linux编译文件及中间文件目录
src #源码
DiskSpace.h #磁盘空间计算、日志文件删除API集
DiskSpace.cpp
pyprint.h #采用宏定义实现的打印输出
spaceMgr.h #基于DiskSpace函数集实现的磁盘管理线程,定期巡检磁盘并删除指定旧日志
spaceMgr.cpp
myThread.h #linux下线程类实现
myThread.cpp
win32Thread.h #win下线程类实现
win32Thread.cpp
main.cpp
CMakeLists.txt #cmake工程配置文件
DiskSpace.h:
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef DISK_SPACE_H
#define DISK_SPACE_H
/***********************************************************************
*Copyright 2022-09-20, pyfree
*
*File Name : DiskSpace.h
*File Mark :
*Summary :
*磁盘空间统计和日志删除相关函数集
*Current Version : 1.00
*Author : pyfree
*FinishDate :
*
*Replace Version :
*Author :
*FinishDate :
************************************************************************/
#include <string>
namespace pyfree
{
/**
* 根据指定磁盘获取磁盘的总空间和剩余空间
* @param _DiskStr {char} 磁盘目录,一般win指定{C,D},linux指定{/}
* @param _totalSize {int} 返回磁盘总空间
* @param _freeSize {int} 返回磁盘剩余空间
* @return {int} 预留的返回值,暂指定是常量1
*/
int getDiskFreeSpace(char _DiskStr, int &_totalSize, int &_freeSize);
/**
* 根据指定目录 扩展名 天数限制等删除目录下的文件,项目用于删除旧日志操作
* @param _dir {string}} 目录
* @param extname {string} 扩展名,如txt/ini/log等
* @param dayForLimit_ {int} 指定天数,默认为0时会删除非当天的其他文件
* @return {void} 无返回
*/
void moveOldFile(std::string _dir, const std::string &extname, int dayForLimit_=0);
/**
* 获取当天凌晨时刻的偏移时间,单位秒,与1970-01-01 00:00:00起
* @param deviation {int} 偏移秒数
* @return {int} 当天凌晨时刻的偏移时间.单位秒
*/
int getCurDayZeroClockTime(int deviation=0);
};
#endif
DiskSpace.cpp:
#include "DiskSpace.h"
#include <time.h>
#include <list>
#include <vector>
#ifndef WIN32
#include <sys/statfs.h>
#include <dirent.h>
/*#include <sys/vfs.h> or <sys/statfs.h> */
#include <sys/vfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#else
#include <io.h>
#include <direct.h>
#include <Windows.h>
#endif
#include "pyprint.h"
int pyfree::getDiskFreeSpace(char _DiskStr, int &_totalSize, int &_freeSize)
{
#ifdef WIN32
BOOL fResult;
unsigned _int64 i64FreeBytesToCaller;
unsigned _int64 i64TotalBytes;
unsigned _int64 i64FreeBytes;
char dir[4] = { _DiskStr, ':', '\\' };
//GetDiskFreeSpaceEx function,get the disk space status,return BOOL type
fResult = GetDiskFreeSpaceEx(
dir,
(PULARGE_INTEGER)&i64FreeBytesToCaller,
(PULARGE_INTEGER)&i64TotalBytes,
(PULARGE_INTEGER)&i64FreeBytes);
if (fResult)//jude the disk is in work status by the return value
{
_totalSize = static_cast<int>(static_cast<float>(i64TotalBytes) / 1024 / 1024); //disk total size
_freeSize = static_cast<int>(static_cast<float>(i64FreeBytesToCaller) / 1024 / 1024); //disk free space sze
MyPrint(L_NOTICE,"_totalSize(%ul) _freeSize(%ul)\n", _totalSize,_freeSize);
}
#endif // WIN32
#ifdef __linux__
//MyPrint(L_NOTICE,"DiskFlag(%c)\n", _DiskStr);
struct statfs diskInfo;
statfs("/", &diskInfo);
unsigned long long totalBlocks = diskInfo.f_bsize;
unsigned long long totalSize = totalBlocks * diskInfo.f_blocks;
_totalSize = static_cast<int>(totalSize >> 20);
//MyPrint(L_NOTICE,"TOTAL_SIZE == %d MB\n", _totalSize);
unsigned long long freeDisk = diskInfo.f_bfree*totalBlocks;
_freeSize = static_cast<int>(freeDisk >> 20);
//MyPrint(L_NOTICE,"DISK_FREE == %d MB\n", _freeSize);
#endif
return 1;
}
//delete old file which is older taday for the file modify time
void pyfree::moveOldFile(std::string _dir, const std::string &extname, int dayForLimit_)
{
try{
MyPrint(L_NOTICE,"now will moveOldFile(*.%s) from(%s) \n",extname.c_str(),_dir.c_str());
#ifdef WIN32
_finddata_t fileInfo;
intptr_t hFile;
std::string filter = _dir;
if (filter[filter.size() - 1] != '//' || filter[filter.size() - 1] != '\\') {
filter.push_back('\\');
}
filter += "*.";
filter += extname;
//time_t file_time_ = time(NULL);
time_t file_time_ = (time_t)getCurDayZeroClockTime(dayForLimit_*86400);
//get
hFile = _findfirst(filter.c_str(), &fileInfo);
if (hFile == -1) {
return;
}
std::string delOldFile = "";
//find the oldest file by modify time
do {
if (extname.empty())//no ext name, that is dir
{
if ((fileInfo.attrib & _A_SUBDIR)) {
if (0 == strcmp(fileInfo.name, ".") || 0 == strcmp(fileInfo.name, ".."))
{
continue;
}
}
}
//if(fileInfo.time_write<_time)//modify time
if (fileInfo.time_create<file_time_)//create time
{
file_time_ = fileInfo.time_create;
delOldFile = _dir + "//" + (std::string(fileInfo.name));
}
} while (_findnext(hFile, &fileInfo) == 0);
_findclose(hFile);
#endif
#ifdef linux
std::string curdir = _dir;
if (curdir[curdir.size() - 1] != '/') {
curdir.push_back('/');
}
DIR *dfd;
if ((dfd = opendir(curdir.c_str())) == NULL)
{
MyPrint(L_WARNING,"open %s error with msg is: %s\n", curdir.c_str(), strerror(errno));
return;
}
struct dirent *dp;
//time_t file_time_ = time(NULL);
time_t file_time_ = (time_t)getCurDayZeroClockTime(dayForLimit_ * 86400);
std::string delOldFile = "";
while ((dp = readdir(dfd)) != NULL)
{
if (extname.empty())//no ext name, that is dir
{
if (dp->d_type == DT_DIR) {
if (0 == strcmp(dp->d_name, ".") || 0 == strcmp(dp->d_name, ".."))
{
continue;
}
}
}
else {
if (NULL == strstr(dp->d_name, extname.c_str()))
{
continue;
}
}
std::string _path = _dir + "/";
_path += dp->d_name;
struct stat el;
stat(_path.c_str(), &el);
if (el.st_mtime<file_time_) {
file_time_ = el.st_mtime;
delOldFile = _path;
}
}
if (NULL != dp) {
delete dp;
dp = NULL;
}
if (NULL != dfd) {
closedir(dfd);
dfd = NULL;
}
#endif
if (!delOldFile.empty())
{
//MyPrint(L_NOTICE,"get old file: %s \n", delOldFile.c_str());
int ret = remove(delOldFile.c_str());
if (0 != ret) {
MyPrint(L_WARNING,"can't remove %s \n", delOldFile.c_str());
}else{
MyPrint(L_NOTICE,"success remove %s \n", delOldFile.c_str());
}
}
}catch(...){
MyPrint(L_TRACE,"moveOldFile(*.%s) from(%s) exception error\n"
,extname.c_str(),_dir.c_str());
}
}
int pyfree::getCurDayZeroClockTime(int deviation)
{
int ZeroClockTime_ = 0;
time_t cur_time_ = time(NULL);
struct tm _tt;
#ifdef WIN32
localtime_s(&_tt, &cur_time_);
#else
localtime_r(&cur_time_,&_tt);
#endif
//当日凌晨时刻
_tt.tm_hour = 0;
_tt.tm_min = 0;
_tt.tm_sec = 0;
ZeroClockTime_ = static_cast<int>(mktime(&_tt));
ZeroClockTime_ -= deviation;//偏移时间
return ZeroClockTime_;
}
pyprint.h:
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef _PY_PRINT_H_
#define _PY_PRINT_H_
/***********************************************************************
*Copyright 2022-09-20, pyfree
*
*File Name : pyprint.h
*File Mark :
*Summary : 打印输出通用宏定义
*
*Current Version : 1.00
*Author : pyfree
*FinishDate :
*
*Replace Version :
*Author :
*FinishDate :
************************************************************************/
typedef enum PrintLevel
{
L_NOTICE = 1, //一般输出
L_WARNING = 2, //告警输出
L_TRACE = 3, //追踪调试
L_DEBUG = 4, //软件bug
L_FATAL = 5 //致命错误
}PrintLevel;
#define MyPrint(level,log_fmt,...) \
do{ \
switch(level) \
{ \
case L_FATAL: \
printf("L(5,FATAL)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
break;\
case L_DEBUG: \
printf("L(4,DEBUG)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
break;\
case L_TRACE: \
printf("L(3,TRACE)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
break;\
case L_WARNING: \
printf("L(2,WARNING)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
break;\
case L_NOTICE: \
printf("L(1,NOTICE)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
break;\
default: \
printf("L(-1,UNKOWN)[%s:%d][%s] \n"log_fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
break;\
} \
}while (0)
#endif
spaceMgr.h:
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef _SPACE_MGR_H_
#define _SPACE_MGR_H_
/***********************************************************************
*Copyright 2020-09-20, pyfree
*
*File Name : spaceMgr.h
*File Mark :
*Summary : 磁盘空间巡检线程类,根据预留空间要求删除app日志文件
*
*Current Version : 1.00
*Author : pyfree
*FinishDate :
*
*Replace Version :
*Author :
*FinishDate :
************************************************************************/
#ifdef WIN32
#include "win32Thread.h"
#endif
#ifdef linux
#include <string>
#include "myThread.h"
#endif
#include <vector>
class DiskSpaceMgr : public MyThread
{
public:
/**
* 构造函数,如传入参数D 2000 log log,则指明当D盘空闲空间不足2000M时,删除当前目录/log下的log(后缀)文件
* @param disk_ {char} 指定盘符
* @param fsl_ {int} 预留空间大小,单位MB
* @param dir_ {string} 指定目录
* @param ext_ {string} 扩展名
* @return { }
*/
DiskSpaceMgr(char disk_, int fsl_,std::string dir_="log",std::string ext_="log");
virtual ~DiskSpaceMgr(void);
int Run();
void add(std::string dir_,std::string ext_);
private:
struct DelInfo
{
DelInfo(std::string dir_,std::string ext_)
: dir(dir_), ext(ext_)
{};
std::string dir;
std::string ext;
};
private:
bool running;
//用于日志删除
std::vector<DelInfo> dirs; //存储目录
char DiskStr; //日志存储磁盘
int freeSizeLimit; //磁盘预留空间要求
};
#endif
spaceMgr.cpp:
#include "spaceMgr.h"
#ifdef WIN32
#include <windows.h>
#endif
#ifdef linux
#define Sleep(x) usleep(x*1000)
#endif
#include "DiskSpace.h"
DiskSpaceMgr::DiskSpaceMgr(char disk_, int fsl_,std::string dir_/*="log"*/,std::string ext_/*="log"*/)
: running(true)
, DiskStr(disk_)
, freeSizeLimit(fsl_)
{
DelInfo del_(dir_,ext_);
dirs.push_back(del_);
}
DiskSpaceMgr::~DiskSpaceMgr(void)
{
running = false;
}
int DiskSpaceMgr::Run()
{
int _totalSize = 0;
int _freeSize = 0;
while (running)
{
if (pyfree::getDiskFreeSpace(DiskStr, _totalSize, _freeSize) > 0)
{
if (freeSizeLimit > _freeSize)
{
for(unsigned int i=0; i<dirs.size(); ++i)
{
std::string ext = dirs.at(i).ext;
pyfree::moveOldFile(dirs.at(i).dir, ext);
}
}
}
Sleep(10);
}
return 0;
}
void DiskSpaceMgr::add(std::string dir_,std::string ext_)
{
DelInfo del_(dir_,ext_);
dirs.push_back(del_);
}
关于myThread.h 、 myThread.cpp、 win32Thread.h 、 win32Thread.cpp 文件以往文件都有,也一并给出
myThread.h
/*
* add arg in linux system and compile: -lpthread
*
*/
#ifndef _MYTHREAD_H
#define _MYTHREAD_H
#include <pthread.h>
#include <unistd.h>
class MyThread
{
private:
//current thread ID
pthread_t tid;
//thread status
int threadStatus;
//get manner pointer of execution
static void* run0(void* pVoid);
//manner of execution inside
void* run1();
public:
//threadStatus-new create
static const int THREAD_STATUS_NEW = 0;
//threadStatus-running
static const int THREAD_STATUS_RUNNING = 1;
//threadStatus-end
static const int THREAD_STATUS_EXIT = -1;
// constructed function
MyThread();
~MyThread();
//the entity for thread running
virtual int Run()=0;
//start thread
bool start();
//gte thread ID
pthread_t getThreadID();
//get thread status
int getState();
//wait for thread end
void join();
//wait for thread end in limit time
void join(unsigned long millisTime);
};
#endif /* _MYTHREAD_H */
myThread.cpp
#include "myThread.h"
#include <stdio.h>
void* MyThread::run0(void* pVoid)
{
MyThread* p = (MyThread*) pVoid;
p->run1();
return p;
}
void* MyThread::run1()
{
threadStatus = THREAD_STATUS_RUNNING;
tid = pthread_self();
Run();
threadStatus = THREAD_STATUS_EXIT;
tid = 0;
pthread_exit(NULL);
}
MyThread::MyThread()
{
tid = 0;
threadStatus = THREAD_STATUS_NEW;
}
MyThread::~MyThread()
{
join(10);
}
int MyThread::Run()
{
while(true){
printf("thread is running!\n");
sleep(100);
}
return 0;
}
bool MyThread::start()
{
return pthread_create(&tid, NULL, run0, this) == 0;
}
pthread_t MyThread::getThreadID()
{
return tid;
}
int MyThread::getState()
{
return threadStatus;
}
void MyThread::join()
{
if (tid > 0)
{
pthread_join(tid, NULL);
}
}
void MyThread::join(unsigned long millisTime)
{
if (tid == 0)
{
return;
}
if (millisTime == 0)
{
join();
}else
{
unsigned long k = 0;
while (threadStatus != THREAD_STATUS_EXIT && k <= millisTime)
{
usleep(100);
k++;
}
}
}
win32Thread.h
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef WIN32THREAD_H
#define WIN32THREAD_H
#include <process.h>
#include <iostream>
typedef void *HANDLE;
class MyThread
{
public:
MyThread();
~MyThread();
void start();
virtual int Run();
HANDLE getThread();
private:
HANDLE hThread;
static void agent(void *p);
};
#endif
win32Thread.cpp
#include "win32Thread.h"
#include <windows.h>
MyThread::MyThread()
{
}
MyThread::~MyThread()
{
WaitForSingleObject(hThread, INFINITE);
}
void MyThread::start()
{
hThread =(HANDLE)_beginthread(agent, 0, (void *)this);
}
int MyThread::Run()
{
printf("Base Thread\n");
return 0;
}
void MyThread::agent(void *p)
{
MyThread *agt = (MyThread *)p;
agt->Run();
}
HANDLE MyThread::getThread()
{
return hThread;
}
main.cpp,磁盘空间获取及日志删除API使用示例
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#endif
#ifdef linux
#define Sleep(x) usleep(x*1000)
#endif
#include "spaceMgr.h"
int main(int argc, char *argv[])
{
//日志记录删除
DiskSpaceMgr *ptr_DiskSpaceMgr = new DiskSpaceMgr('D',1200000
,"D:\\workForMy\\workspace\\log_test\\bin\\log","log");
ptr_DiskSpaceMgr->start();
int i = 0;
while(i++<1)
{
Sleep(10);
}
delete ptr_DiskSpaceMgr;
ptr_DiskSpaceMgr = NULL;
return 0;
}
四、编译实现
采用cmake组织工程文件:
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (log_mgr_test)
#
if(WIN32)
message(STATUS "windows compiling...")
add_definitions(-D_PLATFORM_IS_WINDOWS_)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
set(WIN_OS true)
else(WIN32)
message(STATUS "linux compiling...")
add_definitions( -D_PLATFORM_IS_LINUX_)
add_definitions("-Wno-invalid-source-encoding")
# add_definitions("-O2")
set(UNIX_OS true)
set(_DEBUG true)
endif(WIN32)
#
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# 指定源文件的目录,并将名称保存到变量
SET(source_h
#
${PROJECT_SOURCE_DIR}/src/pyprint.h
${PROJECT_SOURCE_DIR}/src/DiskSpace.h
${PROJECT_SOURCE_DIR}/src/spaceMgr.h
)
SET(source_cpp
#
${PROJECT_SOURCE_DIR}/src/DiskSpace.cpp
${PROJECT_SOURCE_DIR}/src/spaceMgr.cpp
${PROJECT_SOURCE_DIR}/src/main.cpp
)
#头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)
if (${UNIX_OS})
SET(source_h_linux
#
${PROJECT_SOURCE_DIR}/src/myThread.h
)
SET(source_cpp_linux
${PROJECT_SOURCE_DIR}/src/myThread.cpp
)
add_definitions(
"-W"
"-fPIC"
"-Wall"
# "-Wall -g"
"-Werror"
"-Wshadow"
"-Wformat"
"-Wpointer-arith"
"-D_REENTRANT"
"-D_USE_FAST_MACRO"
"-Wno-long-long"
"-Wuninitialized"
"-D_POSIX_PTHREAD_SEMANTICS"
"-DACL_PREPARE_COMPILE"
"-Wno-unused-parameter"
"-fexceptions"
)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
link_directories()
# 指定生成目标
add_executable(log_mgr_test ${source_h} ${source_cpp} ${source_h_linux} ${source_cpp_linux})
#link
target_link_libraries(log_mgr_test
-lpthread -pthread -lz -lrt -ldl
)
endif(${UNIX_OS})
if (${WIN_OS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4819")
SET(source_h_win
${PROJECT_SOURCE_DIR}/src/win32Thread.h
)
SET(source_cpp_win
${PROJECT_SOURCE_DIR}/src/win32Thread.cpp
)
add_definitions(
"-D_CRT_SECURE_NO_WARNINGS"
"-D_WINSOCK_DEPRECATED_NO_WARNINGS"
"-DNO_WARN_MBCS_MFC_DEPRECATION"
"-DWIN32_LEAN_AND_MEAN"
)
link_directories()
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)
# 指定生成目标
add_executable(log_mgr_testd ${source_h} ${source_cpp} ${source_h_win} ${source_cpp_win})
else(CMAKE_BUILD_TYPE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)
# 指定生成目标
add_executable(log_mgr_test ${source_h} ${source_cpp} ${source_h_win} ${source_cpp_win})
endif (CMAKE_BUILD_TYPE)
endif(${WIN_OS})
win编译时采用cmake+vs编译,具体编译版本可以依据自身电脑安装版本决定
cd log_mgr_test && mkdir build_win && cd build_win
cmake -G "Visual Studio 10 2010 Win64" -DCMAKE_BUILD_TYPE=Release ..
msbuild log_mgr_test.sln /p:Configuration="Release" /p:Platform="x64"
运行效果类似:
D:\workForMy\workspace\log_mgr_test\bin>log_mgr_test.exe
L(1,NOTICE)[..\src\DiskSpace.cpp:45][pyfree::getDiskFreeSpace]
_totalSize(939588l) _freeSize(112679l)
L(1,NOTICE)[..\src\DiskSpace.cpp:69][pyfree::moveOldFile]
moveOldFile(*.log) 1 from(D:\workForMy\workspace\log_test\bin\log)
D:\workForMy\workspace\log_mgr_test\bin>
Linux下
cd log_mgr_test
mkdir build_linux
cd build_linux
cmake ..
make
编译过程:
[py@pyfree build_linux]$ cmake ..
-- 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
-- Detecting C compile features
-- Detecting C compile features - 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
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- linux compiling...
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/hgfs/workForMy/workspace/log_mgr_test/build_linux
[py@pyfree build_linux]$ make
Scanning dependencies of target log_mgr_test
[ 20%] Building CXX object CMakeFiles/log_mgr_test.dir/src/DiskSpace.cpp.o
[ 40%] Building CXX object CMakeFiles/log_mgr_test.dir/src/spaceMgr.cpp.o
[ 60%] Building CXX object CMakeFiles/log_mgr_test.dir/src/main.cpp.o
[ 80%] Building CXX object CMakeFiles/log_mgr_test.dir/src/myThread.cpp.o
[100%] Linking CXX executable ../bin/log_mgr_test
[100%] Built target log_mgr_test
[py@pyfree build_linux]$
五、附录说明
上面已经提供了完整的源文件,如果还不能实现,请去下载整个示例代码包: