【學習cmake】find_package與CMake查找鏈接庫 實踐篇

cmake 生成供find_package使用的自定義模塊

cmake中經常使用find_package尋找模塊,使用起來非常方便.find_package的原理是什麼呢?如何自己寫個模塊提供給別人使用?如果別人希望用find_package的形式使用你的模塊中的庫,我該如何用cmake寫這個庫呢?
下面用一個例子來說明:
myapp程序通過find_package調用mylib中的庫
1.myapp工程

myapp工程目錄如下
.
├── CMakeLists.txt
└── myapp.c

其中CMakeLists.txt

project(myapp)
cmake_minimum_required(VERSION 2.8)
SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/home/rootroot/newworkspace/mylib/install")
find_package(mylib REQUIRED)
add_executable(${PROJECT_NAME} myapp.c)
target_link_libraries(${PROJECT_NAME} mylib::mylib)

 

通過find_package來尋找我的自定義模塊mylib,SET(CMAKE_PREFIX_PATH)告訴cmake在我指定的位置尋找模塊,我的mylib安裝在/home/rootroot/newworkspace/mylib/install路徑下.
myapp.c代碼如下

#include<stdio.h>
#include <mylib.h>
int main()
{
    hello();
    return 0;
}

2.mylib工程

最後生成的mylib工程結構如下
.
├── CMakeLists.txt
├── include
│ └── mylib.h
├── install
│ ├── include
│ │ └── mylib.h
│ └── lib
│ ├── cmake
│ │ └── mylib
│ │ ├── mylib-config.cmake
│ │ └── mylib-config-noconfig.cmake
│ ├── libmylib.a

└── mylib.c

其中install是要myapp需要調用的庫文件夾.mylib-config.cmake是由cmake自動生成的文件.findpack需要找的.cmake文件才能尋找包成功.

mylib.c代碼如下

#include<stdio.h>
#include"mylib.h"
void hello()
{
      printf("hello");
}

mylib.h

#ifndef MYLIB_H
#define MYLIB_H
#include <stdio.h>
void hello();
#endif

關鍵是如何寫CMakeLists.txt,要能生成find_package能夠找到的模塊(包).
CMakeLists.txt代碼如下:

cmake_minimum_required(VERSION 2.8)
add_library(mylib mylib.c include/mylib.h)
SET(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install)
target_include_directories(mylib PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "include/mylib.h")
install(TARGETS mylib
    EXPORT mylib-targets
    PUBLIC_HEADER DESTINATION include
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    RUNTIME DESTINATION bin)
install(EXPORT mylib-targets
    NAMESPACE mylib::
    FILE mylib-config.cmake
    DESTINATION lib/cmake/mylib)

   

分句解析:
add_library(mylib mylib.c include/mylib.h)
表示將mylib.c編譯成mylib鏈接庫文件
SET(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install)
表示將編譯好的庫文件安裝在當前工程的install文件夾下.

target_include_directories(mylib PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)

 

BUILD_INTERFACE表示源文件夾在哪
INSTALL_INTERFACE表示安裝文件夾在哪

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

表示安裝的頭文件名稱是mylib.h.

install(TARGETS mylib
    EXPORT mylib-targets
    PUBLIC_HEADER DESTINATION include
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    RUNTIME DESTINATION bin)

這是安裝的一些屬性:注意EXPORT選項標識了庫文件爲供別的程序使用的,LIBRARY DESTINATION 表示庫文件的目標文件夾lib 的路徑爲相對於CMAKE_INSTALL_PREFIX的路徑.
其中

install(EXPORT mylib-targets
    NAMESPACE mylib::
    FILE mylib-config.cmake
    DESTINATION lib/cmake/mylib)

 

安裝的時候還需要生成 mylib-config.cmake文件才能讓find_package找到.
注意.cmake文件必須是命名如mylib-config.cmake或者
MylibConfig.cmake才能找到.
3編譯運行

先編譯安裝mylib
在mylib文件夾下

mkdir build
cd build
cmake ..
make
make install

 

在myapp文件夾下

mkdir build
cd build
cmake ..
make
./myapp

顯示 hello

最後,爲了方便大家理解,將代碼打包上傳,歡迎大家下載
https://download.csdn.net/download/ktigerhero3/10773044

參考文獻
https://stackoverflow.com/questions/31537602/how-to-use-cmake-to-find-and-link-to-a-library-using-install-export-and-find-pac
https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#package-configuration-file
---------------------  
作者:滄海飛帆   原文:https://blog.csdn.net/ktigerhero3/article/details/83863226 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章