Cmake config

cmake_minimum_required(VERSION 3.10)

#put your files in sub folder of src dep res
project(Proj)

#turn on source_group filter
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

#utility functions
macro(SubDirList result curdir)
  file(GLOB children RELATIVE ${curdir} ${curdir}/*)
  set(dirlist "")
  foreach(child ${children})
    if(IS_DIRECTORY ${curdir}/${child})
      list(APPEND dirlist ${child})
    endif()
  endforeach()
  set(${result} ${dirlist})
endmacro()

macro(create_source_tree any_file)
    set(_source_root ${CMAKE_CURRENT_SOURCE_DIR})
    foreach(_tree_file ${${any_file}})
        #change to relative path
        string(REGEX REPLACE ${_source_root}/* "" _tree_file_path_relative ${_tree_file})

        #get file name without path
        string(REGEX REPLACE ".*/" ""  _tree_file_name ${_tree_file_path_relative})

        #remove file name from path string
        string(REGEX REPLACE /${_tree_file_name} ""  _tree_file_path_relative_pure ${_tree_file_path_relative})

        #change / into \\ to repesent a group path
        string(REGEX REPLACE "/" "\\\\\\\\" _tree_file_path_group ${_tree_file_path_relative_pure})
        string(APPEND _tree_file_path_group "\\\\")

        #message(STATUS ${_tree_file_path_group})
        #message(STATUS ${_tree_file})
        source_group(${_tree_file_path_group} FILES ${_tree_file})
        #all pro_tree__all_files must be added to add_executable, inorder to get shown in filter
    endforeach(_tree_file)
endmacro(create_source_tree)

#set output path of exe
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}/bin) # folder auto created if not exist

#include files
#layout format:libname
#                   include
#                   lib
#                   bin
#put .c .cpp files under src/
SubDirList(subs ${CMAKE_CURRENT_SOURCE_DIR}/dep)

foreach(subdir ${subs})
    set(deal "dep/")
    string(APPEND deal ${subdir} "/include/")
    list(APPEND includelist ${deal})
    #message(STATUS ${deal})
endforeach()

include_directories(${includelist})

#include all folders under src
file(GLOB_RECURSE all LIST_DIRECTORIES true RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/*)
file(GLOB_RECURSE dataonly LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/*)
foreach(data ${dataonly})
    list(FIND all ${data} pos)
    if(pos GREATER -1)
        list(REMOVE_ITEM all ${data})
    endif()
endforeach(data)

include_directories(${all})

#copy dll files to bin
file(GLOB_RECURSE dynamiclibs dep/*.dll)
foreach(dll ${dynamiclibs})
    file(COPY ${dll} DESTINATION ${EXECUTABLE_OUTPUT_PATH})
    #复制到编译根目录中,因为VS编译的工作目录为.vcxproj所在文件夹
    #在vs里调试运行时,会到这里来找dll
    file(COPY ${dll} DESTINATION ${CMAKE_BINARY_DIR})
endforeach()

#dependend lib
file(GLOB_RECURSE staticlibs dep/*.lib)
link_libraries(${staticlibs})

#resource files
file(COPY res/ DESTINATION ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}/res)

#program source files
file(GLOB_RECURSE sourcefiles  src/* )

#add exe
add_executable(${CMAKE_PROJECT_NAME} ${sourcefiles})

################################################################
#创建filter tree 开始
################################################################
#关于将文件添加到filter中
#有个source_group TREE,还没尝试。手动一个一个添加。

#万恶之源
#1#最重要的条件:想出现在filter中,必须添加在某个target的source中。
#可用target_sources指定。

#2#有些库写的比较脏,例如glm,其中有个文件有个空的main函数,若将其
#添加到target的source中会导致main重复。
#再如boost中的asio,只使用头文件模式的时候,将其添加到target的source中
#也会导致出错。

#不给这些库添加filter即可。因为想出现在filter中,必须添加到target的source中。
#但添加进去又会出错...

#不添加filter的文件夹
#这里只控制dep src 下的直接子目录,所以只可添加这些文件夹下的子文件夹
set(RubDirList
dep/boost
dep/glm
)

#从filter中排除间接子目录
#有些库添加到target_sources会出错,例如boost中的asio,不为其建立filter即可
#添加方式:dep/boost/include/boost/asio
set(RubbishExcludeFromFilterList

)

SubDirList(treedir1 ${CMAKE_CURRENT_SOURCE_DIR}/dep)#依赖库
foreach(depdir ${treedir1})
    string(PREPEND depdir "dep/")
    string(APPEND depdir "/include")
    list(APPEND tempdepdir ${depdir})
endforeach()
set(treedir1 ${tempdepdir})

SubDirList(treedir2 ${CMAKE_CURRENT_SOURCE_DIR}/src)#程序文件
foreach(srcdir ${treedir2})
    string(PREPEND srcdir "src/")
    list(APPEND tempsrcdir ${srcdir})
endforeach()
set(treedir2 ${tempsrcdir})

set(treedirall ${treedir1} ${treedir2})

#排除直接子文件夹
foreach(projitem ${treedirall})
    foreach(rubbish ${RubDirList})
        set(ThisTmpString "")
        string(APPEND ThisTmpString ".*" ${rubbish} ".*")
        if (${projitem} MATCHES ${ThisTmpString})
            list(REMOVE_ITEM treedirall ${projitem})
        endif(${projitem} MATCHES ${ThisTmpString})
    endforeach()
endforeach()

#获取所有文件
foreach(treedirone ${treedirall})
    string(APPEND treedirone "/*")
    file(GLOB_RECURSE pro_tree__tmpsource  ${treedirone} )
    list(APPEND pro_tree__all_files ${pro_tree__tmpsource})
endforeach()

#排除间接子文件夹
foreach(projitem ${pro_tree__all_files})
    foreach(rubbish ${RubbishExcludeFromFilterList})
        set(ThisTmpString "")
        string(APPEND ThisTmpString ".*" ${rubbish} ".*")
        if (${projitem} MATCHES ${ThisTmpString})
            list(REMOVE_ITEM pro_tree__all_files ${projitem})
        endif(${projitem} MATCHES ${ThisTmpString})
    endforeach()
endforeach()

#必须的一个步骤
target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${pro_tree__all_files})

create_source_tree(pro_tree__all_files)
################################################################
#创建filter tree 结束
################################################################

 

转载于:https://www.cnblogs.com/Searchor/p/7397537.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值