简单的find_package Module模式示例,通过Findxxx.cmake查找依赖库的安装信息。
一、目录结构如下:
二、代码文件&安装目录:
1、lib目录:
demo.h:
#include <iostream>
#include <string>
namespace test{
std::string run();
}
demo.cpp:
#include "demo.h"
namespace test{
std::string run()
{
return "find_package_demo";
}
}
CMakeLists.txt:
cmake_minimum_required( VERSION 3.8 FATAL_ERROR)
project(demo VERSION 1.0.0 LANGUAGES CXX)
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR}/..)
set(CMAKE_INSTALL_PREFIX ${PROJECT_ROOT}/install/)#安装目录
#set compile flags
#add_definitions(-std=c++11 -g -rdynamic)
set(CMAKE_CXX_FLAGS "-g3 -rdynamic -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -fsanitize=address -fno-omit-frame-pointer -fsanitize=leak")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
SET(BIN_DESTINATION ${PROJECT_SOURCE_DIR}/bin)
SET(INSTALL_DESTION ${PROJECT_SOURCE_DIR}/install)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BIN_DESTINATION})
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BIN_DESTINATION})
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BIN_DESTINATION})
#include dirs
include_directories(./)
#libraries
SET(SRC demo.cpp)
add_library(demo SHARED ${SRC})
SET_TARGET_PROPERTIES(demo PROPERTIES VERSION ${PROJECT_VERSION})
SET_TARGET_PROPERTIES(demo PROPERTIES PUBLIC_HEADER ${CMAKE_CURRENT_LIST_DIR}/demo.h)
install(TARGETS demo
EXPORT demo
LIBRARY DESTINATION lib # 动态库安装路径
ARCHIVE DESTINATION lib # 静态库安装路径
RUNTIME DESTINATION bin # 可执行文件安装路径
PUBLIC_HEADER DESTINATION include # 头文件安装路径
)
2、main目录
main.cpp:
#include <iostream>
#include <string>
#include "demo.h"
using namespace std;
int main(int argc,char *argv[])
{
cout<<"main..."<<endl;
cout<<test::run()<<endl;
cout<<"exit."<<endl;
return 0;
}
CMakeLists.txt:
cmake_minimum_required( VERSION 3.8 FATAL_ERROR)
project(main VERSION 1.0.0 LANGUAGES CXX)
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR}/..)
message(${PROJECT_ROOT})
set(CMAKE_INSTALL_PREFIX ${PROJECT_ROOT}/install/)
#set compile flags
#add_definitions(-std=c++11 -g -rdynamic)
set(CMAKE_CXX_FLAGS "-g3 -rdynamic -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -fsanitize=address -fno-omit-frame-pointer -fsanitize=leak")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
#set dirs
SET(BIN_DESTINATION ${PROJECT_SOURCE_DIR}/bin)
SET(INSTALL_DESTION ${PROJECT_SOURCE_DIR}/install)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BIN_DESTINATION})
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BIN_DESTINATION})
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BIN_DESTINATION})
#设置查找Finddemo.cmake的路径
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/cmake/)
message("cmake_module_path:${CMAKE_MODULE_PATH}")
#使用find_package查找demo(这里会从CMAKE_MODULE_PATH设置的路径中查找)
find_package(demo REQUIRED MODULE)
#如果找到了(demo_FOUND会被设置为True,是一种约定,你也可以使用自己喜欢的变量<但是不建议这么做>)
if (demo_FOUND)
#打印相关的信息
message("demo_FOUND:${demo_FOUND}")
message("demo_version:${demo_VERSION}")
message("demo_include:${demo_INCLUDE_DIR}")
message("demo_library:${demo_LIBRARY}")
endif()
#include dirs
include_directories(./ ${demo_INCLUDE_DIR}) #把demo.h所在的路径demo_INCLUDE_DIR添加到include dir中(Finddemo.cmake已经设置了demo_INCLUDE_DIR变量)
#link dirs
link_directories(${BIN_DESTINATION})
#execute
SET(SRC_MAIN main.cpp)
add_executable( ${PROJECT_NAME} ${SRC_MAIN})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION})
target_link_libraries(${PROJECT_NAME} ${demo_LIBRARY}) #链接libdemo.so(Finddemo.cmake设置了demo_LIBRARY变量)
install(TARGETS main
EXPORT main
LIBRARY DESTINATION lib # 动态库安装路径
ARCHIVE DESTINATION lib # 静态库安装路径
RUNTIME DESTINATION bin # 可执行文件安装路径
PUBLIC_HEADER DESTINATION include # 头文件安装路径
)
cmake目录:
Finddemo.cmake文件
message("now using Finddemo.cmake find demo lib")
#find demo.h
FIND_PATH(demo_INCLUDE_DIR demo.h
/usr/include/demo/
/usr/local/demo/include/
~/work/demo/find_package_simple/install/include/)
message("include_dir: ${demo_INCLUDE_DIR}")
#find libdemo.so
FIND_LIBRARY(demo_LIBRARY libdemo.so
/usr/local/demo/lib/
~/work/demo/find_package_simple/install/lib/)
message("libs: ${demo_LIBRARY}")
if(demo_INCLUDE_DIR AND demo_LIBRARY)
set(demo_FOUND TRUE)
set(demo_VERSION 1.0.0)
endif(demo_INCLUDE_DIR AND demo_LIBRARY)
3、install目录
bin目录:
lib目录:
include目录:
三、find_package原理说明:
构建main的时候,cmake会在main目录的CMakeLists.txt的第24行指定的目录查找Finddemo.cmake文件,第28行的find_package(demo)通过Finddemo.cmake文件查找demo的安装信息(头文件、.so或.a、版本信息等等),Finddemo.cmake文件设置了与demo的安装信息相关的变量(demo_FOUND、demo_INCLUDE_DIR、demo_LIBRARY、demo_VERSION等),由demo_FOUND指示了是否查找成功,查找成功后即可在CMakeLists.txt文件中使用这些变量了