CMake cheatsheet - Serbipunk/notes GitHub Wiki

execute_process

https://cmake.org/cmake/help/v3.0/command/execute_process.html

add_custom_command

https://zhuanlan.zhihu.com/p/95771200

add_custom_command(TARGET ${EXE1}
                   PRE_BUILD
                   COMMAND ${CMAKE_COMMAND} -E echo oj8k
                   VERBATIM
)

PRE_BUILD | POST_BUILD

example:

FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)

FetchContent_Declare(
  <name>
  <contentOptions>...
  [EXCLUDE_FROM_ALL]
  [SYSTEM]
  [OVERRIDE_FIND_PACKAGE |
   FIND_PACKAGE_ARGS args...]
)

CMake cheatsheet

builtin variables

https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html

cmake-variables

https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html

include

Load and run CMake code from a file or module. https://cmake.org/cmake/help/latest/command/include.html

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]
                      [NO_POLICY_SCOPE])

source_group

定义了一个源文件的group,在IDE project生成时。生成源文件group时,有2种签名。

source_group(<name> [FILES <src>...] [REGULAR_EXPRESSION <regex>])

source_group ("${_target_folder}" FILES "${_file}")

os platform

Detect Microsoft Windows

if(WIN32)
    # for Windows operating system in general
endif()

Or:

if(MSVC OR MSYS OR MINGW)
    # for detecting Windows compilers
endif()

Detect Apple MacOS

if(APPLE)
    # for MacOS X or iOS, watchOS, tvOS (since 3.10.3)
endif()

Detect Unix and Linux

if(UNIX AND NOT APPLE)
    # for Linux, BSD, Solaris, Minix
endif()

dirs

${CMAKE_CURRENT_SOURCE_DIR} 貌似是 CMakeLists.txt 的文件夹

find_package

find_package(OpenCV)
MESSAGE("### opencv found: ${OpenCV_FOUND}")

target_link_libraries的库属性

https://blog.csdn.net/turbock/article/details/90034787

当创建动态库时,

  • 如果源文件(例如CPP)中包含第三方头文件,但是头文件(例如hpp)中不包含该第三方文件头,采用PRIVATE。
  • 如果源文件和头文件中都包含该第三方文件头,采用PUBLIC。
  • 如果头文件中包含该第三方文件头,但是源文件(例如CPP)中不包含,采用 INTERFACE。

message

message([STATUS] "CMAKE_BINARY_DIR: " ${CMAKE_BINARY_DIR})

define output directory

SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)

target_link_libraries的属性

https://cmake.org/cmake/help/v3.0/command/target_link_libraries.html

https://blog.csdn.net/turbock/article/details/90034787

当创建动态库时,

如果源文件(例如CPP)中包含第三方头文件,但是头文件(例如hpp)中不包含该第三方文件头,采用PRIVATE。
如果源文件和头文件中都包含该第三方文件头,采用PUBLIC。
如果头文件中包含该第三方文件头,但是源文件(例如CPP)中不包含,采用 INTERFACE。

命令表

