Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/xmake-io/xrepo-cmake
CMake wrapper for Xrepo C and C++ package manager
https://github.com/xmake-io/xrepo-cmake
cmake package-manager xmake
Last synced: 29 days ago
JSON representation
CMake wrapper for Xrepo C and C++ package manager
- Host: GitHub
- URL: https://github.com/xmake-io/xrepo-cmake
- Owner: xmake-io
- License: apache-2.0
- Created: 2022-01-12T07:25:16.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2025-01-03T14:16:51.000Z (30 days ago)
- Last Synced: 2025-01-03T15:27:19.598Z (30 days ago)
- Topics: cmake, package-manager, xmake
- Language: CMake
- Homepage: https://xrepo.xmake.io
- Size: 121 KB
- Stars: 57
- Watchers: 3
- Forks: 9
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
README
## Supporting the project
Support this project by [becoming a sponsor](https://xmake.io/#/about/sponsor). Your logo will show up here with a link to your website. 🙏
## Introduction
CMake wrapper for [Xrepo](https://xrepo.xmake.io/) C and C++ package manager.
This allows using CMake to build your project, while using Xrepo to manage
dependent packages. This project is partially inspired by
[cmake-conan](https://github.com/conan-io/cmake-conan).Example use cases for this project:
- Existing CMake projects which want to use Xrepo to manage packages.
- New projects which have to use CMake, but want to use Xrepo to manage
packages.Note: please use CMake 3.19 or later for reliable package usage in CMake code.
## Usage
### Apis
#### xrepo_package
[`xrepo.cmake`](./xrepo.cmake) provides `xrepo_package` function to manage
packages.```cmake
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]
)
```Some of the function arguments correspond directly to Xrepo command options.
`xrepo_package` adds package install directory to `CMAKE_PREFIX_PATH`. So `find_package`
can be used. If `CMAKE_MINIMUM_REQUIRED_VERSION` >= 3.1, cmake `PkgConfig` will also search
for pkgconfig files under package install directories.After calling `xrepo_package(foo)`, there are three ways to use `foo` package:
1. Call `find_package(foo)` if package provides cmake config-files.
- Refer to CMake [`find_package`](https://cmake.org/cmake/help/latest/command/find_package.html) documentation for more details.
2. If the package does not provide cmake config files or find modules
- Following variables can be used to use the pacakge (variable names following cmake
find modules [standard variable names](https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#standard-variable-names))
- `foo_INCLUDE_DIRS`
- `foo_LIBRARY_DIRS`
- `foo_LIBRARIES`
- `foo_DEFINITIONS`
- If `DIRECTORY_SCOPE` is specified, `xrepo_package` will run following code
```cmake
include_directories(${foo_INCLUDE_DIRS})
link_directories(${foo_LIBRARY_DIRS})
```
3. Use `xrepo_target_packages`. Please refer to following section.Note `CONFIGS path/to/script.lua` is for fine control over package configs.
For example:
- Exclude packages on system.
- Override dependent packages' default configs, e.g. set `shared=true`.If `DEPS` is specified, all dependent libraries will add to `CMAKE_PREFIX_PATH`, along with include,
libraries being included in the four variables.#### xrepo_target_packages
Add package includedirs and links/linkdirs to the given target.
```cmake
xrepo_target_packages(
target
[NO_LINK_LIBRARIES]
[PRIVATE|PUBLIC|INTERFACE]
package1 package2 ...
)
```- `NO_LINK_LIBRARIES`
- In case a package provides multiple libs and user need to select which one
to link, pass `NO_LINK_LIBRARIES` to disable calling `target_link_libraries`.
User should call `target_link_libraries` to setup correct library linking.
- `PRIVATE|PUBLIC|INTERFACE`
- The default is not specifying propagation control keyword when calling
`target_include_libraries`, `target_link_libraries`, etc, because there's no
default choice on this in CMake.
- Refer to this [Stack Overflow answer](https://stackoverflow.com/a/26038443)
for differences.### Use package from official repository
Xrepo official repository: [xmake-repo](https://github.com/xmake-io/xmake-repo)
Here's an example `CMakeLists.txt` that uses `gflags` package version 2.2.2
managed by Xrepo.#### Integrate xrepo.cmake
```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)
```#### Add basic packages
```cmake
xrepo_package("zlib")add_executable(example-bin "")
target_sources(example-bin PRIVATE
src/main.cpp
)
xrepo_target_packages(example-bin zlib)
```#### Add packages with configs
```cmake
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)
```#### Add packages with cmake modules
```cmake
xrepo_package("gflags 2.2.2" CONFIGS "shared=true,mt=true")# `xrepo_package` add gflags install directory to CMAKE_PREFIX_PATH.
# As gflags provides cmake config-files, we can now call `find_package` to find
# gflags package.
find_package(gflags CONFIG COMPONENTS shared)add_executable(example-bin "")
target_sources(example-bin PRIVATE
src/main.cpp
)
target_link_libraries(example-bin gflags)
```#### Add custom packages
We can also add custom packages in our project.
```cmake
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)
```Define myzlib package in packages/xmake.lua
```lua
package("myzlib")
set_homepage("http://www.zlib.net")
set_description("A Massively Spiffy Yet Delicately Unobtrusive Compression Library")set_urls("http://zlib.net/zlib-$(version).tar.gz",
"https://downloads.sourceforge.net/project/libpng/zlib/$(version)/zlib-$(version).tar.gz")add_versions("1.2.10", "8d7e9f698ce48787b6e1c67e6bff79e487303e66077e25cb9784ac8835978017")
on_install(function (package)
-- TODO
end)on_test(function (package)
assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
end)
```We can write a custom package in xmake.lua, please refer [Define Xrepo package](https://xmake.io/#/package/remote_package?id=package-description).
### Options and variables for `xrepo.cmake`
Following options can be speicified with `cmake -D=`.
Or use `set(var value)` in `CMakeLists.txt`.- `XMAKE_CMD`: string, defaults to empty string
- Specify path to `xmake` command. Use this option if `xmake` is not installed
in standard location and can't be detected automatically.
- `XREPO_PACKAGE_VERBOSE`: `[ON|OFF]`
- Enable verbose output for Xrepo Packages.
- `XREPO_BOOTSTRAP_XMAKE`: `[ON|OFF]`
- If `ON`, `xrepo.cmake` will install `xmake` if it is not found.
- `XREPO_PACKAGE_DISABLE`: `[ON|OFF]`
- Set this to `ON` to disable `xrepo_package` function.
- If setting this variable in `CMakeLists.txt`, please set it before including
`xrepo.cmake`.
- `XREPO_BUILD_PARALLEL_JOBS`: `[COUNT]`
- Set parallel compilation threads num function.
- If setting this variable in `CMakeLists.txt`, please set it before including
`xrepo.cmake`.
- `XMAKE_RELEASE_LATEST`: `[VERSION]`
- Set xmake version.
- If setting this variable in `CMakeLists.txt`, please set it before including
`xrepo.cmake`.### Switching compiler and cross compilation
Following variables controll cross compilation. Note: to specify a different compiler other than
the default one on system, platform must be set to "cross".- `XREPO_TOOLCHAIN`: string, defaults to empty string
- Specify toolchain name. Run `xmake show -l toolchains` to see available toolchains.
- `XREPO_PLATFORM`: string, defaults to empty string
- Specify platform name. If `XREPO_TOOLCHAIN` is specified and this is not,
`XREPO_PLATFORM` will be set to `cross`.
- `XREPO_ARCH`: string, defaults to empty string
- Specify architecture name.
- `XREPO_XMAKEFILE`: string, defaults to empty string
- Specify Xmake script file of Xrepo package.### Use package from 3rd repository
In addition to installing packages from officially maintained repository,
Xrepo can also install packages from third-party package managers such as vcpkg/conan/conda/pacman/homebrew/apt/dub/cargo.For the use of the command line, we can refer to the documentation: [Xrepo command usage](https://xrepo.xmake.io/#/getting_started?id=install-packages-from-third-party-package-manager)
We can also use it directly in cmake to install packages from third-party repositories, just add the repository name as a namespace. e.g. `vcpkg::zlib`, `conan::pcre2`
#### Conan
```cmake
xrepo_package("conan::gflags/2.2.2")
```#### Conda
```cmake
xrepo_package("conda::gflags 2.2.2")
```#### Vcpkg
```cmake
xrepo_package("vcpkg::gflags")
```#### Homebrew
```cmake
xrepo_package("brew::gflags")
```## How does it work?
[`xrepo.cmake`](./xrepo.cmake) module basically does the following tasks:
- Call `xrepo install` to ensure specific package is installed.
- Call `xrepo fetch` to get package information and setup various variables for
using the installed package in CMake.The following section is a short introduction to using Xrepo. It helps to
understand how `xrepo.cmake` works and how to specify some of the options in
`xrepo_package`.### Xrepo workflow
Assmuing [Xmake](https://github.com/xmake-io/xmake/) is installed.
Suppose we want to use `gflags` packages.
First, search for `gflags` package in Xrepo.
```
$ xrepo search gflags
The package names:
gflags:
-> gflags-v2.2.2: The gflags package contains a C++ library that implements commandline flags processing. (in builtin-repo)
```It's already in Xrepo, so we can use it. If it's not in Xrepo, we can create it in
[self-built repositories](https://xrepo.xmake.io/#/getting_started?id=suppory-distributed-repository).Let's see what configs are available for the package before using it:
```
$ xrepo info gflags
...
-> configs:
-> mt: Build the multi-threaded gflags library. (default: false)
-> configs (builtin):
-> debug: Enable debug symbols. (default: false)
-> shared: Build shared library. (default: false)
-> pic: Enable the position independent code. (default: true)
...
```Suppose we want to use multi-threaded gflags shared library. We can install the package with following command:
```
xrepo install --mode=release --configs='mt=true,shared=true' 'gflags 2.2.2'
```Only the first call to the above command will compile and install the package.
To speed up cmake configuration, `xrepo` command will only be executed when the
package is not installed or `xrepo_package` parameters have changed.After package installation, because we are using CMake instead of Xmake, we have
to get package installation information by ourself. `xrepo fetch` command does
exactly this:```
xrepo fetch --json --mode=release --configs='mt=true,shared=true' 'gflags 2.2.2'
```The above command will print out package's include, library directory along with
other information. `xrepo_package` uses these information to setup variables to use
the specified package.For CMake 3.19 and later which has JSON support, `xrepo_package` parses the JSON
output. For previous version of CMake, `xrepo_package` uses only the `--cflags` option
to get package include directory. Library and cmake module directory are infered from that
directory, so it maybe unreliable to detect the correct paths.