cmake 输出相关信息
message(STATUS "CMake version: ${CMAKE_VERSION}") message(STATUS "CMake C compiler: ${CMAKE_C_COMPILER}") message(STATUS "CMake CXX compiler: ${CMAKE_CXX_COMPILER}") message(STATUS "Build directory: ${PROJECT_BINARY_DIR}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
判断是否被当作subproject
# Determine if is built as a subproject (using add_subdirectory) # or if it is the master project. if (NOT DEFINED XXX_MASTER_PROJECT) set(XXX_MASTER_PROJECT OFF) if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(XXX_MASTER_PROJECT ON) endif () message(STATUS "Is build as a master project: ${XXX_MASTER_PROJECT}") endif ()
生成compile_commands.json以供clangd使用
windows下需要使用Ninja,如果使用vscode则在设置里把
cmake.generator
设置为Ninja
# generate compile_commands.json set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
cmake设置rpath,unix下搜索同目录下的so文件
set(CMAKE_SKIP_BUILD_RPATH FALSE) # 加入rpath set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) # 表示编译的时候是否使用CMAKE_INSTALL_RPATH作为rpath路径 set(CMAKE_INSTALL_RPATH "\${ORIGIN}") # 设置rpath安装时的路径,${ORIGIN}代表运行时当前目录
cmake设置输出目录,解决windows下命令行生成目录不正确但是IDE生成目录正确的问题 一定要放在project命令后面
set(XXX_OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin) set(XXX_OUTPUT_LIB_DIR ${PROJECT_BINARY_DIR}/lib) set(XXX_OUTPUT_PDB_DIR ${PROJECT_BINARY_DIR}/pdb) set(XXX_PLUGINS_OUTPUT_DIR ${XXX_OUTPUT_DIR}/plugins) # do not set cmake internal variables in functions(not work...) # difference between windows and linux, see https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#runtime-output-artifacts set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${XXX_OUTPUT_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${XXX_OUTPUT_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${XXX_OUTPUT_LIB_DIR}) set(CMAKE_PDB_OUTPUT_DIRECTORY ${XXX_OUTPUT_PDB_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE} ${XXX_OUTPUT_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE} ${XXX_OUTPUT_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE} ${XXX_OUTPUT_LIB_DIR}) set(CMAKE_PDB_OUTPUT_DIRECTORY_${CMAKE_BUILD_TYPE} ${XXX_OUTPUT_PDB_DIR})
cmake开启fPIC
if (NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) # Otherwise we can't link .so libs with .a libs set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif()
cmake统一符号可见性,默认隐藏
if (XXX_MASTER_PROJECT AND NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET) set(CMAKE_CXX_VISIBILITY_PRESET hidden CACHE STRING "Preset for the export of private symbols") set_property(CACHE CMAKE_CXX_VISIBILITY_PRESET PROPERTY STRINGS hidden default) endif () if (XXX_MASTER_PROJECT AND NOT DEFINED CMAKE_VISIBILITY_INLINES_HIDDEN) set(CMAKE_VISIBILITY_INLINES_HIDDEN ON CACHE BOOL "Whether to add a compile flag to hide symbols of inline functions") endif ()
集成vcpkg toolchain
if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE) message(STATUS "VCPKG_ROOT: $ENV{VCPKG_ROOT}") set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") endif()
集成vcpkg manifest 一定要放在project命令之前
if (XXX_RUN_TEST) list(APPEND VCPKG_MANIFEST_FEATURES "tests") endif() if (XXX_BUILD_EXAMPLES) list(APPEND VCPKG_MANIFEST_FEATURES "examples") endif() if (XXX_BUILD_BENCHMARKS) list(APPEND VCPKG_MANIFEST_FEATURES "benchmarks") endif()
ctest集成gtest
enable_testing() file(GLOB_RECURSE source CONFIGURE_DEPENDS *.h *.cpp) find_package(GTest CONFIG REQUIRED) add_executable(test_main ${source}) target_link_libraries(test_main PRIVATE GTest::gtest) include(GoogleTest) gtest_discover_tests(test_main WORKING_DIRECTORY ${XXX_OUTPUT_DIR})
cmake 拷贝文件(如dll、exe等)到指定目录
set(DLL_PATH ******) set(OUTPUT_DIR ******) add_custom_command(TARGET XXX POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DLL_PATH} ${OUTPUT_DIR} COMMENT "Copying DLL to output directory" )