创建自己的xxxConfig.cmake,用于第三方使用

1.构建自己xxxConfig.cmake

构建自己的xxxConfig.cmake,可以让第三方人员通过find_package找到并进行使用。

1.1.文件架构

整个文件的架构如下所示:

├── CMakeLists.txt  # cmake构建脚本
├── include # 库的头文件
│   └── plus.h
├── PLUSConfig.cmake.in # 用于生成 xxxConfig.cmake
└── src # 库的源文件
    └── plus.cpp

其中plus.cpp的作用是将两个整数进行求和,其内容如下;

#include "plus.h"

int plus(int a, int b){
	return a+b;
}

构建一个库,该库会提供上述的函数plus供第三方使用

1.2.configure_package_config_file

该命令用于生成xxxCionfig.cmake文件的,其使用方式如下:

configure_package_config_file(
  <input> 
  <output>
  INSTALL_DESTINATION <path>
  [PATH_VARS <var1> <var2> ... <varN>]
  [NO_SET_AND_CHECK_MACRO]
  [NO_CHECK_REQUIRED_COMPONENTS_MACRO]
  [INSTALL_PREFIX <path>]
  )
  1. input:文件名,一般为xxxConfig.cmake.in文件,需要自己提供
  2. output:文件名,一般为xxConfig.cmake文件。其会通过input中的文件进行生成
  3. INSTALL_DESTINATION:改参数后跟绝对或相对路径,表示output中的文件在install的时候会被装载到那个位置。如果使用相对路径,则其相对于INSTALL_PREFIX所表示的路径
  4. PATH_VARS:其后跟这变量的名字,这些变量需要在xxxConfig.cmake.in文件中出现。例如变量名 A,则在xxxConfig.cmake.in中要以 @PACKAGE_A@的形式出现。这些变量的作用一般是在xxxConfig.cmake.in生成xxxConfig.cmake的时候进行对应的变量替换
  5. INSTALL_PREFIX:install时候的prefix path

1.3.CMakeLists.txt编写

主要参考cmake的官方文档:Generating a Package Configuration File
CMakeLists.txt的编写如下:

# -----------------------------------生成库-----------------------------------
cmake_minimum_required(VERSION 3.4)
project(PLUS)

# 我自定义了install时候的路径,也可以定义为自己的install路径
SET(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install)

add_library(plus SHARED ${CMAKE_CURRENT_SOURCE_DIR}/src/plus.cpp)
target_include_directories(plus PUBLIC 
		$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
		$<INSTALL_INTERFACE:include>)

set_target_properties(plus PROPERTIES PUBLIC_HEADER "include/plus.h")

#==================生成目标文件的xxxTarget.cmake======================
# 会将生成的库libplus.so安装到${CMAKE_INSTALL_PREFIX}/lib下
install(
	TARGETS plus
	EXPORT ${PROJECT_NAME}Targets
	PUBLIC_HEADER DESTINATION include
	ARCHIVE DESTINATION lib
 	LIBRARY DESTINATION lib
	RUNTIME DESTINATION bin
)
# 生成 xxxTargets.cmake文件
install(
	EXPORT ${PROJECT_NAME}Targets
	FILE ${PROJECT_NAME}Targets.cmake
	DESTINATION lib/cmake/mylib
)

#======================生成 xxxConfig.cmake===============================
# 该变量会通过xxxConfig.cmake.in用于在生成的xxxConfig.cmake中
set(INCLUDE_DIRS include)
set(LIBRARIES plus)
set(LIB_DIR lib)

# 由cmake提供
include(CMakePackageConfigHelpers)

# 生成 xxxConfigVersion.cmake文件
write_basic_package_version_file(
	${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
	VERSION 1.1.1
	COMPATIBILITY SameMajorVersion
)

# 用于生成 xxxConfig.cmake文件
configure_package_config_file(
	${PROJECT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in
	${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
	INSTALL_DESTINATION lib/cmake/mylib
	PATH_VARS INCLUDE_DIRS LIBRARIES LIB_DIR
	INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
)

install(
	FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake ${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
	DESTINATION lib/cmake/mylib
)

1.4.cmake.in文件编写

其中xxxConfig.cmake.in文件中的内容如下:

@PACKAGE_INIT@

set( @PROJECT_NAME@_LIBRARIES  plus)
set( @PROJECT_NAME@_INCLUDE_DIRS  @PACKAGE_INCLUDE_DIRS@)
set( @PROJECT_NAME@_LIBRARY_DIRS @PACKAGE_LIB_DIR@)

check_required_components(${PROJECT_NAME})

其中:
@PACKAGE_INIT@:必须有,用于命令configure_package_config_file进行识别。该语句之后的命令才会被用于构建xxxConfig.cmake

CMakeLists.txt中的变量INCLUDE_DIRS,在xxxConfig.cmake.in中以@PACKAGE_INCLUDE_DIRS@形式出现,在生成xxxConfig.cmake的时候,会被替换成变量INCLUDE_DIRS表示的内容

1.5.构建

构建命令如下:

cd <project_path>
mdkir build && cd build
cmake ..
make
make install

执行命令后,得到文件分布如下:

├── CMakeLists.txt
├── include
│   └── plus.h
├── install
│   ├── include
│   │   └── plus.h
│   └── lib
│       ├── cmake
│       │   └── mylib
│       │       ├── PLUSConfig.cmake
│       │       ├── PLUSConfigVersion.cmake
│       │       ├── PLUSTargets.cmake
│       │       └── PLUSTargets-noconfig.cmake
│       └── libplus.so
├── PLUSConfig.cmake.in
└── src
    └── plus.cpp

其中 xxxConfig.cmake文件的内容:


####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was PLUSConfig.cmake.in                            ########

get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)

macro(set_and_check _var _file)
  set(${_var} "${_file}")
  if(NOT EXISTS "${_file}")
    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
  endif()
endmacro()

macro(check_required_components _NAME)
  foreach(comp ${${_NAME}_FIND_COMPONENTS})
    if(NOT ${_NAME}_${comp}_FOUND)
      if(${_NAME}_FIND_REQUIRED_${comp})
        set(${_NAME}_FOUND FALSE)
      endif()
    endif()
  endforeach()
endmacro()

####################################################################################

set( PLUS_LIBRARIES  plus)
set( PLUS_INCLUDE_DIRS  ${PACKAGE_PREFIX_DIR}/include)
set( PLUS_LIBRARY_DIRS ${PACKAGE_PREFIX_DIR}/lib)

check_required_components(${PROJECT_NAME})

2.使用

我们在别的地方进行使用我们生成的xxxConfig.cmake文件。另外起一个单独的项目,其CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.4)
project(Te)

# 设置find_package的查找路径
set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/plus/install/lib/cmake/mylib)

find_package(PLUS REQUIRED)
if(PLUS_FOUND)
	message(STATUS "PLUS_FOUND = ${PLUS_FOUND}")
	message(STATUS "PLUS_INCLUDE_DIRS = ${PLUS_INCLUDE_DIRS}")
	message(STATUS "PLUS_LIBRARIES = ${PLUS_LIBRARIES}")
	message(STATUS "PLUS_LIBRARY_DIRS = ${PLUS_LIBRARY_DIRS}")
endif()


add_executable(ppp ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)

target_link_directories(ppp PUBLIC ${PLUS_LIBRARY_DIRS})
target_link_libraries(ppp plus)
target_include_directories(ppp PUBLIC ${PLUS_INCLUDE_DIRS})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值