CMake 提供了許多有用的目錄相關(guān)宏變量,用于在不同平臺上正確處理文件路徑。以下是完整的分類說明:
- 標準目錄變量
系統(tǒng)標準目錄
cmake
安裝目錄變量
CMAKE_INSTALL_PREFIX # 安裝根目錄 (/usr/local)
CMAKE_INSTALL_BINDIR # 可執(zhí)行文件目錄 (bin)
CMAKE_INSTALL_SBINDIR # 系統(tǒng)可執(zhí)行文件目錄 (sbin)
CMAKE_INSTALL_LIBDIR # 庫文件目錄 (lib 或 lib64)
CMAKE_INSTALL_INCLUDEDIR # 頭文件目錄 (include)
CMAKE_INSTALL_DATAROOTDIR # 數(shù)據(jù)文件根目錄 (share)
CMAKE_INSTALL_DATADIR # 數(shù)據(jù)文件目錄 (share)
CMAKE_INSTALL_DOCDIR # 文檔目錄 (share/doc)
CMAKE_INSTALL_MANDIR # man 手冊目錄 (share/man)
CMAKE_INSTALL_SYSCONFDIR # 配置文件目錄 (etc)
CMAKE_INSTALL_LOCALSTATEDIR # 本地狀態(tài)數(shù)據(jù)目錄 (var)
使用示例
cmake
cmake_minimum_required(VERSION 3.10)
project(MyProject)
# 設(shè)置安裝路徑
set(CMAKE_INSTALL_PREFIX "/opt/myapp")
# 安裝目標
install(TARGETS myapp
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES myheader.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproject
)
install(DIRECTORY docs/
DESTINATION ${CMAKE_INSTALL_DOCDIR}
)
- 項目目錄變量
項目相關(guān)目錄
cmake
項目根目錄
CMAKE_SOURCE_DIR # 頂層 CMakeLists.txt 所在目錄
CMAKE_BINARY_DIR # 構(gòu)建根目錄 (build)
CMAKE_CURRENT_SOURCE_DIR # 當前處理的 CMakeLists.txt 所在目錄
CMAKE_CURRENT_BINARY_DIR # 當前構(gòu)建目錄
CMAKE_CURRENT_LIST_DIR # 當前正在處理的 CMake 文件所在目錄
項目特定目錄
PROJECT_SOURCE_DIR # 項目 CMakeLists.txt 目錄
PROJECT_BINARY_DIR # 項目構(gòu)建目錄
<PROJECT-NAME>_SOURCE_DIR # 特定項目源碼目錄
<PROJECT-NAME>_BINARY_DIR # 特定項目構(gòu)建目錄
使用示例
cmake
cmake_minimum_required(VERSION 3.10)
project(MyApp)
message("源碼根目錄: ${CMAKE_SOURCE_DIR}")
message("構(gòu)建根目錄: ${CMAKE_BINARY_DIR}")
message("當前源碼目錄: ${CMAKE_CURRENT_SOURCE_DIR}")
message("項目源碼目錄: ${PROJECT_SOURCE_DIR}")
# 添加子目錄
add_subdirectory(${CMAKE_SOURCE_DIR}/src)
# 包含頭文件目錄
include_directories(${CMAKE_SOURCE_DIR}/include)
# 添加當前目錄的源文件
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
- 平臺特定目錄變量
Windows 目錄變量
cmake
Windows 特定路徑
CMAKE_WINDOWS_DIR # Windows 目錄
CMAKE_SYSTEM_DIR # 系統(tǒng)目錄
CMAKE_PROGRAMFILES_DIR # Program Files 目錄
Unix/Linux 目錄變量
cmake
Unix/Linux 標準路徑
CMAKE_ROOT # CMake 安裝根目錄
CMAKE_INSTALL_FULL_<DIR> # 完整安裝路徑
使用示例
cmake
# 平臺特定的安裝配置
if(WIN32)
set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_LIBDIR "lib")
set(CMAKE_INSTALL_DATADIR "share")
elseif(UNIX)
set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_LIBDIR "lib")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
set(CMAKE_INSTALL_LIBDIR "lib64")
endif()
endif()
- 模塊和包目錄變量
模塊搜索路徑
cmake
CMAKE_MODULE_PATH # CMake 模塊搜索路徑
CMAKE_PREFIX_PATH # 包搜索路徑
CMAKE_FIND_ROOT_PATH # 交叉編譯時的根路徑
使用示例
cmake
# 添加自定義模塊路徑
list(APPEND CMAKE_MODULE_PATH
${CMAKE_SOURCE_DIR}/cmake
${CMAKE_SOURCE_DIR}/cmake/modules
)
# 添加包搜索路徑
list(APPEND CMAKE_PREFIX_PATH
/opt/local
/usr/local
${CMAKE_SOURCE_DIR}/third_party
)
# 查找包
find_package(OpenSSL REQUIRED)
find_package(Boost COMPONENTS filesystem system)
- 編譯器相關(guān)目錄變量
編譯器路徑
cmake
CMAKE_C_COMPILER # C 編譯器路徑
CMAKE_CXX_COMPILER # C++ 編譯器路徑
CMAKE_COMPILER_IS_GNUCC # 是否是 GNU C 編譯器
CMAKE_COMPILER_IS_GNUCXX # 是否是 GNU C++ 編譯器
使用示例
cmake
# 檢查編譯器
message("C 編譯器: ${CMAKE_C_COMPILER}")
message("C++ 編譯器: ${CMAKE_CXX_COMPILER}")
# 編譯器特定設(shè)置
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
endif()
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
- 完整項目示例
項目目錄結(jié)構(gòu)
text
myproject/
├── CMakeLists.txt
├── cmake/
│ └── FindMyLib.cmake
├── src/
│ ├── CMakeLists.txt
│ └── main.cpp
├── include/
│ └── myproject/
│ └── header.h
├── third_party/
│ └── somelib/
└── tests/
└── CMakeLists.txt
頂層 CMakeLists.txt
cmake
cmake_minimum_required(VERSION 3.15)
project(MyProject VERSION 1.0.0 LANGUAGES C CXX)
# 設(shè)置 C++ 標準
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 目錄變量輸出
message(STATUS "項目信息:")
message(STATUS " 項目名稱: ${PROJECT_NAME}")
message(STATUS " 項目版本: ${PROJECT_VERSION}")
message(STATUS " 源碼目錄: ${CMAKE_SOURCE_DIR}")
message(STATUS " 構(gòu)建目錄: ${CMAKE_BINARY_DIR}")
message(STATUS " 當前目錄: ${CMAKE_CURRENT_SOURCE_DIR}")
# 添加模塊搜索路徑
list(APPEND CMAKE_MODULE_PATH
${CMAKE_SOURCE_DIR}/cmake
${CMAKE_CURRENT_SOURCE_DIR}/cmake
)
# 添加包搜索路徑
list(APPEND CMAKE_PREFIX_PATH
${CMAKE_SOURCE_DIR}/third_party
)
# 安裝目錄配置
include(GNUInstallDirs)
# 自定義安裝目錄
set(MYPROJECT_INCLUDE_INSTALL_DIR
${CMAKE_INSTALL_INCLUDEDIR}/myproject
)
set(MYPROJECT_CMAKE_INSTALL_DIR
${CMAKE_INSTALL_LIBDIR}/cmake/myproject
)
# 添加子目錄
add_subdirectory(src)
add_subdirectory(tests)
# 安裝配置
install(
DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
)
# 導(dǎo)出包配置
install(EXPORT MyProjectTargets
FILE MyProjectTargets.cmake
NAMESPACE MyProject::
DESTINATION ${MYPROJECT_CMAKE_INSTALL_DIR}
)
src/CMakeLists.txt
cmake
# 打印當前目錄信息
message(STATUS "源碼構(gòu)建目錄: ${CMAKE_CURRENT_BINARY_DIR}")
# 添加源文件
set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utils.cpp
)
# 添加頭文件目錄
include_directories(
${CMAKE_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR} # 用于生成的頭文件
)
# 創(chuàng)建可執(zhí)行文件
add_executable(myapp ${SOURCES})
# 設(shè)置輸出目錄
set_target_properties(myapp PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
)
# 安裝目標
install(TARGETS myapp
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
- 高級目錄管理
自定義目錄變量
cmake
# 定義項目特定的目錄變量
set(MYPROJECT_SRC_DIR ${CMAKE_SOURCE_DIR}/src)
set(MYPROJECT_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
set(MYPROJECT_TEST_DIR ${CMAKE_SOURCE_DIR}/tests)
set(MYPROJECT_BUILD_DIR ${CMAKE_BINARY_DIR})
set(MYPROJECT_OUTPUT_DIR ${CMAKE_BINARY_DIR}/output)
# 創(chuàng)建自定義目錄
file(MAKE_DIRECTORY ${MYPROJECT_OUTPUT_DIR}/bin)
file(MAKE_DIRECTORY ${MYPROJECT_OUTPUT_DIR}/lib)
file(MAKE_DIRECTORY ${MYPROJECT_OUTPUT_DIR}/include)
# 設(shè)置輸出目錄
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${MYPROJECT_OUTPUT_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MYPROJECT_OUTPUT_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MYPROJECT_OUTPUT_DIR}/bin)
路徑操作函數(shù)
cmake
# 獲取相對路徑
get_filename_component(RELATIVE_PATH
${CMAKE_CURRENT_SOURCE_DIR}
RELATIVE ${CMAKE_SOURCE_DIR}
)
# 獲取絕對路徑
get_filename_component(ABSOLUTE_PATH
"include/myheader.h"
ABSOLUTE
BASE_DIR ${CMAKE_SOURCE_DIR}
)
# 路徑拼接
set(FULL_INCLUDE_PATH
${CMAKE_SOURCE_DIR}/include
)
# 檢查路徑是否存在
if(EXISTS ${FULL_INCLUDE_PATH})
message(STATUS "包含目錄存在: ${FULL_INCLUDE_PATH}")
else()
message(WARNING "包含目錄不存在: ${FULL_INCLUDE_PATH}")
endif()
- 交叉編譯目錄設(shè)置
交叉編譯配置
cmake
# 設(shè)置交叉編譯工具鏈
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# 工具鏈路徑
set(TOOLCHAIN_DIR /opt/arm-toolchain)
set(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-g++)
# 系統(tǒng)根目錄
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR}/arm-linux-gnueabihf)
# 只在目標系統(tǒng)中查找?guī)?set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
- 實用調(diào)試技巧
調(diào)試目錄變量
cmake
# 打印所有目錄變量
function(print_directory_variables)
message(STATUS "=== 目錄變量 ===")
message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(STATUS "PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")
message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}")
message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
endfunction()
# 在需要的地方調(diào)用
print_directory_variables()