CMake笔记


判断系统平台

if(WIN32)
    # Windows
elseif(UNIX)
    # Linux、MacOs
endif()

判断编译器

不同的编译器有不同的编译链接参数,所以需要判断。

if(MSVC)
    # Visual Studio
elseif(MINGW)
    # MinGW
elseif(MSYS)
    # MSYS
elseif(CYGWIN)
    # Cygwin
elseif(APPLE)
    # MacOs、iOS, watchOS、tvOS
endif()

获取编译器位数

一般用于检查当前工具链是32位还是64位

if (CMAKE_SIZEOF_VOID_P EQUAL 8)
    # 64 bit
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
    # 32bit
else()
    # other
endif()

DOC:https://cmake.org/cmake/help/latest/variable/CMAKE_SIZEOF_VOID_P.html

判断Debug、Release等模式

CMake有几个内置的编译参数Debug、Release、RelWithDebInfo、MinSizeRel,在脚本中通过检查字符串来判断。

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    # is debug
endif()

DOC:https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html

修改静态库与共享库的前后缀

# 静态库前缀与后缀
message(STATUS ${CMAKE_STATIC_LIBRARY_PREFIX})
message(STATUS ${CMAKE_STATIC_LIBRARY_SUFFIX})

# 共享库前缀与后缀
message(STATUS ${CMAKE_SHARED_LIBRARY_PREFIX})
message(STATUS ${CMAKE_SHARED_LIBRARY_SUFFIX})

在UNIX系统上,库文件默认是以lib开头的,如果想去掉它,可以这样做

set(CMAKE_STATIC_LIBRARY_PREFIX "")
set(CMAKE_SHARED_LIBRARY_PREFIX "")

修改输出文件名

输出文件名默认是和工程名称一致的,修改OUTPUT_NAME属性可以改变输出文件名称。

set_target_properties(${Target} PROPERTIES OUTPUT_NAME "new")

DOC:https://cmake.org/cmake/help/latest/prop_tgt/OUTPUT_NAME.html

指定二进制文件输出位置

# lib文件
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "...")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "...")

# exe、dll文件
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "...")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "...")

生成Win32 GUI程序

EXE项目默认是控制台程序,如果要生成GUI程序则要指定为WIN32

add_executable(Demo WIN32)

DOC:https://cmake.org/cmake/help/latest/command/add_executable.html

MSVC设置MT参数

VS工程默认是用/MD编译的(依赖VC运行库),若要生成不依赖VC运行库的文件则需要修改为/MT

if(MSVC)
    # MTd、MT
    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>")
endif()

DOC:https://cmake.org/cmake/help/git-stage/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html

MSVC添加UAC支持

按照现代CMake写法,应该使用target_link_options才对,但是实测发现没有效果,不知道是不是BUG。所以得直接修改LINK_FLAGS

if(MSVC)
    set_target_properties(${Target} PROPERTIES LINK_FLAGS "/MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\"")
endif()

禁用清单文件

if(MSVC)
    target_link_options(${Target} PRIVATE /MANIFEST:NO)
endif()

指定DEF文件

一般用于指定导出函数。

if(MSVC)
    target_link_options(${Target} PRIVATE /DEF:exports.def)
endif()

指定C++语言标准

# 使用C++20
set(CMAKE_CXX_STANDARD 20)

DOC:https://cmake.org/cmake/help/latest/variable/CMAKE_CXX_STANDARD.html