CMake 常用操作指令

1、设置CMake的版本

cmake_minimum_required(VERSION 3.6)

2、设置当前项目的名称

project(project_name)

3、设置当前项目中使用C++的版本

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

4、设置要包含头文件的路径

include_directories(directories)

5、设置要链接库的路径

link_directories(directories)

6、设置输出路径

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY path)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY path)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY path)
set(EXECUTABLE_OUTPUT_PATH path)

例子:
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../output/bin/${Configuration})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../output/bin/${Configuration})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../output/bin/${Configuration})
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../output/bin/${Configuration})

7、搜集某个目录下面的源文件

aux_source_directory(${CMAKE_SOURCE_DIR}/src SRCS)

8、生成静态库或动态库

add_library(library_name ${source}) // 默认静态
add_library(library_name SHARED/STATIC ${source})

9、生成可执行程序

add_executable(exec ${SRCS})

10、设置要链接的库

target_link_libraries(name link_name)
比如
target_link_libraries(cmake_exec test_lib)

11、设置链接时候的一些参数

add_link_options(options)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} options")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} options")
例如(Windows下):
# 增量连接
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNOREIDL /INCREMENTAL")
# 设置def
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEF:${CMAKE_CURRENT_SOURCE_DIR}/dll/wemeet.def")

12、添加子目录

add_subdirectory(subdirectory)

 如果不是子目录应该怎么办

add_subdirectory(directory target)

13、划分目录结构

