Mastering_CMake的第五章創建自己的包,並在其他的工程中使用find_package查找自己的創建的包
ide是clion,gcc環境是MinGW
工程目錄和文件
1、創建一個源文件gromit.cpp和頭文件gromit.h作爲自己創建的包的對象,gromit.cpp中只有一個函數,打印一條消息
gromit.h文件 class gromit { public: void info(); };
gromit.cpp文件
#include <iostream> #include "gromit.h" void gromit::info(){ std::cout << "Hello, info!" << std::endl; }
2、創建項目的包配置文件,項目必須提供程序包配置文件,以便外部應用程序可以找到它們。考慮一個簡單的項目“Gromit”,該項目提供了可執行文件以生成源代碼以及一個庫,生成的代碼必須與該庫鏈接。CMakeLists.txt文件的開頭可能是:
cmake_minimum_required(VERSION 3.15) project(Gromit)#工程名稱 set(version 1.0)#設置版本 # Create library and executable. #創建靜態庫,庫名稱是gromit add_library(gromit STATIC gromit.cpp gromit.h) add_executable(gromit-gen gromit_gen.cpp) target_link_libraries(gromit-gen gromit)#鏈接庫
爲了安裝Gromit並導出其目標以供外部項目使用
set(CMAKE_INSTALL_PREFIX D:/gromit)#設置安裝位置,將頭文件和庫都安裝到這個文章 # Install and export the targets. #安裝頭文件 install(FILES gromit.h DESTINATION include/gromit-${version}) install(TARGETS gromit gromit-gen DESTINATION lib/gromit-${version} EXPORT gromit-targets) install(EXPORT gromit-targets DESTINATION lib/gromit-${version})
最後,Gromit必須在其安裝目錄中提供一個軟件包配置文件,以便外部項目可以使用find_package包來定位它:
# Create and install package configuration and version files. configure_file( ${Gromit_SOURCE_DIR}/pkg/gromit-config.cmake.in ${Gromit_BINARY_DIR}/pkg/gromit-config.cmake @ONLY) configure_file( ${Gromit_SOURCE_DIR}/gromit-config-version.cmake.in ${Gromit_BINARY_DIR}/gromit-config-version.cmake @ONLY) install(FILES ${Gromit_BINARY_DIR}/pkg/gromit-config.cmake ${Gromit_BINARY_DIR}/gromit-config-version.cmake DESTINATION lib/gromit-${version})
此代碼配置並安裝程序包配置文件和相應的程序包版本文件。軟件包配置輸入文件gromit-config.cmake.in中包含代碼,
# Compute installation prefix relative to this file. get_filename_component (_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component (_prefix "${_dir}/../.." ABSOLUTE) # Import the targets. include ("${_prefix}/lib/gromit-@version@/gromit-targets.cmake") # Report other information. set (gromit_INCLUDE_DIRS "${_prefix}/include/gromit-@version@")
相應的軟件包版本文件是從其輸入文件gromit-config-version.cmake.in配置的,其中包含以下代碼
set(PACKAGE_VERSION "@version@") if (NOT "${PACKAGE_FIND_VERSION}" VERSION_GREATER "@version@") set(PACKAGE_VERSION_COMPATIBLE 1) # compatible with older if ("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "@version@") set(PACKAGE_VERSION_EXACT 1) # exact match for this version endif () endif ()
3、安裝庫,如下圖所示,在clion的:Build-Install
將在安裝路徑下生成庫和頭文件
4、完整的CMakeLists.txt文件如下
cmake_minimum_required(VERSION 3.15) project(Gromit)#工程名稱 set(version 1.0)#設置版本 # Create library and executable. #創建靜態庫,庫名稱是gromit add_library(gromit STATIC gromit.cpp gromit.h) add_executable(gromit-gen gromit_gen.cpp) target_link_libraries(gromit-gen gromit)#鏈接庫 set(CMAKE_INSTALL_PREFIX D:/gromit)#設置安裝位置,將頭文件和庫都安裝到這個文章 # Install and export the targets. #安裝頭文件 install(FILES gromit.h DESTINATION include/gromit-${version}) install(TARGETS gromit gromit-gen DESTINATION lib/gromit-${version} EXPORT gromit-targets) install(EXPORT gromit-targets DESTINATION lib/gromit-${version}) # Create and install package configuration and version files. configure_file( ${Gromit_SOURCE_DIR}/pkg/gromit-config.cmake.in ${Gromit_BINARY_DIR}/pkg/gromit-config.cmake @ONLY) configure_file( ${Gromit_SOURCE_DIR}/gromit-config-version.cmake.in ${Gromit_BINARY_DIR}/gromit-config-version.cmake @ONLY) install(FILES ${Gromit_BINARY_DIR}/pkg/gromit-config.cmake ${Gromit_BINARY_DIR}/gromit-config-version.cmake DESTINATION lib/gromit-${version}) 5、創建一個項目調用生成的庫gromit
完整的CMakeLists.txt文件如下
cmake_minimum_required(VERSION 3.15) project(MyProject) set(CMAKE_CXX_STANDARD 14) #查找庫,查找剛纔創建的gromit庫 find_package(gromit 1.0 REQUIRED PATHS D:/gromit)#設置查找路徑,如果沒有這個路徑,就要設置環境變量 include_directories(${gromit_INCLUDE_DIRS})#添加依賴 message(${gromit_INCLUDE_DIRS})#會輸出"D:/gromit/include/gromit-1.0" # run imported executable add_custom_command(OUTPUT generated.cpp COMMAND gromit-gen generated.cpp) add_executable(myexe generated.cpp) target_link_libraries(myexe gromit) # link to imported library add_executable(MyProject main.cpp) target_link_libraries(MyProject gromit)#鏈接庫
6、main.cpp主函數如下
#include <iostream> #include "gromit.h"//使用創建的庫 int main() { std::cout << "Hello, World!" << std::endl; gromit g; g.info(); system("pause"); return 0; }
7、運行結果如下
但是無法看到gromit中的info()函數的實現。