CMake 构建可以被find_package的自建library

3 篇文章 0 订阅

这里使用我自己构建的项目进行举例说明

  1. 项目框架介绍

项目名为bitcq_nvenc,下图为项目结构
项目根目录
其中include中包含了项目对外的头文件以及项目本身使用到的其他头文件,source中包含了cpp文件

  1. cmake文件介绍
    下面是CMakeLists.txt文件,删去了多余部分只保留核心代码进行说明
cmake_minimum_required(VERSION 3.5)  #指定cmake最低要求版本

set(CMAKE_CXX_STANDARD 17) #指定项目使用的C++版本
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -fPIC -O3 -Wall -g") #附加选项 酌情添加
set(CMAKE_INSTALL_PREFIX /usr) #默认编译软件后的make install根路径
set(PROJECT_VERSION 0.0.1) #设置项目的版本号变量

project(bitcq_nvenc VERSION ${PROJECT_VERSION} LANGUAGES CXX) #这里用于设置待自动生成的项目版本很好

set(HEADERS ${CMAKE_SOURCE_DIR}/include/${PROJECT_NAME}.hpp) #设置待对外的项目头文件

add_library(${PROJECT_NAME} SHARED ${CMAKE_SOURCE_DIR}/source/${PROJECT_NAME}.cc) #这里生成核心项目的so文件 一般以lib***.so结尾 注意需使用SHARED生成动态库

if (BUILD_SHARED_LIBS) #这里编译给定的target时使用指定的编译定义
    target_compile_definitions(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:BUILD_DLL> $<INSTALL_INTERFACE:USE_DLL>)
else()
    target_compile_definitions(${PROJECT_NAME} PUBLIC USE_LIB)
endif()

target_include_directories(${PROJECT_NAME} PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include/>  #这里将项目引用的include文件夹包含进去 可以根据自己项目进行实际调整
    $<INSTALL_INTERFACE:include/${PROJECT_NAME}/>
)

target_link_libraries(${PROJECT_NAME} PRIVATE 
    rt #链接自己项目依赖的库
)

set_target_properties(${PROJECT_NAME} PROPERTIES #这里开始就是设置安装相关参数了
    SOVERSION ${PROJECT_VERSION}
    PUBLIC_HEADER ${HEADERS}
)

install(TARGETS ${PROJECT_NAME}  #这里export target暂存
    EXPORT ${PROJECT_NAME}-targets
    LIBRARY DESTINATION lib
    PUBLIC_HEADER DESTINATION include
)

# 安装install中export的项目安装内容到targets.cmake 暂存
install(EXPORT ${PROJECT_NAME}-targets
    NAMESPACE ${PROJECT_NAME}::
    FILE ${PROJECT_NAME}-targets.cmake
    DESTINATION lib/cmake/${PROJECT_NAME}   
)

#设置即将生成的cmake.in文件内使用到的环境变量
set(INCLUDE_INSTALL_DIR include/)
set(LIBRARY_INSTALL_DIR lib/)

# 生成一个cmake.in文件用于链接到targets.cmake
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/build/${PROJECT_NAME}-config.cmake.in [[
@PACKAGE_INIT@
# include(CMakeFindDependencyMacro)
# find_dependency(OtherLib REQUIRED) #这个设置可以给待使用项目自动链接其他需求库

include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake") #这里设置find_package之后需要查找的cmake文件
set_and_check(BITCQ_NVENC_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") #设置find_package后的include变量
set_and_check(BITCQ_NVENC_LIBRARY "@PACKAGE_LIBRARY_INSTALL_DIR@lib@PROJECT_NAME@.so") #设置find_package后的lib变量
check_required_components("@PROJECT_NAME@")
]])

