CMake里面怎么递归地设定头文件的搜索目录

CMake里面怎么递归地设定头文件的搜索目录,第1张

CMake头文件搜索路径

# 中午吃完饭,就到了办公室,开始看 OGRE 的CMake配置文件。

# 想根据实例,再配合 CMake 安装包里自带了官方Manual,学习CMakeLists文件的编写。

# 不得不承认,没有外网真心惨。用手机查资料眼睛都瞅瞎了。

# 中间出去吃了个晚饭,然后一直研究到10点,还算是有点收获

本文内容要点:

1. 多目录下,头文件路径包含

2. 项目依赖关系设置

3. 发现的一些问题

本文涉及到的CMake命令

project(name) : 设置project的名字为name。

add_dependencies:设置依赖关系

add_subdirectory:添加子目录

add_executable:添加可执行文件

add_library:添加库

cmake_minimum_required:设置cmake最低版本要求

include_directories:包含目录

target_link_libraries:链接库

set:可以用于设置变量

补充命令:

file(GLOB_RECURSE HEADER_FILES dir/*.h??)

此命令可以用来收集源文件 HEADER_FILES 作为变量保存收集的结果。 后面为文件过滤器,其中dir为起始搜索的文件夹,即在dir目录下,开始收集,而且会遍历子目录。 ? 代表 a-z。

首先给出目录结构(“-”表示目录级数)

-sin

--include

---sin.h

--src

---sin.cpp

-sinutil

--include

---sinutil.h

--src

---sinutil.cpp

-main

--main.cpp

目的:

main.cpp 要使用 sin 里面 sin.h 和 sin.cpp 生成的静态库 sin.lib,而 sin.lib 的生成要使用 sinutil 里面的 sinutil.h 和 sinutil.cpp 生成的静态库 sinutil.lib 。

sinutil.cpp 要包含 sinutil.h,而 sinutil.h 不在 sinutil.cpp 目录下。同理 sin.cpp 也要包含 sinutil.h ,main.cpp 要包含 sin.h。

根据CMake的规则,在根目录下和每个子目录下加入 CMakeLists.txt 文件。

# 为了便于区分,我给每个 CMakeLists.txt 加了编号后缀。

# 真正运行的时候,CMake配置文件只能命名为 CMakeLists.txt。

得到的目录结构如下:

- CMakeLists.txt - 1

-sin

-- CMakeLists.txt - 2

--include

---sin.h

--src

---sin.cpp

-sinutil

-- CMakeLists.txt - 3

--include

---sinutil.h

--src

---sinutil.cpp

-main

-- CMakeLists.txt - 4

--main.cpp

CMake配置文件内容如下:

#CMakeLists.txt - 1

cmake_minimum_required(VERSION 2.8.1)

project(CMakeDemo)

include_directories(${CMakeDemo_SOURCE_DIR}/sin/include)

include_directories(${CMakeDemo_SOURCE_DIR}/sinutil/include)

add_subdirectory(sin)

add_subdirectory(sinutil)

add_subdirectory(main)

#CMakeLists.txt - 4

project(MainDemo)

set(SRC_LIST main.cpp)

add_executable(demo ${SRC_LIST})

add_dependencies(demo SinLibrary)

target_link_libraries(demo ${SinLibrary})

#CMakeLists.txt - 2

set(HEADER_LIST include/sin.h)

set(SRC_LIST src/sin.cpp)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

add_library(SinLibrary ${HEADER_LIST} ${SRC_LIST})

add_dependencies(SinLibrary SinUtilLibrary)

target_link_libraries(SinLibrary ${SinUtilLibrary})

#CMakeLists.txt - 3

set(HEADER_LIST include/sinutil.h)

set(SRC_LIST src/sinutil.cpp)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

add_library(SinUtilLibrary ${HEADER_LIST} ${SRC_LIST})

结论:

1. CMake使用 include_directories 命令来添加头文件包含路径,且 include_directories 命令具有继承性。下级目录继承了上级目录中CMakeLists.txt 里面 include 的 directrories。但是平级目录之间的 CMakeList.txt 里面的include_directories 不能共享。

2. CMAKE_CURRENT_SOURCE_DIR 为 CMake 定义的环境变量,指向当前 CMakeLists.txt 所在的目录。

3. 当使用 project(name) 命令时,CMake会自动生成两个变量 name_SOURCE_DIR 和 name_BINARY_DIR,前一个指向使用 project 命令的CMakeLists.txt 所在的文件夹,后一个指向用cmake构建时,Build 目录下对应的目录。

问题:

1. 目前还没搞清 project 与 VS 里面的 解决方案(solution)和 工程(项目,project)的对应关系。

2. 使用 add_dependencies 来设置依赖关系时,在VS 2003 下,会为每一个subdirectory里面的project生成一个额外的带 UTILITY 后缀的工程,能不生成吗?

空协的。。。。自己看

http://page.renren.com/601515204/note/892301714?ref=hotnewsfeed&sfet=2012&fin=1&fid=21075429468&ff_id=601515204&platform=0&expose_time=1357989999&feed=page_blog&tagid=892301714&statID=page_601515204_2&level=1

// FileScan.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include <filesystem>

#include <windows.h>

#define OK 0

#define ERR -1

 

#define TEST_FILE_MAX_SIZE "4.67G"

 

#define EXT_LEN 8

#define TYPE_LEN 8

#define DIR_MAX_LEN 260 //文件路径最多256个字符,加上D:\\

    //ftell()返回int,最大2G 1<<32-1

 

typedef enum COND_VALUE

{

    COND_VALUE_MORE = 0 ,//大于

    COND_VALUE_LESS = 1 ,//小于

    COND_VALUE_EUAQL = 2 ,//等于

    COND_VALUE_MAX = 0xf

}COND_VALUE_E

typedef enum COND_TYPE

{

    COND_TYPE_SIZE = 0 ,

    COND_TYPE_CTIME = 1 ,

    COND_TYPE_MTIME = 2,

    COND_TYPE_EXTNAME = 4,

    COND_TYPE_FILETYPE = 8,

    COND_TYPE_MAX  = 0xf

}COND_TYPE_E

typedef struct COND_INFO

{

    char cCondType : 4

    char cCondValue : 4

}COND_INFO_S

typedef struct FILE_COND

{

    //按照bit位来划分,前面四个bit位表示条件类型,后面四个bit位表示条件值

    char cSymbol//用来标志大于或者小于,搜索时间,大小,类型,扩展名,属性

    char szRes[ 3 ]//预留3个字节,四字节对齐

    unsigned int uiSizeHigh//文件大小 高位

    unsigned int uiSizeLow//低位

    unsigned int uiCStartTime//创建时间

    unsigned int uiCEndTime

    unsigned int uiMStartTime//修改时间

    unsigned int uiMEndTime

    char szExtName[ EXT_LEN ]//扩展名

    char szFileType[ TYPE_LEN ]//文件类型

    unsigned int uiFileAttrib//文件属性

    unsigned int uiFolderSizeHight//文件夹大小

    unsigned int uiFolderSizeLow

}FILE_COND_S

 

//最大允许多少个条件搜索

#define CONDITION_MAX 4

FILE_COND_S g_astCond[ CONDITION_MAX ] = { 0 }

int g_iCondCnt = 0

 

 

int DisposeFile(char szFilePath[] , WIN32_FIND_DATA stWinFile)

{

    DWORDLONG dwHighBase = MAXDWORD

    dwHighBase += 1

    DWORDLONG FileSize = stWinFile.nFileSizeHigh* dwHighBase + stWinFile.nFileSizeLow

    printf("%s\\%s--Size:%lu\n" , szFilePath , stWinFile.cFileName , FileSize)

    return OK

}

 

//转换字符串文件大小(如 45.67G)到int类型的文件大小

#define SECTION_CNT 2

#define MAX_NUM_DEC 100

#define UNIT_CNT   4

#define KB_OFFSET  10  //1KB == 1BIT<<10

#define MB_OFFSET  20

#define GB_OFFSET  30

#define TB_OFFSET  40

#define INT_OFFSET 32

int ConvertSizeStr2SizeLong(char szSizeStr[],unsigned int* puiSizeHigh,unsigned int* puiSizeLow)

{

    int aNumSect[ SECTION_CNT ] = { 0 }//分别存整数位和小数位

    //char sz = "..."

    char acValidUint[UNIT_CNT] = { 'K' , 'M' , 'G' , 'T' }//数组

    //char acValidUint[] = "KMGT"//字符串

    char acOffset[ UNIT_CNT ] = { KB_OFFSET , MB_OFFSET , GB_OFFSET , TB_OFFSET }

    char cOffset = 0

    int iBaseNum

 

    char* pcTmp

    int index = 0

    int i

    int iMask

    //入参判断

    if (szSizeStr == NULL)

    {

        return ERR

    }

 

    pcTmp = szSizeStr

    while (*pcTmp!=0)

    {

        if (*pcTmp == '.')

        {

            index++

            if ( index >= SECTION_CNT )

            {

                return ERR

            }

        }

        else if ( *pcTmp >= '0' && *pcTmp <= '9' )

        {

            //小数位取3位,剩余的舍去

            if ( index == 1 && aNumSect[ index ] > MAX_NUM_DEC )

            {

                pcTmp++

                continue

            }

            else if (index == 0 && aNumSect[index] > MAX_NUM_DEC)

            {

                //1234G 不合法,应该写成1.234T

                return ERR

            }

            aNumSect[ index ] = aNumSect[ index ] * 10 + *pcTmp - '0'

        }

        else

        { 

            for ( i = 0 i < UNIT_CNT++i )

            {

                if ( toupper(*pcTmp) == acValidUint[ i ] )

                {

                    break

                }

            }

            if (i == UNIT_CNT)

            {

                return ERR

            }

        }

        pcTmp++

    }

    if (cOffset == 0)

    {

        *puiSizeHigh = 0

        *puiSizeLow = aNumSect[ 0 ]

    } 

    else

    {

        //先转为下一级单位

        iBaseNum = ( aNumSect[ 0 ] << KB_OFFSET ) + aNumSect[ 0 ]//能保证小于MAX_UNIT

        cOffset -= KB_OFFSET

    }

    iMask = ( 1 << cOffset ) - 1//用于取低于(INT_OFFSET - cOffset)数据

    *puiSizeHigh = ( iBaseNum >> ( INT_OFFSET - cOffset ) ) & iMask

    *puiSizeLow = iBaseNum << cOffset

    return OK

}

 

//比较文件大小

int CompareFileSize(WIN32_FIND_DATA stWinFile , FILE_COND_S stCond,char cCondValue)

{

    switch ( cCondValue )

    {

        case COND_VALUE_LESS:

        {

            if ( stWinFile.nFileSizeHigh > stCond.uiSizeHigh )

            {

                return ERR

            }

            else if ( stWinFile.nFileSizeHigh ==stCond.uiSizeHigh )

            {

                if ( stWinFile.nFileSizeLow > stCond.uiSizeLow )

                {

                    return ERR

                }

            }

            break

        }

        case COND_VALUE_MORE:

        {

            if ( stWinFile.nFileSizeHigh < stCond.uiSizeHigh )

            {

                return ERR

            }

            else if ( stWinFile.nFileSizeHigh == stCond.uiSizeHigh )

            {

                if ( stWinFile.nFileSizeLow < stCond.uiSizeLow )

                {

                    return ERR

                }

            }

            break

        }

        case COND_VALUE_EUAQL:

        {

            if ( stWinFile.nFileSizeHigh != stCond.uiSizeHigh || stWinFile.nFileSizeLow != stCond.uiSizeLow )

            {

                return ERR

            }

            break

        }

        default:

            break

    }

    return OK

}

int CompareFileTime(WIN32_FIND_DATA stWinFile , FILE_COND_S stCond , char cCondValue)

{

    return OK

}

int CheckCondition(char szFilePath[],WIN32_FIND_DATA stWinFile)

{

    int i

    int iCondType

    int iCondValue

    COND_INFO_S* pstCondInfo

 

    for ( i = 0 i < g_iCondCnt ++i )

    {

        pstCondInfo = (COND_INFO_S*)(&( g_astCond[ i ].cSymbol))

        switch (pstCondInfo->cCondType)

        {

            case COND_TYPE_SIZE:

            {

                if ( CompareFileSize(stWinFile , g_astCond[ i ],pstCondInfo->cCondValue) != OK )

                {

                    return ERR

                }

                break

            }

            case COND_TYPE_CTIME:

            {

                if ( CompareFileTime(stWinFile , g_astCond[ i ] , pstCondInfo->cCondValue) != OK )

                {

                    return ERR

                }

                break

            }

            //...

            default:

                break

        }

    }

    return OK

}

 

int ScanDir(char szDir[])

{

    if ( szDir == NULL )

    {

        return ERR

    }

 

    char szSubDir[ DIR_MAX_LEN ] = { 0 }

    char szFind[ DIR_MAX_LEN ] = { 0 }

 

    WIN32_FIND_DATA stWinFile

    HANDLE hd

 

    _snprintf_c(szFind , 

                DIR_MAX_LEN , 

                "%s\\*" ,

                szDir)//两个反斜杠表示一个反斜杠转义符

    hd = FindFirstFile(szFind , &stWinFile)//hd标志文件位置,用于查找下一个文件

    if ( hd == INVALID_HANDLE_VALUE )

    {

        return ERR

    }

 

    while (1)

    {

        if (strcmp(stWinFile.cFileName,".") == 0 || strcmp(stWinFile.cFileName,"..") == 0)

        {

            //NULL

        }

        //判断是否是文件夹

        else if ( stWinFile.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )

        {

            //清空szSubDir,因为在重新对szSubDir赋值时,是直接覆盖的,后者比当前保存的数据短,所以需要先清空再赋值

            memset(szSubDir , 0 , DIR_MAX_LEN)

            _snprintf_c(szSubDir , DIR_MAX_LEN , "%s\\%s" , szDir , stWinFile.cFileName)

            ScanDir(szSubDir)//递归处理

        }

        else

        {

            if ( CheckCondition(szDir , stWinFile) == OK )

            {

                DisposeFile(szDir , stWinFile)

            }

        }

        //查找下一个文件失败就跳出循环

        if ( !FindNextFile(hd , &stWinFile) )

        {

            break

        }

    }

    FindClose(hd)

    return OK

}

 

int _tmain(int argc, _TCHAR* argv[])

{

    COND_INFO_S stCond = { 0 }

    COND_INFO_S* pstCond

    char szDir[] = "C:"

    stCond.cCondValue = COND_TYPE_SIZE

    stCond.cCondValue = COND_VALUE_MORE

 

    if (ConvertSizeStr2SizeLong(TEST_FILE_MAX_SIZE,&(g_astCond[0].uiSizeHigh),&(g_astCond[0].uiSizeLow)) == OK)

    {

        memcpy(&(g_astCond[ 0 ].cSymbol),&stCond,1)

        pstCond = (COND_INFO_S*)( &g_astCond[ 0 ].cSymbol )

        g_iCondCnt = 1

        ScanDir(szDir)

    }

    system("pause")

    return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11816716.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存