From f50f32ea606d2392eb2fb6ff005658b1233f3c13 Mon Sep 17 00:00:00 2001 From: GordonYang1 <1468121796@qq.com> Date: Mon, 22 Jun 2026 14:19:32 +0800 Subject: [PATCH] feat: provide CMake config package for `find_package(InfiniCCL)` --- CMakeLists.txt | 45 ++++++++++++++++++++++++++++++++-- README.md | 40 ++++++++++++++++++++++++------ cmake/InfiniCCLConfig.cmake.in | 18 ++++++++++++++ 3 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 cmake/InfiniCCLConfig.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 399949c..42d4699 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.18) -project(InfiniCCL LANGUAGES C CXX) +project(InfiniCCL VERSION 0.1.0 LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -379,12 +379,53 @@ file(CHMOD "${CMAKE_BINARY_DIR}/icclrun" # For Production/System Install include(GNUInstallDirs) -install(TARGETS infiniccl DESTINATION ${CMAKE_INSTALL_LIBDIR}) +# Install the library and record it in an export set so that downstream +# projects can pull in `InfiniCCL::infiniccl` via `find_package(InfiniCCL)`. +# All hardware/backend dependencies (CUDA, MPI, NCCL, ...) are linked PRIVATE +# into this shared library, so they are NOT propagated as usage requirements. +install(TARGETS infiniccl + EXPORT InfiniCCLTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/infiniccl) install(PROGRAMS scripts/icclrun.py DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME icclrun) +# ========================================================= +# --- CMake Package Config (`find_package(InfiniCCL)`) --- +# ========================================================= +set(INFINICCL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/InfiniCCL) + +# Export the imported target definition (`InfiniCCL::infiniccl`). +install(EXPORT InfiniCCLTargets + FILE InfiniCCLTargets.cmake + NAMESPACE InfiniCCL:: + DESTINATION ${INFINICCL_CMAKE_DIR} +) + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/InfiniCCLConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/InfiniCCLConfig.cmake" + INSTALL_DESTINATION ${INFINICCL_CMAKE_DIR} +) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/InfiniCCLConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/InfiniCCLConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/InfiniCCLConfigVersion.cmake" + DESTINATION ${INFINICCL_CMAKE_DIR} +) + # Install the supporting logic to a private folder. set(ICCL_PRIVATE_LIB ${CMAKE_INSTALL_LIBDIR}/infiniccl) install(FILES scripts/icclrun_logic.py DESTINATION ${ICCL_PRIVATE_LIB}) diff --git a/README.md b/README.md index bf89d4b..df99f2f 100644 --- a/README.md +++ b/README.md @@ -212,19 +212,45 @@ For all the options of the script, see: ### 2. Run a Custom User Program -InfiniCCL does not yet provide a CMake config package (e.g., `find_package(InfiniCCL)`). Until then, the recommended way to link your own programs is to: - -1. **Set an environment variable** `INFINICCL_INSTALL` pointing to the InfiniCCL installation directory (e.g., `~/.infini` or a shared NFS path), and/or set the installed library path to `LD_LIBRARY_PATH`. - -2. **Link directly** to the library, headers, and required dependencies (MPI, GPU runtime). - Within the program, just include: ```cpp #include ``` -### Minimal `CMakeLists.txt` Example +#### Recommended: `find_package(InfiniCCL)` + +The simplest way to consume InfiniCCL is through `find_package`. This pulls in the +imported target `InfiniCCL::infiniccl`, and there is no need to hand-wire include +paths, the `.so`, or the RPATH yourself. + +```cmake +cmake_minimum_required(VERSION 3.18) +project(UserApp LANGUAGES CXX) + +find_package(InfiniCCL REQUIRED) + +add_executable(app main.cc) +target_link_libraries(app PRIVATE InfiniCCL::infiniccl) +``` + +Point CMake at the InfiniCCL install prefix with any of the usual mechanisms: + +```bash +cmake -B build -DCMAKE_PREFIX_PATH=/path/to/install # e.g. ~/.infini +# or: -DInfiniCCL_ROOT=/path/to/install +``` + +There is no need to resolve hardware/backend dependencies (e.g., CUDA, MPI, NCCL, …) +just to use InfiniCCL. However, if your own program calls those APIs directly +(e.g. allocating GPU buffers or calling MPI), you must link them in addition to +`InfiniCCL::infiniccl`. + +#### Alternative: manual linking + +If you prefer not to use the config package, set the environment variable +`INFINICCL_INSTALL` to the InfiniCCL installation directory (e.g. `~/.infini` or +a shared NFS path) and link directly to the library and headers: ```cmake cmake_minimum_required(VERSION 3.18) diff --git a/cmake/InfiniCCLConfig.cmake.in b/cmake/InfiniCCLConfig.cmake.in new file mode 100644 index 0000000..42fdb43 --- /dev/null +++ b/cmake/InfiniCCLConfig.cmake.in @@ -0,0 +1,18 @@ +@PACKAGE_INIT@ + +# InfiniCCL CMake package configuration file. +# +# Provides the imported target: +# InfiniCCL::infiniccl +# +# which carries the public include directory and the location of +# `libinfiniccl`. All hardware/backend dependencies (CUDA, MPI, NCCL, ...) +# are linked PRIVATE into the shared library, so consumers do not need to +# resolve them just to use InfiniCCL. The `find_dependency` hooks below are +# intentionally left as a guarded extension point for future builds that may +# expose such dependencies through the public interface. +include(CMakeFindDependencyMacro) + +include("${CMAKE_CURRENT_LIST_DIR}/InfiniCCLTargets.cmake") + +check_required_components(InfiniCCL)