#cmake #package #build-script #cargo-build #build-dependencies #link #find

build cmake-package

A helper library for Cargo build-scripts to find and link against existing CMake packages

3 releases

new 0.1.2 Oct 24, 2024
0.1.1 Oct 19, 2024
0.1.0 Oct 19, 2024

#172 in Build Utils

Download history 245/week @ 2024-10-14 170/week @ 2024-10-21

415 downloads per month

MIT license

49KB
874 lines

cmake-package

A Rust crate for Cargo build scripts to find CMake packages installed on the system and link against them. This is especially useful when your Rust project depends on a system library that only provides a CMake package. This is essentially similar to the pkg-config crate, but for CMake.

Refer to the documentation for more information on usage.

License

This project is licensed under the MIT license. See the LICENSE file for more information.

Contribution

All contributions are welcome. Please open an issue or a pull request if you have any problem, suggestions or improvement!


lib.rs:

A simple CMake package finder.

This crate is intended to be used in cargo build scripts to obtain information about and existing system CMake package and CMake targets defined in the package, such as include directories and link libraries for individual CMake targets defined in the package.

The crate runs the cmake command in the background to query the system for the package and to extract the necessary information, which means that in order for this crate to work, the cmake executable must be located the system PATH. CMake version [3.19][CMAKE_MIN_VERSION] or newer is required for this crate to work.

The entry point for the crate is the [find_package()] function that returns a builder, which you can use to specify further constraints on the package (version or components). Once you call the find() method on the builder, the crate will try to find the package on the system or return an error. If the package is found, an instance of the CMakePackage struct is returned that contains information about the package. Using its target() method, you can query information about individual CMake targets defined in the package.

If you want to make your dependency on CMake optional, you can use the [find_cmake()] function to check that a suitable version of CMake is found on the system and then decide how to proceed yourself. It is not necessary to call the function before using [find_package()].

Example

use cmake_package::find_package;

let package = find_package("OpenSSL").version("1.0").find();
let target = match package {
    Err(_) => panic!("OpenSSL>=1.0 not found"),
    Ok(package) => {
        package.target("OpenSSL::SSL").unwrap()
    }
};

println!("Include directories: {:?}", target.include_directories);
target.link();

How Does it Work?

When you call [FindPackageBuilder::find()], the crate will create a temporary directory with a CMakeLists.txt file that contains actual find_package() command to search for the package. The crate will then run actual cmake command in the temporary directory to let CMake find the package. The CMakeLists.txt then writes the information about the package into a JSON file that is then read by this crate to produce the CMakePackage.

When a target is queried using the [CMakePackage::target()] method, the crate runs the CMake command again the same directory, but this time the CMakeLists.txt attempts to locate the specified CMake target and list all its (relevant) properties and properties of all its transitive dependencies. The result is again written into a JSON file that is then processed by the crate to produce the CMakeTarget instance.

Known Limitations

The crate currently supporst primarily linking against shared libraries. Linking against static libraries is not tested and may not work as expected. The crate currently does not support linking against MacOS frameworks.

CMake generator expressions are not supported in property values right now, because they are evaluated at later stage of the build, not during the "configure" phase of CMake, which is what this crate does. Some generator expressions could be supported by the crate in the future (e.g. by evaluating them ourselves).

There's currently no way to customize the CMakeLists.txt file that is used to query the package or the target in order to extract non-standard properties or variables set by the CMake package. This may be addressed in the future.

Dependencies

~5–15MB
~223K SLoC