CMake作为构建系统可以轻松生成Visual Studio工程,这让我们的新项目可以不必维护一组专门的Visual Studio工程文件和sln文件了。但是CMake默认生成的工程文件中,只是笼统区分了头文件和其他源文件。对于大型项目,要在众多的源文件中找到想要的那个是很恼火的事情。对此,Visual Studio提供了filter机制来分类显示源文件。对于手工维护工程文件的项目,我们可以自己添加filter,然后提交到代码库,并与其他成员共享。 但是,在使用CMake后,手工维护filter是不现实的。CMake也提供了可以生成filter的机制,就是source_group()命令。结合source_group(), file(), string()等命令,我们可以让实现CMake自动按目录结构生成filter。 方法很简单,代码如下:
代码语言:javascript复制macro(source_group_by_dir source_files)
if(MSVC)
set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR})
foreach(sgbd_file ${${source_files}})
string(REGEX REPLACE ${sgbd_cur_dir}/(.*) \1 sgbd_fpath ${sgbd_file})
string(REGEX REPLACE "(.*)/.*" \1 sgbd_group_name ${sgbd_fpath})
string(COMPARE EQUAL ${sgbd_fpath} ${sgbd_group_name} sgbd_nogroup)
string(REPLACE "/" "\" sgbd_group_name ${sgbd_group_name})
if(sgbd_nogroup)
set(sgbd_group_name "\")
endif(sgbd_nogroup)
source_group(${sgbd_group_name} FILES ${sgbd_file})
endforeach(sgbd_file)
endif(MSVC)
endmacro(source_group_by_dir)
代码语言:javascript复制 使用的时候,先在比较顶层的CMakeLists.txt中定义该宏。然后在添加工程(add_library或者add_executable)的CMakeLists.txt文件中调用该宏:
代码语言:javascript复制source_group_by_dir(all_files)
代码语言:javascript复制其中all_files是保存了所有文件名的变量。注意,这里用的是变量名,而没有引用其值。
一般这个文件列表可以用file()或者aux_source_directory()来得到。例如对于C 工程,通常是这样的:
代码语言:javascript复制file(GLOB_RECURSE project_headers *.h)
file(GLOB_RECURSE project_cpps *.cpp)
set(all_files ${project_headers} ${project_cpps})
source_group_by_dir(all_files)