CMake 使用札记
目录
本篇记录在使用 CMake 中遇到的一些问题及解决办法
参考资料:
- https://cmake.org/
- https://cmake.org/cmake/help/v3.0/manual/cmake-commands.7.html
- https://en.wikipedia.org/wiki/CMake
Q : shared library for Visual Studio,只生成了 .dll, 没有生成 .lib
if(MSVC_VERSION)
set_target_properties(${PROJECT_NAME} PROPERTIES
LINK_FLAGS " /INCREMENTAL:NO /MANIFEST /NOLOGO"
#COMPILE_FLAGS "-DHELLO_EXPORTS" #ajouté in last a verif demin
)
endif(MSVC_VERSION)
Q : 如何获取文件夹下所有文件
使用 file 命令 及 GLOB 或 GLOB_RECURSE flag, GLOB 可以根据 globbing expressions 类正则表达式 生成匹配的文件的列表。它经常用于获取文件夹下的所有源文件。需要注意的是,这个表达式只是类似正则表达式(similar to regular expressions),它和正则表达式是有区别的
GLOB_RECURSE 则可以递遍历指定路径下的所有文件:
*.cxx - match all files with extension cxx *.vt? - match all files with extension vta,…,vtz f[3-5].txt - match files f3.txt, f4.txt, f5.txt
例:
file(GLOB SRC_FILES
"*.cpp"
"subdir/*.cpp"
)
file(GLOB_RECURSE SRC_FILES #递归
"*.cpp"
)
Q : 如何在 Visual Studio 中保持源文件目录结构
使用 source_group 来对 VS 的源文件进行分组:
function(assign_source_group)
foreach(_source IN ITEMS ${ARGN})
if (IS_ABSOLUTE "${_source}")
file(RELATIVE_PATH _source_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${_source}")
else()
set(_source_rel "${_source}")
endif()
get_filename_component(_source_path "${_source_rel}" PATH)
string(REPLACE "/" "\\" _source_path_msvc "${_source_path}")
source_group("${_source_path_msvc}" FILES "${_source}")
endforeach()
endfunction(assign_source_group)
function(my_add_executable)
foreach(_source IN ITEMS ${ARGN})
assign_source_group(${_source})
endforeach()
add_executable(${PROJECT_NAME} ${ARGN})
endfunction(my_add_executable)
function(my_add_shared)
foreach(_source IN ITEMS ${ARGN})
assign_source_group(${_source})
endforeach()
add_library(${PROJECT_NAME} SHARED ${ARGN})
endfunction(my_add_shared)
my_add_shared(${SRC_FILES})
Q : 如何从源文件列表中删除某个文件
可以使用 list 命令 及 REMOVE_ITEM flag。
例子:从源文件列表中删除文件 c.h, c.cpp:
cmake_minimum_required(VERSION 3.9)
file(GLOB SRC_FILES
"*.h"
"*.cpp"
"subdir/*.h"
"subdir/*.cpp"
)
message(${SRC_FILES})
foreach(_src IN ITEMS ${SRC_FILES})
if(${_src} MATCHES "c\.(h|cpp)$")
message("file to remove ${_src}")
list(APPEND RMV_FILES ${_src})
#set(RMV_FILES "${RMV_FILES};${_src}") #the same
endif()
endforeach(_src IN ITEMS ${SRC_FILES})
foreach(_f IN ITEMS ${RMV_FILES})
message("remove file ${_f}")
list(REMOVE_ITEM SRC_FILES ${_f})
endforeach(_f IN ITEMS ${RMV_FILES})
message(${SRC_FILES})
Q : 如何修改生成文件的路径
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${you_path}) #static
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${you_path}) #shared
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${you_path}) #exec