KMPKG Portfile 内置变量全解析
KMPKG 会为每个端口的 portfile.cmake 自动注入一系列只读内置变量,用于适配不同编译目标、系统环境和路径规则,禁止端口代码修改这些变量。以下是按用途分类的完整解读(含实操示例)。
一、基础标识变量
1. PORT
- 作用:当前正在构建的端口名称(与
ports/下的目录名一致)。 - 使用场景:动态拼接路径、日志输出、目标命名等。
- 示例:
# 输出当前构建的端口名
message(STATUS "Building port: ${PORT}")
# 拼接端口专属安装路径
set(PORT_CONFIG_DIR "${CURRENT_INSTALLED_DIR}/share/${PORT}")
2. VERSION
- 作用:当前端口的上游版本号(不含
port-version修订号,如端口版本1.0.0#2时,VERSION为1.0.0)。 - 使用场景:源码下载、版本相关配置、文件名拼接。
- 示例:
# 从自定义地址下载对应版本的源码包
kmpkg_download_distfile(
URL "https://example.com/${PORT}-${VERSION}.tar.gz"
SHA512 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)
3. TARGET_TRIPLET
- 作用:当前编译目标的三元组名称(如
x64-uwp、arm64-linux、x86-mingw)。 - 使用场景:区分不同编译目标的构建逻辑、路径适配。
- 示例:
# 针对 UWP 三元组调整编译参数
if(TARGET_TRIPLET STREQUAL "x64-uwp")
kmpkg_cmake_configure(SOURCE_PATH ${SOURCE_PATH} OPTIONS "-DUWP_BUILD=ON")
endif()
4. HOST_TRIPLET
- 作用:构建机(宿主)对应的三元组名称(如 Windows 主机为
x64-windows,macOS 主机为x64-osx)。 - 使用场景:区分宿主/目标环境的工具链路径。
- 示例:
# 从宿主安装目录获取构建工具
set(HOST_TOOL "${CURRENT_HOST_INSTALLED_DIR}/bin/make${KMPKG_HOST_EXECUTABLE_SUFFIX}")
二、系统判定变量
1. 目标系统判定:KMPKG_TARGET_IS_<system>
- 作用:判定编译目标系统(如 UWP、Linux、Android),匹配时值为
TRUE,否则未定义。 - 支持的系统值:
变量 匹配场景 KMPKG_TARGET_IS_WINDOWSWindows(含 UWP、MinGW) KMPKG_TARGET_IS_UWP仅 UWP(Windows 运行时) KMPKG_TARGET_IS_MINGW仅 MinGW 环境 KMPKG_TARGET_IS_LINUXLinux 系统 KMPKG_TARGET_IS_OSXmacOS 系统 KMPKG_TARGET_IS_IOSiOS 系统 KMPKG_TARGET_IS_ANDROIDAndroid 系统 KMPKG_TARGET_IS_FREEBSDFreeBSD 系统 KMPKG_TARGET_IS_OPENBSDOpenBSD 系统 KMPKG_TARGET_IS_EMSCRIPTENEmscripten(Wasm)环境 - 示例:
# UWP 目标禁用动态库,强制静态编译
if(KMPKG_TARGET_IS_UWP)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
endif()
# Linux 目标链接 pthread 库
if(KMPKG_TARGET_IS_LINUX)
target_link_libraries(${PORT} PRIVATE pthread)
endif()
2. 宿主系统判定:KMPKG_HOST_IS_<system>
- 作用:判定构建机系统(宿主环境),匹配时值为
TRUE,否则未定义。 - 支持的系统值:
WINDOWS/OSX/LINUX/FREEBSD/OPENBSD。 - 使用场景:适配宿主系统的工具链、路径分隔符、可执行文件后缀。
- 示例:
# Windows 宿主使用批处理脚本,Linux/macOS 宿主使用 shell 脚本
if(KMPKG_HOST_IS_WINDOWS)
set(SCRIPT_PATH "${SOURCE_PATH}/build.bat")
else()
set(SCRIPT_PATH "${SOURCE_PATH}/build.sh")
execute_process(COMMAND chmod +x ${SCRIPT_PATH})
endif()
三、路径/可执行文件后缀变量
1. KMPKG_HOST_PATH_SEPARATOR
- 作用:宿主系统的路径分隔符(Windows 为
;,类 Unix 为:)。 - 注意:必须用引号包裹(避免分号被 CMake 解析为列表分隔符)。
- 示例:
# 向环境变量追加路径
set(ENV{PATH} "$ENV{PATH}${KMPKG_HOST_PATH_SEPARATOR}${SOURCE_PATH}/tools")
2. KMPKG_HOST_EXECUTABLE_SUFFIX
- 作用:宿主系统的可执行文件后缀(Windows 为
.exe,类 Unix 为空字符串)。 - 示例:
# 定位宿主的 cmake 可执行文件
set(HOST_CMAKE "${CURRENT_HOST_INSTALLED_DIR}/bin/cmake${KMPKG_HOST_EXECUTABLE_SUFFIX}")
3. KMPKG_TARGET_EXECUTABLE_SUFFIX
- 作用:目标系统的可执行文件后缀(
KMPKG_TARGET_IS_WINDOWS为.exe,否则为空)。 - 示例:
# 安装可执行文件时适配目标后缀
install(
PROGRAMS "${SOURCE_PATH}/bin/app"
RENAME "app${KMPKG_TARGET_EXECUTABLE_SUFFIX}"
DESTINATION "${CURRENT_PACKAGES_DIR}/bin"
)
4. KMPKG_HOST_BUNDLE_SUFFIX / KMPKG_TARGET_BUNDLE_SUFFIX
- 作用:宿主/目标系统的「包后缀」(如 macOS 为
.bundle,其他系统为空)。 - 示例:
# 安装 macOS 目标的 bundle 文件
if(KMPKG_TARGET_IS_OSX)
install(
DIRECTORY "${SOURCE_PATH}/lib/mylib${KMPKG_TARGET_BUNDLE_SUFFIX}"
DESTINATION "${CURRENT_PACKAGES_DIR}/lib"
)
endif()
四、库文件前缀/后缀变量
这类变量适配不同系统的库文件命名规则(如 Linux 静态库为 libxxx.a,Windows 为 xxx.lib),与 CMake 原生变量(如 CMAKE_STATIC_LIBRARY_PREFIX)等价,但为 KMPKG 标准化封装。
| 变量 | 作用 | 示例取值(Windows/Unix) |
|---|---|---|
KMPKG_TARGET_STATIC_LIBRARY_PREFIX | 目标系统静态库前缀 | "" / "lib" |
KMPKG_TARGET_STATIC_LIBRARY_SUFFIX | 目标系统静态库后缀 | ".lib" / ".a" |
KMPKG_TARGET_SHARED_LIBRARY_PREFIX | 目标系统动态库前缀 | "" / "lib" |
KMPKG_TARGET_SHARED_LIBRARY_SUFFIX | 目标系统动态库后缀 | ".dll" / ".so" |
KMPKG_TARGET_IMPORT_LIBRARY_PREFIX | 目标系统导入库前缀(仅 Windows) | "" / 无意义 |
KMPKG_TARGET_IMPORT_LIBRARY_SUFFIX | 目标系统导入库后缀(仅 Windows) | ".lib" / 无意义 |
示例:动态拼接库文件名
# 构造目标系统的静态库名称(如 Windows: foo.lib,Linux: libfoo.a)
set(STATIC_LIB_NAME "${KMPKG_TARGET_STATIC_LIBRARY_PREFIX}foo${KMPKG_TARGET_STATIC_LIBRARY_SUFFIX}")
# 验证库文件是否存在
if(NOT EXISTS "${CURRENT_INSTALLED_DIR}/lib/${STATIC_LIB_NAME}")
message(FATAL_ERROR "Static library ${STATIC_LIB_NAME} not found!")
endif()
5. KMPKG_FIND_LIBRARY_PREFIXES / KMPKG_FIND_LIBRARY_SUFFIXES
- 作用:
find_library()命令的默认前缀/后缀列表(适配目标系统)。 - 示例:
# 查找目标系统的 foo 库(自动适配前缀/后缀)
find_library(
FOO_LIB
NAMES foo
PATHS "${CURRENT_INSTALLED_DIR}/lib"
PREFIXES ${KMPKG_FIND_LIBRARY_PREFIXES}
SUFFIXES ${KMPKG_FIND_LIBRARY_SUFFIXES}
)
五、编译环境判定变量
KMPKG_CROSSCOMPILING
- 作用:判定是否为「跨编译」(宿主三元组 ≠ 目标三元组),值为
TRUE/FALSE。 - 核心注意:跨编译时,端口不能执行编译生成的二进制文件(如 Android 目标无法在 Windows 主机运行)。
- 示例:
# 非跨编译时,运行测试程序;跨编译时跳过
if(NOT KMPKG_CROSSCOMPILING)
execute_process(
COMMAND "${CURRENT_BUILDDIR}/test${KMPKG_TARGET_EXECUTABLE_SUFFIX}"
RESULT_VARIABLE TEST_RESULT
)
if(TEST_RESULT NOT EQUAL 0)
message(FATAL_ERROR "Test failed!")
endif()
else()
message(STATUS "Cross-compiling, skip test")
endif()
六、安装目录变量
1. CURRENT_INSTALLED_DIR
- 作用:目标三元组的端口安装根目录(绝对路径),即当前端口编译完成后要安装到的目录。
- 示例:
# 查找目标系统的 CMake 配置文件
find_package(
foo CONFIG REQUIRED
PATHS "${CURRENT_INSTALLED_DIR}/share/foo/cmake"
)
2. CURRENT_HOST_INSTALLED_DIR
- 作用:宿主三元组的端口安装根目录(绝对路径),用于获取宿主侧的构建工具/依赖。
- 示例:
# 跨编译时,使用宿主的 pkg-config 工具
if(KMPKG_CROSSCOMPILING)
set(ENV{PKG_CONFIG_EXECUTABLE} "${CURRENT_HOST_INSTALLED_DIR}/bin/pkg-config${KMPKG_HOST_EXECUTABLE_SUFFIX}")
endif()
核心使用原则
- 只读性:所有内置变量禁止修改,修改会导致 KMPKG 构建逻辑异常;
- 系统适配优先:优先使用
KMPKG_TARGET_IS_*/KMPKG_HOST_IS_*判定系统,而非原生 CMake 变量(如WIN32),适配性更强; - 路径拼接规范:路径拼接必须使用
KMPKG_HOST_PATH_SEPARATOR,避免跨系统路径错误; - 跨编译校验:涉及执行编译产物的逻辑,必须先判断
KMPKG_CROSSCOMPILING。