# 创建cmake标准文件config.cmake 
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY AnyNewerVersion 
)
# 将cmake.in文件转化成config.cmake文件并安装到系统目录
configure_package_config_file(${CMAKE_CURRENT_BINARY_DIR}/build/${PROJECT_NAME}-config.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
    INSTALL_DESTINATION ${LIBRARY_INSTALL_DIR}/cmake/${PROJECT_NAME}
    PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_DIR
    #NO_SET_AND_CHECK_MACRO
    #NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
# configure_file(${PROJECT_NAME}-config.cmake.in ${PROJECT_NAME}-config.cmake @ONLY)
install(FILES 
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
    DESTINATION ${LIBRARY_INSTALL_DIR}/cmake/${PROJECT_NAME}
)
  1. 使用方式
    从其他项目中使用该库
find_package(bitcq_nvenc REQUIRED)

add_executable(${YOUR_PROJECT_TARGET_NAME} ${YOUR_PROJECT_SOURCE_FILE} )

target_include_directories(${YOUR_PROJECT_TARGET_NAME} PRIVATE
    ${BITCQ_NVENC_INCLUDE_DIR}
)

target_link_libraries(${YOUR_PROJECT_TARGET_NAME} PRIVATE 
    ${BITCQ_NVENC_LIBRARY}
)
  1. 如何打包项目为deb文件
    项目本身可以通过make install方式安装 不过也可以打包为deb(仅debian系统下),下面介绍一下打包方式
    在根目录下创建一个sh文件,运行下面代码即可创建deb包到根目录,需要注意的是control文件中package名不能使用下划线
#!/bin/bash -e
version=0.0.1

rm -rf build
mkdir build
cd build 
mkdir -p bitcq_nvenc_${version}_arm64/DEBIAN
touch bitcq_nvenc_${version}_arm64/DEBIAN/control
mkdir bitcq_nvenc_${version}_arm64/usr

cmake -DCMAKE_INSTALL_PREFIX=./bitcq_nvenc_${version}_arm64/usr ..
make -j $(nproc) install

echo "Package: bitcq-nvenc
Version: ${version}
Architecture: arm64
Maintainer: 9426224 <9426224@live.com>
Description: A lib used to socket, powered by bitcq." > bitcq_nvenc_${version}_arm64/DEBIAN/control

dpkg-deb --build --root-owner-group bitcq_nvenc_${version}_arm64

mv bitcq_nvenc_${version}_arm64.deb ..
rm -rf ../build
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要编写一个可以被其他CMake文件find_package的包,需要执行以下步骤: 1. 创建一个包含代码的库或二进制文件,并将其安装到系统上。 2. 创建一个CMake配置文件,该文件定义了包的版本号、库/二进制文件路径等信息,并将其安装到系统上。 3. 创建一个CMake模块文件,该文件包含一个find_package函数,用于查找并加载CMake配置文件。 下面是更详细的步骤: 1. 创建库或二进制文件 在CMakeLists.txt中定义库或二进制文件,例如: ``` add_library(mylib SHARED mylib.cpp) # 创建一个共享库 install(TARGETS mylib LIBRARY DESTINATION lib) # 安装该库到系统上 ``` 2. 创建CMake配置文件 创建一个名为`mylib-config.cmake.in`的文件,该文件包含了包的版本号、库文件路径等信息。注意,该文件中需要使用`@VAR@`的形式来引用变量,CMake将在安装时将这些变量替换为实际值。例如: ``` @PACKAGE_INIT@ set(MYLIB_VERSION_MAJOR 1) set(MYLIB_VERSION_MINOR 0) set(MYLIB_VERSION_PATCH 0) set(MYLIB_VERSION "${MYLIB_VERSION_MAJOR}.${MYLIB_VERSION_MINOR}.${MYLIB_VERSION_PATCH}") set(MYLIB_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/include") set(MYLIB_LIBRARIES "${CMAKE_INSTALL_PREFIX}/lib/libmylib.so") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/mylib-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/mylib-config.cmake @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mylib-config.cmake DESTINATION lib/cmake/mylib) ``` 该文件中使用了`@PACKAGE_INIT@`宏来加载CMake的基本配置信息。 3. 创建CMake模块文件 创建一个名为`FindMylib.cmake`的文件,该文件包含了一个find_package函数,用于查找并加载CMake配置文件。例如: ``` find_package(PkgConfig) pkg_check_modules(PC_MYLIB QUIET mylib) find_path(MYLIB_INCLUDE_DIR mylib.h HINTS ${PC_MYLIB_INCLUDE_DIRS} ${CMAKE_INSTALL_PREFIX}/include) find_library(MYLIB_LIBRARY NAMES mylib HINTS ${PC_MYLIB_LIBDIR} ${CMAKE_INSTALL_PREFIX}/lib) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Mylib REQUIRED_VARS MYLIB_INCLUDE_DIR MYLIB_LIBRARY VERSION_VAR MYLIB_VERSION) if(Mylib_FOUND) set(MYLIB_LIBRARIES ${MYLIB_LIBRARY}) set(MYLIB_INCLUDE_DIRS ${MYLIB_INCLUDE_DIR}) endif() mark_as_advanced(MYLIB_INCLUDE_DIR MYLIB_LIBRARY) ``` 该文件中使用了`find_package_handle_standard_args`函数来检查包是否已找到,并将结果保存在`Mylib_FOUND`变量中。此外,还定义了`MYLIB_INCLUDE_DIRS`和`MYLIB_LIBRARIES`变量,用于在其他CMake文件中引用。 4. 安装包 在CMakeLists.txt中添加以下内容,用于安装CMake配置文件和模块文件: ``` install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mylib-config.cmake DESTINATION lib/cmake/mylib) install(FILES FindMylib.cmake DESTINATION lib/cmake/mylib) ``` 5. 使用包 在其他CMake文件中,可以使用`find_package`函数来查找并加载该包,例如: ``` find_package(Mylib REQUIRED) include_directories(${MYLIB_INCLUDE_DIRS}) target_link_libraries(myapp ${MYLIB_LIBRARIES}) ``` 注意,上述代码中的`Mylib`是指在FindMylib.cmake中定义的包名,而不是库/二进制文件的名称。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值