source_group
一般的用法如下:
source_group(common REGULAR_EXPRESSION *.*/common/*.*)
这样会将common目录下面的文件全部分组为common

14、执行系统命令

execute_process
比如运行一个python脚本:
execute_process(COMMAND python copy.py WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/scripts)
备注:
WORKING_DIRECTORY :表示在哪个目录下执行
copy.py里面就是把一个文件从一个目录拷贝到另外一个目录

15、字符串比较

STREQUAL 相等比较
STRLESS 小于
STRGREATER 大于
使用方法:if("hello" STREQUAL "hello")

16、输出调试打印信息,类似于printf

message("hello")

17、判断某个变量是否设置了

if(DEFINED var)

设置环境变量

set(ENV{var} var)

18、判断文件是否存在

if(EXISTS file)

19、判断CMake创建的逻辑目标是否存在

if(TARGET name)
逻辑目标:
add_executable(exec ${SRCS})
这里的exec就是逻辑目标,所以可以写为
if(TARGET exec)

20、设置依赖

ADD_DEPENDENCIES
表示某个工程必须在它之前被执行
比如:
target_link_libraries(cmake_exec test_lib)
表示cmake_exec要连接test_lib,那么我们就要保证test_lib必须在cmake_exec之前生成,这个时候就可以使用ADD_DEPENDENCIES
ADD_DEPENDENCIES(cmake_exec test_lib)

21、设置自定义命令,具体操作可查看文档

add_custume_command

举个例子,比如我们有的时候想在编译之前、链接之前或者在所有项目生成之后执行某些命令,可以这么做

PRE_BUILD:编译之前
PRE_LINK:链接之前
POST_BUILD:所有操作执行之后

具体操作可参考:

add_custom_command(TARGET wemeet
                   PRE_BUILD
                   COMMAND ${CMAKE_SOURCE_DIR}/scripts/copy_file.bat
                   COMMENT "copy file")

22、设置fpic

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

23、创建函数

macro(<name> [arg1])
endmacro(<name>)

比如设置一个函数,按照目录对源文件进行分组

  根据目录划分target

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
macro(set_target_folder_if_exist target folder)
  if(TARGET ${target})
    set_target_properties(${target} PROPERTIES FOLDER ${folder})
  endif()
endmacro()
调用:
set_target_folder_if_exist(cmake_exe cmake)

24、设置警告的等级

add_definitions("/W4 /WX")
也就是将警告视为错误

25、cmake判断平台

Windows平台判断:
if(WIN32)
endif()
LINUX平台判断:
if(UNIX AND NOT APPLE AND NOT ANDROID)
endif()
MAC平台判断:
if(APPLE)
endif()

26、cmake设置编译为release

# SET(CMAKE_BUILD_TYPE Release)   # 这条命令在Windows下面设置不生效
SET(CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "" FORCE)

27、cmake 区别平台,目前 Windows,Linux,Android,Mac 平台都可以很好的区分,但是没有想到怎么区分 iOS

if(WIN32)
  message("WIN32")
elseif(UNIX AND NOT APPLE AND NOT ANDROID)
  message("LINUX")
elseif(ANDROID)
  message("ANDROID")
elseif(APPLE)
  message("APPLE")
else()
  message("else")
endif()

下面是一些在Windows上常用到的指令

27、设置unicode编码

add_definitions(-DUNICODE -D_UNICODE)

28、release模式下生成pdb文件

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")

29、设置多处理器编译

add_definitions("/MP")

30、设置默认启动项

set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT app_name)

31、引入外部的工程

include_external_msproject
比如外面的一个工程是vcxproj的,但是要在cmake里面使用到就可以这么做
include_external_msproject(cmake_test ${CMAKE_SOURCE_DIR}/../../test/cmake_test.vcxproj)

32、使用预编译头

macro(use_precompiled_header TARGET HEADER_FILE SRC_FILE)
  get_filename_component(HEADER ${HEADER_FILE} NAME)
  if (MSVC AND NOT NMAKE AND NOT OGRE_UNITY_BUILD)
    set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /Yu"${HEADER}")
    set_source_files_properties(${SRC_FILE} PPROPERTIES COMPILE_FLAGS /Yc"${HEADER}")
  elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX)
  endif ()
endmacro()
比如:
use_precompiled_header(cmake_exe ${CMAKE_SOURCE_DIR}/src/stdafx.h
                                 ${CMAKE_SOURCE_DIR}/src/stdafx.cpp)

33、当把警告视为错误的时候,屏蔽掉一些警告

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4100 /wd4505 /wd4996")

34、强制指定Windows sdk的版本号,注意要写在project之前,在设置完cmake_minimum_required之后就需要指定,不然可能会不生效

set(CMAKE_SYSTEM_VERSION "10.0.17763.0" CACHE STRING INTERNAL FORCE)
set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION "10.0.17763.0" CACHE STRING INTERNAL FORCE)



CMake 中 macro、function

1、ARGC,ARGV,ARGN 的含义

ARGC:记录传入的参数个数
ARGV:包含所有传入参数的 list
ARGN:包含传入参数的 list,这个 list 是指 macro、function 指定参数之后的所有参数

测试代码1

function(file_source_group_1)
  message("=== file_source_group_1 ===")
  message(${ARGC})
  message(${ARGV})
  message(${ARGN})
  message("=== file_source_group_1 ===")
endfunction(file_source_group_1)

file_source_group_1(hello include/hello.hpp src/hello.cpp)

输出结果1

=== file_source_group_1 ===
3
helloinclude/hello.hppsrc/hello.cpp
helloinclude/hello.hppsrc/hello.cpp
=== file_source_group_1 ===

可见,如果 function 后面不指定任何参数,那么 ARGV 和 ARGN 结果是一样的

测试代码2

function(file_source_group_2 hello)
  message("=== file_source_group_2 ===")
  message(${ARGC})
  message(${ARGV})
  message(${ARGN})
  message("=== file_source_group_2 ===")
endfunction(file_source_group_2)

file_source_group_2(hello include/hello.hpp src/hello.cpp)

输出结果2

=== file_source_group_2 ===
3
helloinclude/hello.hppsrc/hello.cpp
include/hello.hppsrc/hello.cpp
=== file_source_group_2 ===

在 function(file_source_group_2 hello) 函数里面多指定了一个参数,标识第一个传入的参数用 hello 捕获,这个时候 ARGV 还是所有的参数 list,但是 ARGN 是除了第一个参数的所有参数了

2、使用 function 自动生成 VS 的目录

function(add_source_group file_source)
  # 如果给定路径是一个绝对路径
  if (IS_ABSOLUTE "${file_source}")
    file(RELATIVE_PATH source_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${file_source}")
  else()
    set(source_rel "${file_source}")
  endif()
  get_filename_component(source_dir "${source_rel}" PATH)
  # string(REPLACE "/" "\\" dir_name "${source_path}")
  source_group("${source_dir}" FILES "${file_source}")
endfunction()

function(file_source_group)
  foreach(file_source IN ITEMS ${ARGN})
    add_source_group(${file_source})
  endforeach()
endfunction(file_source_group)

set(DEMO_SOURCE
    ${CMAKE_CURRENT_SOURCE_DIR}/include/hello.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/src/hello.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/include/123/test.h
    )

file_source_group(${DEMO_SOURCE})



CMake常见的宏

1、CMAKE_SOURCE_DIR :工程顶层目录所在的路径

2、CMAKE_CURRENT_SOURCE_DIR:当前CMakeLists.txt所在的路径,建议使用CURRENT_SOURCE,不建议使用SOURCE_DIR,因为如果主工程目录改变了,SOURCE_DIR也就会改变,很容易造成编译错误

3、CMAKE_BINARY_DIR:工程编译时的路径

4、PROJECT_NAME:工程名字

5、EXECUTABLE_OUTPUT_PATH:可执行文件的输出路径

6、LIBRARY_OUTPUT_PATH:库的输出路径
 




编译

 Linux

cmake .   // .表示CMakeLists.txt所在的路径,也可以新建一个build目录去编译
make

Windows

cmake .
然后使用vs打开生成的sln文件

cmake -G "Visual Studio 15 Win64" .
编译 64 位,默认生成是 32 位

Mac

cmake -G "XCode" .
然后使用XCode打开

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值