标签:span 输出 习惯 clu 了解 size 规则 生成 UNC
CMake第三课 安装自己编写的头文件和共享库
一.完整过程
手把手教你学CMake,上一节讲到了安装文件。这一节我们将自己动手写一个动态库和一个静态库,并安装头文件和共享库以供其他程序使用 。下一节,我们将编写程序,应用这一节安装的头文件和库文件。本节还是以输出 Hello World 字符串为例进行讲解。
====================================================================================
绝对路径:/home/guo/cmake_practice/3(工程目录)
----------------------------------------------------------
目标:
1.建立一个静态库和动态库,提供 HelloFunc 函数供其他程序编程用,HelloFunc向终端输出 Hello World 字符串。
2.安装头文件与共享库(包含静态库和动态库)。
----------------------------------------------------------
工程目录结构(按照下面结构添加文件夹和文件):
1.一个空文件夹 build
2.在主工程目录(/home/guo/cmake_practice/3)建一个CMakeLists.txt文件
PROJECT(HELLOLIB)
ADD_SUBDIRECTORY(lib)
3.一个lib文件夹(/home/guo/cmake_practice/3/lib) 建立两个源文件 hello.cpp 与 hello.h 和 一个CMakeLists.txt
lib/hello.h内容:
#ifndef HELLO_H #define HELLO_H #include <iostream> using namespace std; int HelloFunc(); #endif
lib/hello.cpp内容:
#include "hello.h" int HelloFunc() { cout<<"Hello World!"<<endl; return 0; }
lib/CMakeLists.txt内容:
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 ) #声明要求的 cmake 最低版本 SET(LIBHELLO_SRC hello.cpp) ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello") SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1) INSTALL(TARGETS hello hello_static LIBRARY DESTINATION include/lib ARCHIVE DESTINATION include/lib)
INSTALL(FILES hello.h DESTINATION include/hello)
----------------------------------------------------------
外部编译
cd build cmake -DCMAKE_INSTALL_PREFIX=/home/guo/cmake_practice/3 .. (指定绝对路径 <prefix>)
make
make install
这样我们就可以将头文件和共享库分别安装到/home/guo/cmake_practice/3/include/hello 和/home/guo/cmake_practice/3/include/lib中了。
====================================================================================
二.详细解释
1.ADD_LIBRARY基本语法:ADD_LIBRARY(libname [SHARED|STATIC|MODULE]
[EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)
2.SET_TARGET_PROPERTIES基本语法: SET_TARGET_PROPERTIES(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)
这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和 API 版本。
----------------------------------------------------------
3.首先生成动态库
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
在 <prefix>/lib 目录得到一个 libhello.so,这就是我们期望的共享库。
4.上述步骤实现了生成动态库,接下来要生成同名静态库就有些麻烦了
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
这样对静态库重命名也不能同时得到 libhello.so/libhello.a 这两个库。因为:cmake 在构建一个新的 target 时,会尝试清理掉其他使用这个名字的库。 即,在构建 libhello.a 时,就会清理掉 libhello.so.
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
这时候,我们再次进行构建,会发现 build/lib 目录中同时生成了 libhello.so 和libhello.a
----------------------------------------------------------
5.按照规则,动态库是应该包含一个版本号的。
为了实现动态库版本号,我们仍然需要使用 SET_TARGET_PROPERTIES 指令。具体使用方法如下:
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION 指代动态库版本,SOVERSION 指代 API 版本。将上述指令加入 lib/CMakeLists.txt 中,重新构建看看结果。
在 build/lib 目录会生成:
libhello.so.1.2
libhello.so.1->libhello.so.1.2
libhello.so ->libhello.so.1
6.安装共享库和头文件
以上面的例子,我们需要将 libhello.a, libhello.so.x 以及 hello.h 安装到系统目录,才能真正让其他人开发使用,在本例中我们
将 hello 的共享库安装到<prefix>/include/lib目录;将 hello.h 安装到<prefix>/include/hello 目录。
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION include/lib ARCHIVE DESTINATION include/lib) INSTALL(FILES hello.h DESTINATION include/hello)
注意:静态库要使用 ARCHIVE 关键字!
标签:span 输出 习惯 clu 了解 size 规则 生成 UNC
原文地址:https://www.cnblogs.com/guoshuai-ouc/p/cmake_lib.html