在 CMake 中使用包
我们新增了一个独立项目 xrepo-cmake。
它是一个基于 Xrepo/Xmake 的 C/C++ 包管理器的 CMake 包装器。
这允许使用 CMake 来构建您的项目,同时使用 Xrepo 来管理依赖包。这个项目的部分灵感来自 cmake-conan。
此项目的示例用例:
- 想要使用 Xrepo 管理包的现有 CMake 项目。
- 必须使用 CMake,但想使用 Xrepo 管理的新项目包。
APIs
xrepo_package
xrepo.cmake 提供xrepo_package
函数来管理包。
xrepo_package(
"foo 1.2.3"
[CONFIGS feature1=true,feature2=false]
[CONFIGS path/to/script.lua]
[DEPS]
[MODE debug|release]
[ALIAS aliasname]
[OUTPUT verbose|diagnosis|quiet]
[DIRECTORY_SCOPE]
)
一些函数参数直接对应于 Xrepo 命令选项。
xrepo_package
将软件包安装目录添加到 CMAKE_PREFIX_PATH
。所以find_package
可以使用。如果 CMAKE_MINIMUM_REQUIRED_VERSION
>= 3.1,cmake pkgConfig
也会搜索 对于软件包安装目录下的 pkgconfig 文件。
调用 xrepo_package(foo)
后,有 foo
包的三种使用方式:
- 如果包提供 cmake 配置文件,则调用
find_package(foo)
。- 有关详细信息,请参阅 CMake
find_package
文档。 2.如果包没有提供cmake配置文件或者找不到模块 - 以下变量可用于使用pacakge(cmake后的变量名 查找模块 标准变量名称)
foo_INCLUDE_DIRS
foo_LIBRARY_DIRS
foo_LIBRARIES
foo_DEFINITIONS
- 如果指定了
DIRECTORY_SCOPE
,则xrepo_package
将运行以下代码cmakeinclude_directories(${foo_INCLUDE_DIRS}) link_directories(${foo_LIBRARY_DIRS})
- 有关详细信息,请参阅 CMake
- 使用
xrepo_target_packages
。请参阅以下部分。
注意 CONFIGS path/to/script.lua
用于对包配置进行精细控制。 例如:
- 排除系统上的包。
- 覆盖依赖包的默认配置,例如设置
shared=true
。
如果指定了 DEPS
,所有依赖库都将添加到 CMAKE_PREFIX_PATH
,以及 include 和 libraries 那四个变量中。
xrepo_target_packages
将包 includedirs 和 links/linkdirs 添加到给定的目标。
xrepo_target_packages(
target
[NO_LINK_LIBRARIES]
[PRIVATE|PUBLIC|INTERFACE]
package1 package2 ...
)
使用来自官方存储库的包
Xrepo 官方仓库:xmake-repo
这是一个使用 gflags
包版本 2.2.2 的示例 CMakeLists.txt
由 Xrepo 管理。
集成 xrepo.cmake
cmake_minimum_required(VERSION 3.13.0)
project(foo)
# Download xrepo.cmake if not exists in build directory.
if(NOT EXISTS "${CMAKE_BINARY_DIR}/xrepo.cmake")
message(STATUS "Downloading xrepo.cmake from https://github.com/xmake-io/xrepo-cmake/")
# mirror https://cdn.jsdelivr.net/gh/xmake-io/xrepo-cmake@main/xrepo.cmake
file(DOWNLOAD "https://raw.githubusercontent.com/xmake-io/xrepo-cmake/main/xrepo.cmake"
"${CMAKE_BINARY_DIR}/xrepo.cmake"
TLS_VERIFY ON)
endif()
# Include xrepo.cmake so we can use xrepo_package function.
include(${CMAKE_BINARY_DIR}/xrepo.cmake)
添加包
xrepo_package("zlib")
add_executable(example-bin "")
target_sources(example-bin PRIVATE
src/main.cpp
)
xrepo_target_packages(example-bin zlib)
添加带有配置的包
xrepo_package("gflags 2.2.2" CONFIGS "shared=true,mt=true")
add_executable(example-bin "")
target_sources(example-bin PRIVATE
src/main.cpp
)
xrepo_target_packages(example-bin gflags)
添加带有 cmake 导入模块的包
xrepo_package("gflags 2.2.2" CONFIGS "shared=true,mt=true")
# `xrepo_package` 会将 gflags 安装目录添加到 CMAKE_PREFIX_PATH.
# `find_package(gflags)` 会从 CMAKE_PREFIX_PATH 包含的目录中找到 gflags 提供的
# config-file 文件。
# 参考 https://cmake.org/cmake/help/latest/command/find_package.html#search-modes
find_package(gflags CONFIG COMPONENTS shared)
add_executable(example-bin "")
target_sources(example-bin PRIVATE
src/main.cpp
)
target_link_libraries(example-bin gflags)
添加自定义包
set(XREPO_XMAKEFILE ${CMAKE_CURRENT_SOURCE_DIR}/packages/xmake.lua)
xrepo_package("myzlib")
add_executable(example-bin "")
target_sources(example-bin PRIVATE
src/main.cpp
)
xrepo_target_packages(example-bin myzlib)
在 packages/xmake.lua 中定义一个包:
package("myzlib")
-- ...
我们可以自定义一个包,具体定义方式,参考文档:自定义 Xrepo 包.
使用来自第三个存储库的包
除了从官方维护的存储库安装软件包之外,Xrepo 还可以安装来自第三方包管理器的包,例如 vcpkg/conan/conda/pacman/homebrew/apt/dub/cargo。
关于命令行的使用,我们可以参考文档:Xrepo命令用法.
我们也可以直接在 cmake 中使用它来安装来自第三方仓库的包,只需将仓库名称添加为命名空间即可。例如:vcpkg::zlib
, conan::pcre2
Conan
xrepo_package("conan::gflags/2.2.2")
Conda
xrepo_package("conda::gflags 2.2.2")
Vcpkg
xrepo_package("vcpkg::gflags")
Homebrew
xrepo_package("brew::gflags")