CMake杂记
1. 在编译过程中打印编印信息
- 执行命令cmake时追加:
-DCMAKE_VERBOSE_MAKEFILE=ON
- 在CMakeLists.txt中添加:
set(CMAKE_VERBOSE_MAKEFILEON ON)
2. 打印自定义变量及其值
get_cmake_property(_variableNames VARIABLES)
foreach (_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
3. 打印环境变量及其值
execute_process(COMMAND "${CMAKE_COMMAND}" "-E" "environment")
4. 多系统区分
if(WIN32)
# todo: windows action
elseif(APPLE)
# todo: mac action
elseif(UNIX)
# todo: linux action
endif()
5. windows下x64和x86区分
if(WINDOWS)
if(CMAKE_CL_64)
target_link_libraries (BarcodeReader "DBRx64")
else()
target_link_libraries (BarcodeReader "DBRx86")
endif()
else()
target_link_libraries (BarcodeReader "DynamsoftBarcodeReader")
endif()
6. 将pthread作为默认线程库
# add pthread library
find_package (Threads)
target_link_libraries(smt-logger ${CMAKE_THREAD_LIBS_INIT})
由于pthread不是linux的默认线程库,需要手动制定。
7. 设置构建类型
#set(CMAKE_BUILD_TYPE "Release")
#set(CMAKE_BUILD_TYPE "Debug")
#set(CMAKE_BUILD_TYPE "MinSizeRel")
#set(CMAKE_BUILD_TYPE "RelWithDebInfo")
8. 编译选项
add_definitions(-Wall)
可以通过add_definitions(xxx)
设置编译选项,
常见编译选项列表:
- -w: 关闭编译时的警告,也就是编译后不显示任何warning,因为有时在编译之后编译器会显示一些例如数据转换之类的警告,这些警告是我们平时可以忽略的。
- -Wall: 编译后显示所有警告。
- -W: 类似-Wall,会显示警告,但是只显示编译器认为会出现错误的警告。
9. TARGET的库属性设置
- 仅仅有静态
- IMPORT_LOCATION=lib路径
- 有动态库且静态库作为链接:
- IMPORTED_IMPLIB=lib路径
- IMPORTED_LOCATION=dll路径
// 区分操作系统cpu架构, include 得在project下面
project(smt-logger-test VERSION 0.1.0)
include(CMakeDetermineSystem)
10. 用于寻找依赖库
include(CMakeFindDependencyMacro)
find_dependency(Threads)
11. 给Window的Debug版本加后缀
if(MSVC)
set(CMAKE_DEBUG_POSTFIX "d")
endif()
12. 判断系统版本
project(app)
include(CMakeDetermineSystem)
13. 生成带版本的so文件
SET_TARGET_PROPERTIES(taos PROPERTIES VERSION 1.6.0.0 SOVERSION 1)
此时会生成如下文件:
libtaos.so -> libtaos.so.1*
libtaos.so.1 -> libtaos.so.1.6.0.0*
libtaos.so.1.6.0.0
14. Copy Qt DLL
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:Qt5::Core>
$<TARGET_FILE:Qt5::Widgets>
... etc ...
15. 打印CMake表达式的值
add_custom_command(TARGET Test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Runtime Dlls: $<TARGET_RUNTIME_DLLS:Test>")
add_custom_command(TARGET Test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Target File: $<TARGET_FILE:${PROJECT_NAME}>")
调试查看CMake的表达式值
16. 拷贝当前项目中别的模块生成的DLL库到example模块里
target_link_libraries(${PROJECT_NAME} PRIVATE
library1
library2)
# Copy the output dll files from library1 and library2 to current module's exe path.
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_RUNTIME_DLLS:${PROJECT_NAME}>
$<TARGET_FILE_DIR:${PROJECT_NAME}>)
这个功能必须cmake版本高于3.21以上才支持
17. QT部署(windeployqt)
if (WIN32)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND "$ENV{Qt5_DIR}/bin/windeployqt.exe" "$<TARGET_FILE:${PROJECT_NAME}>")
endif ()
需要定义Qt5_DIR
环境变量
18. CMake使用MSVC时支持UTF-8
if (WIN32)
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
endif ()
19. CMake 静态库与共享库生成
新建XXX_global.h文件,定义XXX_EXPORT
#ifndef XXX_GLOBAL_H #define XXX_GLOBAL_H #include <QtGlobal> // Define XXX_SHARED_LIB in you application if you want to link against the // sharted version of AppLog #if defined(_WIN32) && defined(XXX_SHARED_LIB) # if defined(XXX_LIBRARY) # define XXX_EXPORT Q_DECL_EXPORT # else # define XXX_EXPORT Q_DECL_IMPORT # endif #else # define XXX_EXPORT #endif #endif //XXX_GLOBAL_H
使用XXX_EXPORT
class XXX_EXPORT XXX { };
CMakeLists.txt,add_library的库类型由
BUILD_SHARED_LIBS
指定// BUILD_SHARED_LIBS默认为OFF option(BUILD_SHARED_LIBS "Specifies the type of libraries (SHARED or STATIC) to build" OFF) add_library(${PROJECT_NAME} ${XXX_HEADERS} ${XXX_SOURCES}) if (BUILD_SHARED_LIBS) target_compile_definitions(${PROJECT_NAME} PUBLIC -DXXX_SHARED_LIB) target_compile_definitions(${PROJECT_NAME} PRIVATE -DXXX_LIBRARY) endif()
如果使用了Conan,则在conanfile.py中加入
def generate(self): tc = CMakeToolchain(self) // ...... if self.options.shared == True: tc.variables["BUILD_SHARED_LIBS"] = "ON" else: tc.variables["BUILD_SHARED_LIBS"] = "OFF" // ...... tc.generate() tc = CMakeDeps(self) tc.generate() def package_info(self): // ...... if self.options.shared: self.cpp_info.defines = ["XXX_SHARED_LIB"]
20. CMake设置程序图标
- 在CMakeLists.txt同级目录下新建文件“
XXX.rc
”,并放入准备好的ico图标文件;在rc文件中添加以下内容
IDI_ICON1 ICON "product.ico"
- 在cmake文件中添加
add_executable(PROJECT_NAME
main.cpp
resource.rc
)
- 重新编译