命令 含义 例子 文档 额外注释
add_executable 编译连接某些cpp
成为可执行文件
add_executable(Hello
src/main.cpp src/foo.cpp)
来自例子1
add_executable( <name> [WIN32]
[MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
如果使用target_sources()
则cpp文件可省略
set 设置变量(正常、<br>高速缓存、环境变量) SET(APP_NAME test) set(<variable> <value>... [PARENT_SCOPE]) PARENT_SCOPE是<br>cmake的特殊机制
TARGET_LINK_LIBRARIES 明确编译目标的
依赖库或gflags
target_link_libraries(Hello Foo)
来自例子6
TARGET_LINK_LIBRARIES(${APP_NAME}

${PROJECT_SOURCE_DIR}/Lib/libfswaplib.so
${OPENGL_LIBRARIES}
...
)
target_link_libraries(<target> ... <item>... ...) item可以的类型:1.库target 2.库完整路径 3.库简化名称 4.连接符号 5. 表达式
add_library 添加库作为target [ADD_LIBRARY(${LIBRARY_NAME} SHARED ${include} ${include_api} ${include_seeta} ${src} ${utils}) add_library(<name> [STATIC / SHARED / MODULE]
[EXCLUDE_FROM_ALL] source1 [source2 ...])](https://cmake.org/cmake/help/v3.0/command/add_library.html?highlight=add_library)
里面关于c系列动态库、
静态库、module库描述
相当简短准确
ADD_DEFINITIONS 编译过程添加define宏变量 ADD_DEFINITIONS(-DPROJ_PATH="${CMAKE_SOURCE_DIR}/") add_definitions(-DFOO -DBAR ...) 类似make中的-D
FIND_PACKAGE 检查依赖软件(?用什么方法) FIND_PACKAGE( Boost COMPONENTS filesystem system thread REQUIRED) find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED]
COMPONENTS] [components...
[OPTIONAL_COMPONENTS components...] <br> [NO_POLICY_SCOPE])
ni
INCLUDE_DIRECTORIES 添加包含文件路径 INCLUDE_DIRECTORIES(
/usr/local/include
${OpenCV_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}/../caffe_deploy/include
)
link 最终路径,插入等,还可以用target_include_directories()、set_property()等查看
link_directories 设置链接器等搜索路径 link_directories(
/usr/lib
${OpenCV_LIB_DIR}
)
link_directories(directory1 directory2 ...) !大写的LINK_DIRECTORIES和link_directories并不相同,一个是只读,一个是设置
AUX_SOURCE_DIRECTORY 赋值出该目录下所有源文件 AUX_SOURCE_DIRECTORY(./include include)
AUX_SOURCE_DIRECTORY(./include/c_api include_api)
aux_source_directory(<dir> <variable>) ni
target_link_libraries 明确指出编译目标时链接的库与flags TARGET_LINK_LIBRARIES(${LIBRARY_NAME}
${PROJECT_SOURCE_DIR}/../caffe_deploy/build/lib/libcaffe.so
/usr/lib/x86_64-linux-gnu/libglut.so
)
target_link_libraries(<target> [item1 [item2 [...]]][[debug/optimized/general] <item>] ...) ni
add_subdirectory 在build目录中
建立子文件夹
ADD_SUBDIRECTORY(main_tests) add_subdirectory(source_dir [binary_dir] <br> [EXCLUDE_FROM_ALL]) ni
cmake_policy 恢复历史版本的cmake特性,以免除生成的bug
include include(cmake/Dependencies.cmake)
FetchContent 获取三方库 FetchContent_Declare(pybind11\nGIT_PROGRESS TRUE \n GIT_SHALLOW TRUE \n GIT_REPOSITORY https://github.com/pybind/pybind11.git \n GIT_TAG v2.10.4 \n ) FetchContent_Declare(<name><contentOptions>...[EXCLUDE_FROM_ALL][SYSTEM][OVERRIDE_FIND_PACKAGE)

可能的宏定义

PROJECT_SOURCE_DIR

CMAKE_MODULE_PATH

all cpp as exe

macro(ncnn_add_example name)
    add_executable(${name} ${name}.cpp)
    target_include_directories(${name} PRIVATE ${OpenCV_INCLUDE_DIRS})
    target_link_libraries(${name} PRIVATE ncnn ${OpenCV_LIBS})

    # add test to a virtual project group
    set_property(TARGET ${name} PROPERTY FOLDER "examples")
endmacro()

find_package(OpenCV QUIET COMPONENTS opencv_world)
# for opencv 2.4 on ubuntu 16.04, there is no opencv_world but OpenCV_FOUND will be TRUE
if("${OpenCV_LIBS}" STREQUAL "")
    set(OpenCV_FOUND FALSE)
endif()
if(NOT OpenCV_FOUND)
    find_package(OpenCV QUIET COMPONENTS core highgui imgproc imgcodecs videoio)
endif()
if(NOT OpenCV_FOUND)
    find_package(OpenCV QUIET COMPONENTS core highgui imgproc)
endif()

if(OpenCV_FOUND)
    message(STATUS "OpenCV library: ${OpenCV_INSTALL_PATH}")
    message(STATUS "    version: ${OpenCV_VERSION}")
    message(STATUS "    libraries: ${OpenCV_LIBS}")
    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
    
    if(${OpenCV_VERSION_MAJOR} GREATER 3)
        set(CMAKE_CXX_STANDARD 11)
    endif()
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src)
    include_directories(${CMAKE_CURRENT_BINARY_DIR}/../src)

    ncnn_add_example(squeezenet)
    ncnn_add_example(squeezenet_c_api)
    ncnn_add_example(fasterrcnn)
    ncnn_add_example(rfcn)
    ncnn_add_example(yolov2)
    ncnn_add_example(yolov3)
    ncnn_add_example(yolov4)
    ncnn_add_example(mobilenetv2ssdlite)
    ncnn_add_example(mobilenetssd)
    ncnn_add_example(squeezenetssd)
    ncnn_add_example(shufflenetv2)
    ncnn_add_example(peleenetssd_seg)
    ncnn_add_example(simplepose)
    ncnn_add_example(retinaface)
    ncnn_add_example(yolact)
else()
    message(WARNING "OpenCV not found, examples won't be built")
endif()
⚠️ **GitHub.com Fallback** ⚠️